feat: more_tests #85
37 changed files with 2473 additions and 1742 deletions
37
.github/actions/acc_test/action.yaml
vendored
37
.github/actions/acc_test/action.yaml
vendored
|
|
@ -2,9 +2,14 @@ name: Acceptance Testing
|
|||
description: "Acceptance Testing pipeline"
|
||||
|
||||
inputs:
|
||||
tf_debug:
|
||||
description: "enable terraform debug logs"
|
||||
default: 'false'
|
||||
required: true
|
||||
|
||||
test_timeout_string:
|
||||
description: "string that determines the timeout (default: 45m)"
|
||||
default: '45m'
|
||||
default: '90m'
|
||||
required: true
|
||||
|
||||
go-version:
|
||||
|
|
@ -141,6 +146,12 @@ runs:
|
|||
${{ steps.goenv.outputs.gomodcache }}
|
||||
key: ${{ runner.os }}-gopkg
|
||||
|
||||
- name: Define service account file path variable
|
||||
id: service_account
|
||||
shell: bash
|
||||
run: |
|
||||
echo "safilepath=${PWD}/stackit/${{ inputs.service_account_json_file_path }}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Creating service_account file from json input
|
||||
if: inputs.service_account_json_content != ''
|
||||
shell: bash
|
||||
|
|
@ -192,6 +203,11 @@ runs:
|
|||
echo "::group::go test file"
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
if [[ "${{ inputs.tf_debug }}" == "true" ]]; then
|
||||
TF_LOG=INFO
|
||||
export TF_LOG
|
||||
fi
|
||||
|
||||
echo "Running acceptance tests for the terraform provider"
|
||||
cd stackit || exit 1
|
||||
|
|
@ -204,7 +220,7 @@ runs:
|
|||
TF_ACC_KEK_KEY_RING_ID=${TF_ACC_KEK_KEY_RING_ID} \
|
||||
TF_ACC_KEK_KEY_VERSION=${TF_ACC_KEK_KEY_VERSION} \
|
||||
TF_ACC_KEK_SERVICE_ACCOUNT=${TF_ACC_KEK_SERVICE_ACCOUNT} \
|
||||
go test ${{ inputs.test_file }} -count=1 -timeout=${{ inputs.test_timeout_string }}
|
||||
go test -v ${{ inputs.test_file }} -timeout=${{ inputs.test_timeout_string }}
|
||||
echo "::endgroup::"
|
||||
env:
|
||||
TF_ACC_PROJECT_ID: ${{ inputs.project_id }}
|
||||
|
|
@ -215,6 +231,7 @@ runs:
|
|||
TF_ACC_KEK_KEY_VERSION: ${{ inputs.tf_acc_kek_key_version }}
|
||||
TF_ACC_KEK_SERVICE_ACCOUNT: ${{ inputs.tf_acc_kek_service_account }}
|
||||
|
||||
# does not work correctly
|
||||
# - name: Run test action
|
||||
# if: ${{ inputs.test_file == '' }}
|
||||
# env:
|
||||
|
|
@ -226,19 +243,25 @@ runs:
|
|||
# TF_ACC_KEK_KEY_RING_ID: ${{ inputs.tf_acc_kek_key_ring_id }}
|
||||
# TF_ACC_KEK_KEY_VERSION: ${{ inputs.tf_acc_kek_key_version }}
|
||||
# TF_ACC_KEK_SERVICE_ACCOUNT: ${{ inputs.tf_acc_kek_service_account }}
|
||||
# TF_ACC_SERVICE_ACCOUNT_FILE: "${PWD}/${{ inputs.service_account_json_file_path }}"
|
||||
# uses: robherley/go-test-action@v0.1.0
|
||||
# TF_ACC_SERVICE_ACCOUNT_FILE: ${{ steps.service_account.outputs.safile }}
|
||||
# uses: robherley/go-test-action@v0
|
||||
# with:
|
||||
# testArguments: "./... -timeout 45m"
|
||||
# testArguments: "./... -timeout ${{ inputs.test_timeout_string }}"
|
||||
# moduleDirectory: "stackit"
|
||||
|
||||
- name: Run acceptance tests
|
||||
if: ${{ inputs.test_file == '' }}
|
||||
shell: bash
|
||||
run: |
|
||||
echo "::group::go test all"
|
||||
set -e
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
if [[ "${{ inputs.tf_debug }}" == "true" ]]; then
|
||||
TF_LOG=INFO
|
||||
export TF_LOG
|
||||
fi
|
||||
|
||||
echo "Running acceptance tests for the terraform provider"
|
||||
cd stackit || exit 1
|
||||
TF_ACC=1 \
|
||||
|
|
@ -250,7 +273,7 @@ runs:
|
|||
TF_ACC_KEK_KEY_RING_ID=${TF_ACC_KEK_KEY_RING_ID} \
|
||||
TF_ACC_KEK_KEY_VERSION=${TF_ACC_KEK_KEY_VERSION} \
|
||||
TF_ACC_KEK_SERVICE_ACCOUNT=${TF_ACC_KEK_SERVICE_ACCOUNT} \
|
||||
go test ./... -count=1 -timeout=${{ inputs.test_timeout_string }}
|
||||
go test -v ./... -timeout=${{ inputs.test_timeout_string }}
|
||||
echo "::endgroup::"
|
||||
env:
|
||||
TF_ACC_PROJECT_ID: ${{ inputs.project_id }}
|
||||
|
|
|
|||
39
.github/workflows/ci_new.yaml
vendored
39
.github/workflows/ci_new.yaml
vendored
|
|
@ -2,6 +2,7 @@ name: CI Workflow
|
|||
|
||||
on:
|
||||
pull_request:
|
||||
types: [ opened, synchronize, reopened ]
|
||||
branches:
|
||||
- alpha
|
||||
- main
|
||||
|
|
@ -218,11 +219,21 @@ jobs:
|
|||
run: go mod tidy
|
||||
|
||||
- name: Testing
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
run: |
|
||||
unset TF_ACC
|
||||
TF_ACC_SERVICE_ACCOUNT_FILE=~/.service_account.json
|
||||
export TF_ACC_SERVICE_ACCOUNT_FILE
|
||||
make test
|
||||
|
||||
- name: Testing with coverage
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
run: |
|
||||
unset TF_ACC
|
||||
TF_ACC_SERVICE_ACCOUNT_FILE=~/.service_account.json
|
||||
export TF_ACC_SERVICE_ACCOUNT_FILE
|
||||
make coverage
|
||||
|
||||
# - name: Acceptance Testing
|
||||
# env:
|
||||
# TF_ACC: "1"
|
||||
|
|
@ -232,20 +243,20 @@ jobs:
|
|||
# export TF_ACC_SERVICE_ACCOUNT_FILE
|
||||
# make test-acceptance-tf
|
||||
|
||||
- name: Run Test
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
uses: ./.github/actions/acc_test
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
project_id: ${{ vars.TF_ACC_PROJECT_ID }}
|
||||
region: ${{ vars.TF_ACC_REGION }}
|
||||
service_account_json_content_b64: "${{ secrets.TF_ACC_SERVICE_ACCOUNT_JSON_B64 }}"
|
||||
project_user_email: ${{ vars.TEST_PROJECT_USER_EMAIL }}
|
||||
tf_acc_kek_key_id: ${{ vars.TF_ACC_KEK_KEY_ID }}
|
||||
tf_acc_kek_key_ring_id: ${{ vars.TF_ACC_KEK_KEY_RING_ID }}
|
||||
tf_acc_kek_key_version: ${{ vars.TF_ACC_KEK_KEY_VERSION }}
|
||||
tf_acc_kek_service_account: ${{ vars.TF_ACC_KEK_SERVICE_ACCOUNT }}
|
||||
# service_account_json_file_path: "~/service_account.json"
|
||||
# - name: Run Acceptance Test
|
||||
# if: ${{ github.event_name == 'pull_request' }}
|
||||
# uses: ./.github/actions/acc_test
|
||||
# with:
|
||||
# go-version: ${{ env.GO_VERSION }}
|
||||
# project_id: ${{ vars.TF_ACC_PROJECT_ID }}
|
||||
# region: ${{ vars.TF_ACC_REGION }}
|
||||
# service_account_json_content_b64: "${{ secrets.TF_ACC_SERVICE_ACCOUNT_JSON_B64 }}"
|
||||
# project_user_email: ${{ vars.TEST_PROJECT_USER_EMAIL }}
|
||||
# tf_acc_kek_key_id: ${{ vars.TF_ACC_KEK_KEY_ID }}
|
||||
# tf_acc_kek_key_ring_id: ${{ vars.TF_ACC_KEK_KEY_RING_ID }}
|
||||
# tf_acc_kek_key_version: ${{ vars.TF_ACC_KEK_KEY_VERSION }}
|
||||
# tf_acc_kek_service_account: ${{ vars.TF_ACC_KEK_SERVICE_ACCOUNT }}
|
||||
# # service_account_json_file_path: "~/service_account.json"
|
||||
|
||||
- name: Check coverage threshold
|
||||
shell: bash
|
||||
|
|
|
|||
6
.github/workflows/renovate.yaml
vendored
6
.github/workflows/renovate.yaml
vendored
|
|
@ -12,8 +12,10 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Self-hosted Renovate
|
||||
uses: renovatebot/github-action@v41.0.0
|
||||
uses: renovatebot/github-action@v46.1.4
|
||||
with:
|
||||
configurationFile: .github/renovate.json
|
||||
token: ${{ secrets.RENOVATE_TOKEN }}
|
||||
# token: ${{ secrets.RENOVATE_TOKEN }}
|
||||
token: ${{ env.FORGEJO_TOKEN }}
|
||||
|
|
|
|||
35
.github/workflows/tf-acc-test.yaml
vendored
35
.github/workflows/tf-acc-test.yaml
vendored
|
|
@ -1,10 +1,24 @@
|
|||
name: TF Acceptance Tests Workflow
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
branches:
|
||||
- alpha
|
||||
- main
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
enable_debug:
|
||||
description: "enable terraform debug logs"
|
||||
default: 'false'
|
||||
required: true
|
||||
test_timeout_string:
|
||||
description: "string that determines the timeout (default: 45m)"
|
||||
default: '90m'
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
acc_test:
|
||||
|
|
@ -14,7 +28,8 @@ jobs:
|
|||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Run Test
|
||||
- name: Run Test (workflow dispatch)
|
||||
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||
uses: ./.github/actions/acc_test
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
|
|
@ -26,4 +41,20 @@ jobs:
|
|||
tf_acc_kek_key_ring_id: ${{ vars.TF_ACC_KEK_KEY_RING_ID }}
|
||||
tf_acc_kek_key_version: ${{ vars.TF_ACC_KEK_KEY_VERSION }}
|
||||
tf_acc_kek_service_account: ${{ vars.TF_ACC_KEK_SERVICE_ACCOUNT }}
|
||||
# service_account_json_file_path: "~/service_account.json"
|
||||
tf_debug: ${{ inputs.enable_debug }}
|
||||
test_timeout_string: ${{ inputs.test_timeout_string }}
|
||||
|
||||
- name: Run Test (automatic)
|
||||
if: ${{ github.event_name != 'workflow_dispatch' }}
|
||||
uses: ./.github/actions/acc_test
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
project_id: ${{ vars.TF_ACC_PROJECT_ID }}
|
||||
region: 'eu01'
|
||||
service_account_json_content_b64: "${{ secrets.TF_ACC_SERVICE_ACCOUNT_JSON_B64 }}"
|
||||
project_user_email: ${{ vars.TEST_PROJECT_USER_EMAIL }}
|
||||
tf_acc_kek_key_id: ${{ vars.TF_ACC_KEK_KEY_ID }}
|
||||
tf_acc_kek_key_ring_id: ${{ vars.TF_ACC_KEK_KEY_RING_ID }}
|
||||
tf_acc_kek_key_version: ${{ vars.TF_ACC_KEK_KEY_VERSION }}
|
||||
tf_acc_kek_service_account: ${{ vars.TF_ACC_KEK_SERVICE_ACCOUNT }}
|
||||
tf_debug: ${{ inputs.enable_debug }}
|
||||
|
|
|
|||
|
|
@ -29,12 +29,8 @@ linters:
|
|||
depguard:
|
||||
rules:
|
||||
main:
|
||||
list-mode: lax
|
||||
allow:
|
||||
- tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview
|
||||
- github.com/hashicorp/terraform-plugin-framework
|
||||
- github.com/hashicorp/terraform-plugin-log
|
||||
- github.com/stackitcloud/stackit-sdk-go
|
||||
list-mode: original
|
||||
allow: []
|
||||
deny:
|
||||
- pkg: github.com/stretchr/testify
|
||||
desc: Do not use a testing framework
|
||||
|
|
@ -76,6 +72,7 @@ linters:
|
|||
exclusions:
|
||||
paths:
|
||||
- generator/
|
||||
- internal/testutils
|
||||
generated: lax
|
||||
warn-unused: true
|
||||
# Excluding configuration per-path, per-linter, per-text and per-source.
|
||||
|
|
@ -86,7 +83,7 @@ linters:
|
|||
- gochecknoinits
|
||||
formatters:
|
||||
enable:
|
||||
#- gofmt
|
||||
- gofmt
|
||||
- goimports
|
||||
settings:
|
||||
goimports:
|
||||
|
|
|
|||
|
|
@ -28,6 +28,9 @@ data "stackitprivatepreview_postgresflexalpha_database" "example" {
|
|||
- `database_id` (Number) The ID of the database.
|
||||
- `instance_id` (String) The ID of the instance.
|
||||
- `project_id` (String) The STACKIT project ID.
|
||||
|
||||
### Optional
|
||||
|
||||
- `region` (String) The region which should be addressed
|
||||
|
||||
### Read-Only
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ data "stackitprivatepreview_postgresflexalpha_instance" "example" {
|
|||
|
||||
- `instance_id` (String) The ID of the instance.
|
||||
- `project_id` (String) The STACKIT project ID.
|
||||
|
||||
### Optional
|
||||
|
||||
- `region` (String) The region which should be addressed
|
||||
|
||||
### Read-Only
|
||||
|
|
@ -37,6 +40,7 @@ data "stackitprivatepreview_postgresflexalpha_instance" "example" {
|
|||
|
||||
⚠︝ **Note:** This feature is in private preview. Supplying this object is only permitted for enabled accounts. If your account does not have access, the request will be rejected. (see [below for nested schema](#nestedatt--encryption))
|
||||
- `flavor_id` (String) The id of the instance flavor.
|
||||
- `id` (String) internal ID
|
||||
- `is_deletable` (Boolean) Whether the instance can be deleted or not.
|
||||
- `name` (String) The name of the instance.
|
||||
- `network` (Attributes) The access configuration of the instance (see [below for nested schema](#nestedatt--network))
|
||||
|
|
|
|||
|
|
@ -27,12 +27,12 @@ data "stackitprivatepreview_postgresflexalpha_user" "example" {
|
|||
|
||||
- `instance_id` (String) The ID of the instance.
|
||||
- `project_id` (String) The STACKIT project ID.
|
||||
- `region` (String) The region which should be addressed
|
||||
- `user_id` (Number) The ID of the user.
|
||||
|
||||
### Optional
|
||||
|
||||
- `id` (String) Terraform's internal resource ID. It is structured as \"`project_id`,`region`,`instance_id`,`user_id`\".",
|
||||
- `region` (String) The region which should be addressed
|
||||
|
||||
### Read-Only
|
||||
|
||||
|
|
|
|||
|
|
@ -54,4 +54,4 @@ import {
|
|||
|
||||
### Read-Only
|
||||
|
||||
- `id` (Number) The id of the database.
|
||||
- `id` (String) The id of the database.
|
||||
|
|
|
|||
|
|
@ -54,6 +54,6 @@ import {
|
|||
|
||||
### Read-Only
|
||||
|
||||
- `id` (Number) The ID of the user.
|
||||
- `id` (String) The ID of the user.
|
||||
- `password` (String) The password for the user.
|
||||
- `status` (String) The current status of the user.
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ func CreateTemporaryHome(createValidCredentialsFile bool, t *testing.T) string {
|
|||
|
||||
// Define content, default = invalid token
|
||||
token := "foo_token"
|
||||
//if createValidCredentialsFile {
|
||||
// if createValidCredentialsFile {
|
||||
// token = GetTestProjectServiceAccountJson("")
|
||||
//}
|
||||
if _, err = file.WriteString(token); err != nil {
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ func ResourceNameWithDateTime(name string) string {
|
|||
return fmt.Sprintf("tf-acc-%s-%s", name, dateTimeTrimmed)
|
||||
}
|
||||
|
||||
//func GetTestProjectServiceAccountJson(path string) string {
|
||||
// func GetTestProjectServiceAccountJson(path string) string {
|
||||
// var err error
|
||||
// json, ok := os.LookupEnv("TF_ACC_SERVICE_ACCOUNT_JSON_CONTENT")
|
||||
// if !ok || json == "" {
|
||||
|
|
@ -153,7 +153,7 @@ func ResourceNameWithDateTime(name string) string {
|
|||
// return credentials.TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN, nil
|
||||
//}
|
||||
|
||||
//func readTestServiceAccountJsonFromFile(path string) (string, error) {
|
||||
// func readTestServiceAccountJsonFromFile(path string) (string, error) {
|
||||
// if path == "" {
|
||||
// customPath, ok := os.LookupEnv("TF_ACC_SERVICE_ACCOUNT_FILE")
|
||||
// if !ok || customPath == "" {
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ func DatabaseDataSourceSchema(ctx context.Context) schema.Schema {
|
|||
MarkdownDescription: "The STACKIT project ID.",
|
||||
},
|
||||
"region": schema.StringAttribute{
|
||||
Required: true,
|
||||
Optional: true,
|
||||
Description: "The region which should be addressed",
|
||||
MarkdownDescription: "The region which should be addressed",
|
||||
Validators: []validator.String{
|
||||
|
|
|
|||
|
|
@ -64,17 +64,21 @@ func mapResourceFields(source *v3alpha1api.GetDatabaseResponse, model *resourceM
|
|||
return fmt.Errorf("model input is nil")
|
||||
}
|
||||
|
||||
var databaseId int64
|
||||
if model.Id.ValueInt64() != 0 {
|
||||
databaseId = model.Id.ValueInt64()
|
||||
var databaseID int64
|
||||
if model.DatabaseId.ValueInt64() != 0 {
|
||||
if source.Id != 0 {
|
||||
if model.DatabaseId.ValueInt64() != int64(source.Id) {
|
||||
return fmt.Errorf("retrieved ID does not match known ID")
|
||||
}
|
||||
}
|
||||
databaseID = model.DatabaseId.ValueInt64()
|
||||
} else if source.Id != 0 {
|
||||
databaseId = int64(source.Id)
|
||||
databaseID = int64(source.Id)
|
||||
} else {
|
||||
return fmt.Errorf("database id not present")
|
||||
}
|
||||
|
||||
model.Id = types.Int64Value(databaseId)
|
||||
model.DatabaseId = types.Int64Value(databaseId)
|
||||
model.DatabaseId = types.Int64Value(databaseID)
|
||||
model.Name = types.StringValue(source.GetName())
|
||||
model.Owner = types.StringValue(cleanString(source.Owner))
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ func TestMapResourceFields(t *testing.T) {
|
|||
},
|
||||
expected: expected{
|
||||
model: &resourceModel{
|
||||
Id: types.Int64Value(1),
|
||||
Id: types.StringNull(),
|
||||
Name: types.StringValue("my-db"),
|
||||
Owner: types.StringValue("my-owner"),
|
||||
DatabaseId: types.Int64Value(1),
|
||||
|
|
|
|||
|
|
@ -11,9 +11,9 @@ import (
|
|||
|
||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource/identityschema"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
|
||||
"github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v3alpha1api"
|
||||
|
||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
||||
|
|
@ -30,11 +30,6 @@ var (
|
|||
_ resource.ResourceWithConfigure = &databaseResource{}
|
||||
_ resource.ResourceWithImportState = &databaseResource{}
|
||||
_ resource.ResourceWithModifyPlan = &databaseResource{}
|
||||
_ resource.ResourceWithIdentity = &databaseResource{}
|
||||
|
||||
// Error message constants
|
||||
extractErrorSummary = "extracting failed"
|
||||
extractErrorMessage = "Extracting identity data: %v"
|
||||
)
|
||||
|
||||
// NewDatabaseResource is a helper function to simplify the provider implementation.
|
||||
|
|
@ -45,14 +40,6 @@ func NewDatabaseResource() resource.Resource {
|
|||
// resourceModel describes the resource data model.
|
||||
type resourceModel = postgresflexalphaResGen.DatabaseModel
|
||||
|
||||
// DatabaseResourceIdentityModel describes the resource's identity attributes.
|
||||
type DatabaseResourceIdentityModel struct {
|
||||
ProjectID types.String `tfsdk:"project_id"`
|
||||
Region types.String `tfsdk:"region"`
|
||||
InstanceID types.String `tfsdk:"instance_id"`
|
||||
DatabaseID types.Int64 `tfsdk:"database_id"`
|
||||
}
|
||||
|
||||
// databaseResource is the resource implementation.
|
||||
type databaseResource struct {
|
||||
client *v3alpha1api.APIClient
|
||||
|
|
@ -138,30 +125,6 @@ func (r *databaseResource) Schema(ctx context.Context, _ resource.SchemaRequest,
|
|||
resp.Schema = s
|
||||
}
|
||||
|
||||
// IdentitySchema defines the schema for the resource's identity attributes.
|
||||
func (r *databaseResource) IdentitySchema(
|
||||
_ context.Context,
|
||||
_ resource.IdentitySchemaRequest,
|
||||
response *resource.IdentitySchemaResponse,
|
||||
) {
|
||||
response.IdentitySchema = identityschema.Schema{
|
||||
Attributes: map[string]identityschema.Attribute{
|
||||
"project_id": identityschema.StringAttribute{
|
||||
RequiredForImport: true,
|
||||
},
|
||||
"region": identityschema.StringAttribute{
|
||||
RequiredForImport: true,
|
||||
},
|
||||
"instance_id": identityschema.StringAttribute{
|
||||
RequiredForImport: true,
|
||||
},
|
||||
"database_id": identityschema.Int64Attribute{
|
||||
RequiredForImport: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Create creates the resource and sets the initial Terraform state.
|
||||
func (r *databaseResource) Create(
|
||||
ctx context.Context,
|
||||
|
|
@ -178,12 +141,12 @@ func (r *databaseResource) Create(
|
|||
|
||||
ctx = core.InitProviderContext(ctx)
|
||||
|
||||
projectId := model.ProjectId.ValueString()
|
||||
projectID := model.ProjectId.ValueString()
|
||||
region := model.Region.ValueString()
|
||||
instanceId := model.InstanceId.ValueString()
|
||||
instanceID := model.InstanceId.ValueString()
|
||||
|
||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
||||
ctx = tflog.SetField(ctx, "project_id", projectID)
|
||||
ctx = tflog.SetField(ctx, "instance_id", instanceID)
|
||||
ctx = tflog.SetField(ctx, "region", region)
|
||||
|
||||
// Generate API request body from model
|
||||
|
|
@ -200,9 +163,9 @@ func (r *databaseResource) Create(
|
|||
// Create new database
|
||||
databaseResp, err := r.client.DefaultAPI.CreateDatabaseRequest(
|
||||
ctx,
|
||||
projectId,
|
||||
projectID,
|
||||
region,
|
||||
instanceId,
|
||||
instanceID,
|
||||
).CreateDatabaseRequestPayload(*payload).Execute()
|
||||
if err != nil {
|
||||
core.LogAndAddError(ctx, &resp.Diagnostics, funcErrorSummary, fmt.Sprintf("Calling API: %v", err))
|
||||
|
|
@ -219,23 +182,33 @@ func (r *databaseResource) Create(
|
|||
)
|
||||
return
|
||||
}
|
||||
databaseId := int64(*dbID)
|
||||
ctx = tflog.SetField(ctx, "database_id", databaseId)
|
||||
databaseID := int64(*dbID)
|
||||
databaseIDString := strconv.Itoa(int(*dbID))
|
||||
|
||||
ctx = tflog.SetField(ctx, "database_id", databaseID)
|
||||
ctx = core.LogResponse(ctx)
|
||||
|
||||
// Save identity into Terraform state
|
||||
identity := DatabaseResourceIdentityModel{
|
||||
ProjectID: types.StringValue(projectId),
|
||||
Region: types.StringValue(region),
|
||||
InstanceID: types.StringValue(instanceId),
|
||||
DatabaseID: types.Int64Value(databaseId),
|
||||
}
|
||||
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
model.DatabaseId = types.Int64Value(databaseID)
|
||||
model.Id = utils.BuildInternalTerraformId(projectID, region, instanceID, databaseIDString)
|
||||
|
||||
database, err := postgresflexalphaWait.GetDatabaseByIdWaitHandler(ctx, r.client.DefaultAPI, projectId, instanceId, region, databaseId).
|
||||
// Set data returned by API in id
|
||||
resp.Diagnostics.Append(
|
||||
resp.State.SetAttribute(
|
||||
ctx,
|
||||
path.Root("database_id"),
|
||||
databaseID,
|
||||
)...,
|
||||
)
|
||||
// Set data returned by API in id
|
||||
resp.Diagnostics.Append(
|
||||
resp.State.SetAttribute(
|
||||
ctx,
|
||||
path.Root("id"),
|
||||
model.Id,
|
||||
)...,
|
||||
)
|
||||
|
||||
database, err := postgresflexalphaWait.GetDatabaseByIdWaitHandler(ctx, r.client.DefaultAPI, projectID, instanceID, region, databaseID).
|
||||
SetTimeout(15 * time.Minute).
|
||||
SetSleepBeforeWait(15 * time.Second).
|
||||
WaitWithContext(ctx)
|
||||
|
|
@ -284,17 +257,28 @@ func (r *databaseResource) Read(
|
|||
|
||||
ctx = core.InitProviderContext(ctx)
|
||||
|
||||
projectId := model.ProjectId.ValueString()
|
||||
instanceId := model.InstanceId.ValueString()
|
||||
projectID := model.ProjectId.ValueString()
|
||||
instanceID := model.InstanceId.ValueString()
|
||||
region := model.Region.ValueString()
|
||||
databaseId := model.DatabaseId.ValueInt64()
|
||||
databaseID := model.DatabaseId.ValueInt64()
|
||||
|
||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
||||
databaseIDString := strconv.Itoa(int(databaseID))
|
||||
|
||||
ctx = tflog.SetField(ctx, "project_id", projectID)
|
||||
ctx = tflog.SetField(ctx, "instance_id", instanceID)
|
||||
ctx = tflog.SetField(ctx, "region", region)
|
||||
ctx = tflog.SetField(ctx, "database_id", databaseId)
|
||||
ctx = tflog.SetField(ctx, "database_id", databaseID)
|
||||
|
||||
databaseResp, err := postgresflexalphaWait.GetDatabaseByIdWaitHandler(ctx, r.client.DefaultAPI, projectId, instanceId, region, databaseId).
|
||||
// Set data returned by API in id
|
||||
resp.Diagnostics.Append(
|
||||
resp.State.SetAttribute(
|
||||
ctx,
|
||||
path.Root("id"),
|
||||
utils.BuildInternalTerraformId(projectID, region, instanceID, databaseIDString),
|
||||
)...,
|
||||
)
|
||||
|
||||
databaseResp, err := postgresflexalphaWait.GetDatabaseByIdWaitHandler(ctx, r.client.DefaultAPI, projectID, instanceID, region, databaseID).
|
||||
SetTimeout(15 * time.Minute).
|
||||
SetSleepBeforeWait(15 * time.Second).
|
||||
WaitWithContext(ctx)
|
||||
|
|
@ -322,18 +306,6 @@ func (r *databaseResource) Read(
|
|||
return
|
||||
}
|
||||
|
||||
// Save identity into Terraform state
|
||||
identity := DatabaseResourceIdentityModel{
|
||||
ProjectID: types.StringValue(projectId),
|
||||
Region: types.StringValue(region),
|
||||
InstanceID: types.StringValue(instanceId),
|
||||
DatabaseID: types.Int64Value(int64(databaseResp.GetId())),
|
||||
}
|
||||
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
// Set refreshed state
|
||||
diags = resp.State.Set(ctx, model)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
|
|
@ -436,18 +408,6 @@ func (r *databaseResource) Update(
|
|||
return
|
||||
}
|
||||
|
||||
// Save identity into Terraform state
|
||||
identity := DatabaseResourceIdentityModel{
|
||||
ProjectID: types.StringValue(projectId),
|
||||
Region: types.StringValue(region),
|
||||
InstanceID: types.StringValue(instanceId),
|
||||
DatabaseID: types.Int64Value(databaseId),
|
||||
}
|
||||
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
// Set state to fully populated data
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &model)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
|
|
@ -469,38 +429,33 @@ func (r *databaseResource) Delete(
|
|||
return
|
||||
}
|
||||
|
||||
// Read identity data
|
||||
var identityData DatabaseResourceIdentityModel
|
||||
resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
ctx = core.InitProviderContext(ctx)
|
||||
|
||||
projectId, region, instanceId, databaseId64, errExt := r.extractIdentityData(model, identityData)
|
||||
if errExt != nil {
|
||||
core.LogAndAddError(
|
||||
ctx,
|
||||
&resp.Diagnostics,
|
||||
extractErrorSummary,
|
||||
fmt.Sprintf(extractErrorMessage, errExt),
|
||||
)
|
||||
}
|
||||
projectID := model.ProjectId.ValueString()
|
||||
instanceID := model.InstanceId.ValueString()
|
||||
region := model.Region.ValueString()
|
||||
databaseID64 := model.DatabaseId.ValueInt64()
|
||||
|
||||
if databaseId64 > math.MaxInt32 {
|
||||
if databaseID64 > math.MaxInt32 {
|
||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error in type conversion", "int value too large (databaseId)")
|
||||
return
|
||||
}
|
||||
databaseId := int32(databaseId64) // nolint:gosec // check is performed above
|
||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
||||
databaseID := int32(databaseID64) // nolint:gosec // check is performed above
|
||||
ctx = tflog.SetField(ctx, "project_id", projectID)
|
||||
ctx = tflog.SetField(ctx, "instance_id", instanceID)
|
||||
ctx = tflog.SetField(ctx, "region", region)
|
||||
ctx = tflog.SetField(ctx, "database_id", databaseId)
|
||||
ctx = tflog.SetField(ctx, "database_id", databaseID)
|
||||
|
||||
// Delete existing record set
|
||||
err := r.client.DefaultAPI.DeleteDatabaseRequest(ctx, projectId, region, instanceId, databaseId).Execute()
|
||||
err := r.client.DefaultAPI.DeleteDatabaseRequest(ctx, projectID, region, instanceID, databaseID).Execute()
|
||||
if err != nil {
|
||||
oapiErr, ok := err.(*oapierror.GenericOpenAPIError) // nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped
|
||||
if ok {
|
||||
if oapiErr.StatusCode == 404 {
|
||||
resp.State.RemoveResource(ctx)
|
||||
return
|
||||
}
|
||||
}
|
||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting database", fmt.Sprintf("Calling API: %v", err))
|
||||
}
|
||||
|
||||
|
|
@ -517,109 +472,44 @@ func (r *databaseResource) ImportState(
|
|||
resp *resource.ImportStateResponse,
|
||||
) {
|
||||
ctx = core.InitProviderContext(ctx)
|
||||
idParts := strings.Split(req.ID, core.Separator)
|
||||
|
||||
if req.ID != "" {
|
||||
idParts := strings.Split(req.ID, core.Separator)
|
||||
if len(idParts) != 4 || idParts[0] == "" || idParts[1] == "" || idParts[2] == "" || idParts[3] == "" {
|
||||
core.LogAndAddError(
|
||||
ctx, &resp.Diagnostics,
|
||||
"Error importing database",
|
||||
fmt.Sprintf(
|
||||
"Expected import identifier with format [project_id],[region],[instance_id],[database_id], got %q",
|
||||
req.ID,
|
||||
),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
if len(idParts) != 4 || idParts[0] == "" || idParts[1] == "" || idParts[2] == "" || idParts[3] == "" {
|
||||
core.LogAndAddError(
|
||||
ctx, &resp.Diagnostics,
|
||||
"Error importing database",
|
||||
fmt.Sprintf(
|
||||
"Expected import identifier with format [project_id],[region],[instance_id],[database_id], got %q",
|
||||
req.ID,
|
||||
),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
databaseId, err := strconv.ParseInt(idParts[3], 10, 64)
|
||||
if err != nil {
|
||||
core.LogAndAddError(
|
||||
ctx,
|
||||
&resp.Diagnostics,
|
||||
"Error importing database",
|
||||
fmt.Sprintf("Invalid database_id format: %q. It must be a valid integer.", idParts[3]),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), idParts[0])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), idParts[1])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), idParts[2])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("database_id"), databaseId)...)
|
||||
|
||||
core.LogAndAddWarning(
|
||||
databaseID, err := strconv.ParseInt(idParts[3], 10, 64)
|
||||
if err != nil {
|
||||
core.LogAndAddError(
|
||||
ctx,
|
||||
&resp.Diagnostics,
|
||||
"Postgresflex database imported with empty password",
|
||||
"The database password is not imported as it is only available upon creation of a new database. The password field will be empty.",
|
||||
"Error importing database",
|
||||
fmt.Sprintf("Invalid database_id format: %q. It must be a valid integer.", idParts[3]),
|
||||
)
|
||||
|
||||
tflog.Info(ctx, "Postgres Flex database state imported")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// If no ID is provided, attempt to read identity attributes from the import configuration
|
||||
var identityData DatabaseResourceIdentityModel
|
||||
resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
tfIDString := utils.BuildInternalTerraformId(idParts...).ValueString()
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("id"), tfIDString)...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), idParts[0])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), idParts[1])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), idParts[2])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("database_id"), databaseID)...)
|
||||
|
||||
projectId := identityData.ProjectID.ValueString()
|
||||
region := identityData.Region.ValueString()
|
||||
instanceId := identityData.InstanceID.ValueString()
|
||||
databaseId := identityData.DatabaseID.ValueInt64()
|
||||
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), projectId)...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), region)...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), instanceId)...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("database_id"), databaseId)...)
|
||||
core.LogAndAddWarning(
|
||||
ctx,
|
||||
&resp.Diagnostics,
|
||||
"Postgresflex database imported with empty password",
|
||||
"The database password is not imported as it is only available upon creation of a new database. The password field will be empty.",
|
||||
)
|
||||
|
||||
tflog.Info(ctx, "Postgres Flex database state imported")
|
||||
}
|
||||
|
||||
// extractIdentityData extracts essential identifiers from the resource model, falling back to the identity model.
|
||||
func (r *databaseResource) extractIdentityData(
|
||||
model resourceModel,
|
||||
identity DatabaseResourceIdentityModel,
|
||||
) (projectId, region, instanceId string, databaseId int64, err error) {
|
||||
if !model.DatabaseId.IsNull() && !model.DatabaseId.IsUnknown() {
|
||||
databaseId = model.DatabaseId.ValueInt64()
|
||||
} else {
|
||||
if identity.DatabaseID.IsNull() || identity.DatabaseID.IsUnknown() {
|
||||
return "", "", "", 0, fmt.Errorf("database_id not found in config")
|
||||
}
|
||||
databaseId = identity.DatabaseID.ValueInt64()
|
||||
}
|
||||
|
||||
if !model.ProjectId.IsNull() && !model.ProjectId.IsUnknown() {
|
||||
projectId = model.ProjectId.ValueString()
|
||||
} else {
|
||||
if identity.ProjectID.IsNull() || identity.ProjectID.IsUnknown() {
|
||||
return "", "", "", 0, fmt.Errorf("project_id not found in config")
|
||||
}
|
||||
projectId = identity.ProjectID.ValueString()
|
||||
}
|
||||
|
||||
if !model.Region.IsNull() && !model.Region.IsUnknown() {
|
||||
region = r.providerData.GetRegionWithOverride(model.Region)
|
||||
} else {
|
||||
if identity.Region.IsNull() || identity.Region.IsUnknown() {
|
||||
return "", "", "", 0, fmt.Errorf("region not found in config")
|
||||
}
|
||||
region = r.providerData.GetRegionWithOverride(identity.Region)
|
||||
}
|
||||
|
||||
if !model.InstanceId.IsNull() && !model.InstanceId.IsUnknown() {
|
||||
instanceId = model.InstanceId.ValueString()
|
||||
} else {
|
||||
if identity.InstanceID.IsNull() || identity.InstanceID.IsUnknown() {
|
||||
return "", "", "", 0, fmt.Errorf("instance_id not found in config")
|
||||
}
|
||||
instanceId = identity.InstanceID.ValueString()
|
||||
}
|
||||
return projectId, region, instanceId, databaseId, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ func DatabaseResourceSchema(ctx context.Context) schema.Schema {
|
|||
Description: "The ID of the database.",
|
||||
MarkdownDescription: "The ID of the database.",
|
||||
},
|
||||
"id": schema.Int64Attribute{
|
||||
"id": schema.StringAttribute{
|
||||
Computed: true,
|
||||
Description: "The id of the database.",
|
||||
MarkdownDescription: "The id of the database.",
|
||||
|
|
@ -65,7 +65,7 @@ func DatabaseResourceSchema(ctx context.Context) schema.Schema {
|
|||
|
||||
type DatabaseModel struct {
|
||||
DatabaseId types.Int64 `tfsdk:"database_id"`
|
||||
Id types.Int64 `tfsdk:"id"`
|
||||
Id types.String `tfsdk:"id"`
|
||||
InstanceId types.String `tfsdk:"instance_id"`
|
||||
Name types.String `tfsdk:"name"`
|
||||
Owner types.String `tfsdk:"owner"`
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v3alpha1api"
|
||||
|
||||
|
|
@ -72,7 +73,13 @@ func (r *instanceDataSource) Configure(
|
|||
|
||||
// Schema defines the schema for the data source.
|
||||
func (r *instanceDataSource) Schema(ctx context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
|
||||
resp.Schema = postgresflexalpha2.InstanceDataSourceSchema(ctx)
|
||||
sch := postgresflexalpha2.InstanceDataSourceSchema(ctx)
|
||||
sch.Attributes["id"] = schema.StringAttribute{
|
||||
Computed: true,
|
||||
Description: "internal ID",
|
||||
MarkdownDescription: "internal ID",
|
||||
}
|
||||
resp.Schema = sch
|
||||
}
|
||||
|
||||
// Read refreshes the Terraform state with the latest data.
|
||||
|
|
@ -90,22 +97,22 @@ func (r *instanceDataSource) Read(
|
|||
|
||||
ctx = core.InitProviderContext(ctx)
|
||||
|
||||
projectId := model.ProjectId.ValueString()
|
||||
instanceId := model.InstanceId.ValueString()
|
||||
projectID := model.ProjectId.ValueString()
|
||||
instanceID := model.InstanceId.ValueString()
|
||||
region := r.providerData.GetRegionWithOverride(model.Region)
|
||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
||||
ctx = tflog.SetField(ctx, "project_id", projectID)
|
||||
ctx = tflog.SetField(ctx, "instance_id", instanceID)
|
||||
ctx = tflog.SetField(ctx, "region", region)
|
||||
instanceResp, err := r.client.DefaultAPI.GetInstanceRequest(ctx, projectId, region, instanceId).Execute()
|
||||
instanceResp, err := r.client.DefaultAPI.GetInstanceRequest(ctx, projectID, region, instanceID).Execute()
|
||||
if err != nil {
|
||||
utils.LogError(
|
||||
ctx,
|
||||
&resp.Diagnostics,
|
||||
err,
|
||||
"Reading instance",
|
||||
fmt.Sprintf("Instance with ID %q does not exist in project %q.", instanceId, projectId),
|
||||
fmt.Sprintf("Instance with ID %q does not exist in project %q.", instanceID, projectID),
|
||||
map[int]string{
|
||||
http.StatusForbidden: fmt.Sprintf("Project with ID %q not found or forbidden access", projectId),
|
||||
http.StatusForbidden: fmt.Sprintf("Project with ID %q not found or forbidden access", projectID),
|
||||
},
|
||||
)
|
||||
resp.State.RemoveResource(ctx)
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ func InstanceDataSourceSchema(ctx context.Context) schema.Schema {
|
|||
MarkdownDescription: "The STACKIT project ID.",
|
||||
},
|
||||
"region": schema.StringAttribute{
|
||||
Required: true,
|
||||
Optional: true,
|
||||
Description: "The region which should be addressed",
|
||||
MarkdownDescription: "The region which should be addressed",
|
||||
Validators: []validator.String{
|
||||
|
|
|
|||
|
|
@ -55,23 +55,21 @@ func mapGetInstanceResponseToModel(
|
|||
}
|
||||
|
||||
m.FlavorId = types.StringValue(resp.GetFlavorId())
|
||||
if m.Id.IsNull() || m.Id.IsUnknown() {
|
||||
m.Id = utils.BuildInternalTerraformId(
|
||||
m.ProjectId.ValueString(),
|
||||
m.Region.ValueString(),
|
||||
m.InstanceId.ValueString(),
|
||||
)
|
||||
}
|
||||
m.Id = utils.BuildInternalTerraformId(
|
||||
m.ProjectId.ValueString(),
|
||||
m.Region.ValueString(),
|
||||
resp.Id,
|
||||
)
|
||||
m.InstanceId = types.StringValue(resp.Id)
|
||||
|
||||
m.IsDeletable = types.BoolValue(resp.GetIsDeletable())
|
||||
|
||||
netAcl, diags := types.ListValueFrom(ctx, types.StringType, resp.Network.GetAcl())
|
||||
netACL, diags := types.ListValueFrom(ctx, types.StringType, resp.Network.GetAcl())
|
||||
if diags.HasError() {
|
||||
return fmt.Errorf("failed converting network acl from response")
|
||||
}
|
||||
|
||||
m.Acl = netAcl
|
||||
m.Acl = netACL
|
||||
|
||||
netInstAdd := types.StringValue("")
|
||||
if instAdd, ok := resp.Network.GetInstanceAddressOk(); ok {
|
||||
|
|
@ -87,7 +85,7 @@ func mapGetInstanceResponseToModel(
|
|||
postgresflexalpharesource.NetworkValue{}.AttributeTypes(ctx),
|
||||
map[string]attr.Value{
|
||||
"access_scope": basetypes.NewStringValue(string(resp.Network.GetAccessScope())),
|
||||
"acl": netAcl,
|
||||
"acl": netACL,
|
||||
"instance_address": netInstAdd,
|
||||
"router_address": netRtrAdd,
|
||||
},
|
||||
|
|
@ -130,7 +128,8 @@ func mapGetDataInstanceResponseToModel(
|
|||
handleConnectionInfo(ctx, m, resp)
|
||||
|
||||
m.FlavorId = types.StringValue(resp.GetFlavorId())
|
||||
m.Id = utils.BuildInternalTerraformId(m.ProjectId.ValueString(), m.Region.ValueString(), m.InstanceId.ValueString())
|
||||
m.Id = types.StringValue(resp.Id)
|
||||
m.TerraformID = utils.BuildInternalTerraformId(m.ProjectId.ValueString(), m.Region.ValueString(), m.InstanceId.ValueString())
|
||||
m.InstanceId = types.StringValue(resp.Id)
|
||||
m.IsDeletable = types.BoolValue(resp.GetIsDeletable())
|
||||
m.Name = types.StringValue(resp.GetName())
|
||||
|
|
@ -212,14 +211,14 @@ func handleNetwork(ctx context.Context, m *dataSourceModel, resp *postgresflex.G
|
|||
}
|
||||
|
||||
func handleEncryption(m *dataSourceModel, resp *postgresflex.GetInstanceResponse) {
|
||||
keyId := ""
|
||||
if keyIdVal, ok := resp.Encryption.GetKekKeyIdOk(); ok {
|
||||
keyId = *keyIdVal
|
||||
keyID := ""
|
||||
if keyIDVal, ok := resp.Encryption.GetKekKeyIdOk(); ok {
|
||||
keyID = *keyIDVal
|
||||
}
|
||||
|
||||
keyRingId := ""
|
||||
if keyRingIdVal, ok := resp.Encryption.GetKekKeyRingIdOk(); ok {
|
||||
keyRingId = *keyRingIdVal
|
||||
keyRingID := ""
|
||||
if keyRingIDVal, ok := resp.Encryption.GetKekKeyRingIdOk(); ok {
|
||||
keyRingID = *keyRingIDVal
|
||||
}
|
||||
|
||||
keyVersion := ""
|
||||
|
|
@ -233,8 +232,8 @@ func handleEncryption(m *dataSourceModel, resp *postgresflex.GetInstanceResponse
|
|||
}
|
||||
|
||||
m.Encryption = postgresflexalphadatasource.EncryptionValue{
|
||||
KekKeyId: types.StringValue(keyId),
|
||||
KekKeyRingId: types.StringValue(keyRingId),
|
||||
KekKeyId: types.StringValue(keyID),
|
||||
KekKeyRingId: types.StringValue(keyRingID),
|
||||
KekKeyVersion: types.StringValue(keyVersion),
|
||||
ServiceAccount: types.StringValue(svcAcc),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,11 +7,10 @@ import (
|
|||
"math"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource/identityschema"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
|
||||
coreUtils "github.com/stackitcloud/stackit-sdk-go/core/utils"
|
||||
|
|
@ -32,7 +31,6 @@ var (
|
|||
_ resource.ResourceWithImportState = &instanceResource{}
|
||||
_ resource.ResourceWithModifyPlan = &instanceResource{}
|
||||
_ resource.ResourceWithValidateConfig = &instanceResource{}
|
||||
_ resource.ResourceWithIdentity = &instanceResource{}
|
||||
)
|
||||
|
||||
// NewInstanceResource is a helper function to simplify the provider implementation.
|
||||
|
|
@ -40,15 +38,6 @@ func NewInstanceResource() resource.Resource {
|
|||
return &instanceResource{}
|
||||
}
|
||||
|
||||
// resourceModel describes the resource data model.
|
||||
type resourceModel = postgresflexalpha.InstanceModel
|
||||
|
||||
type InstanceResourceIdentityModel struct {
|
||||
ProjectID types.String `tfsdk:"project_id"`
|
||||
Region types.String `tfsdk:"region"`
|
||||
InstanceID types.String `tfsdk:"instance_id"`
|
||||
}
|
||||
|
||||
// instanceResource is the resource implementation.
|
||||
type instanceResource struct {
|
||||
client *v3alpha1api.APIClient
|
||||
|
|
@ -60,7 +49,7 @@ func (r *instanceResource) ValidateConfig(
|
|||
req resource.ValidateConfigRequest,
|
||||
resp *resource.ValidateConfigResponse,
|
||||
) {
|
||||
var data resourceModel
|
||||
var data postgresflexalpha.InstanceModel
|
||||
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
|
||||
|
||||
if resp.Diagnostics.HasError() {
|
||||
|
|
@ -84,7 +73,7 @@ func (r *instanceResource) ModifyPlan(
|
|||
req resource.ModifyPlanRequest,
|
||||
resp *resource.ModifyPlanResponse,
|
||||
) { // nolint:gocritic // function signature required by Terraform
|
||||
var configModel resourceModel
|
||||
var configModel postgresflexalpha.InstanceModel
|
||||
// skip initial empty configuration to avoid follow-up errors
|
||||
if req.Config.Raw.IsNull() {
|
||||
return
|
||||
|
|
@ -94,7 +83,7 @@ func (r *instanceResource) ModifyPlan(
|
|||
return
|
||||
}
|
||||
|
||||
var planModel resourceModel
|
||||
var planModel postgresflexalpha.InstanceModel
|
||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &planModel)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
|
|
@ -160,33 +149,13 @@ func (r *instanceResource) Schema(ctx context.Context, _ resource.SchemaRequest,
|
|||
resp.Schema = schema
|
||||
}
|
||||
|
||||
func (r *instanceResource) IdentitySchema(
|
||||
_ context.Context,
|
||||
_ resource.IdentitySchemaRequest,
|
||||
resp *resource.IdentitySchemaResponse,
|
||||
) {
|
||||
resp.IdentitySchema = identityschema.Schema{
|
||||
Attributes: map[string]identityschema.Attribute{
|
||||
"project_id": identityschema.StringAttribute{
|
||||
RequiredForImport: true, // must be set during import by the practitioner
|
||||
},
|
||||
"region": identityschema.StringAttribute{
|
||||
RequiredForImport: true, // can be defaulted by the provider configuration
|
||||
},
|
||||
"instance_id": identityschema.StringAttribute{
|
||||
RequiredForImport: true, // can be defaulted by the provider configuration
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Create creates the resource and sets the initial Terraform state.
|
||||
func (r *instanceResource) Create(
|
||||
ctx context.Context,
|
||||
req resource.CreateRequest,
|
||||
resp *resource.CreateResponse,
|
||||
) { // nolint:gocritic // function signature required by Terraform
|
||||
var model resourceModel
|
||||
var model postgresflexalpha.InstanceModel
|
||||
|
||||
diags := req.Plan.Get(ctx, &model)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
|
|
@ -201,15 +170,15 @@ func (r *instanceResource) Create(
|
|||
ctx = tflog.SetField(ctx, "project_id", projectID)
|
||||
ctx = tflog.SetField(ctx, "region", region)
|
||||
|
||||
var netAcl []string
|
||||
diag := model.Network.Acl.ElementsAs(ctx, &netAcl, false)
|
||||
var netACL []string
|
||||
diag := model.Network.Acl.ElementsAs(ctx, &netACL, false)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if diag.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
replVal := model.Replicas.ValueInt64() // nolint:gosec // check is performed above
|
||||
payload := modelToCreateInstancePayload(netAcl, model, replVal)
|
||||
payload := modelToCreateInstancePayload(netACL, model, replVal)
|
||||
|
||||
// Create new instance
|
||||
createResp, err := r.client.DefaultAPI.CreateInstanceRequest(
|
||||
|
|
@ -229,18 +198,18 @@ func (r *instanceResource) Create(
|
|||
return
|
||||
}
|
||||
|
||||
// Set data returned by API in identity
|
||||
identity := InstanceResourceIdentityModel{
|
||||
ProjectID: types.StringValue(projectID),
|
||||
Region: types.StringValue(region),
|
||||
InstanceID: types.StringPointerValue(instanceID),
|
||||
}
|
||||
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
// Set data returned by API in id
|
||||
resp.Diagnostics.Append(
|
||||
resp.State.SetAttribute(
|
||||
ctx,
|
||||
path.Root("id"),
|
||||
utils.BuildInternalTerraformId(projectID, region, *instanceID),
|
||||
)...,
|
||||
)
|
||||
|
||||
waitResp, err := wait.CreateInstanceWaitHandler(ctx, r.client.DefaultAPI, projectID, region, *instanceID).
|
||||
SetTimeout(30 * time.Minute).
|
||||
SetSleepBeforeWait(10 * time.Second).
|
||||
WaitWithContext(ctx)
|
||||
if err != nil {
|
||||
core.LogAndAddError(
|
||||
|
|
@ -314,7 +283,7 @@ func (r *instanceResource) Read(
|
|||
) { // nolint:gocritic // function signature required by Terraform
|
||||
functionErrorSummary := "read instance failed"
|
||||
|
||||
var model resourceModel
|
||||
var model postgresflexalpha.InstanceModel
|
||||
diags := req.State.Get(ctx, &model)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
|
|
@ -323,9 +292,9 @@ func (r *instanceResource) Read(
|
|||
|
||||
ctx = core.InitProviderContext(ctx)
|
||||
|
||||
var projectId string
|
||||
var projectID string
|
||||
if !model.ProjectId.IsNull() && !model.ProjectId.IsUnknown() {
|
||||
projectId = model.ProjectId.ValueString()
|
||||
projectID = model.ProjectId.ValueString()
|
||||
}
|
||||
|
||||
var region string
|
||||
|
|
@ -333,16 +302,16 @@ func (r *instanceResource) Read(
|
|||
region = r.providerData.GetRegionWithOverride(model.Region)
|
||||
}
|
||||
|
||||
var instanceId string
|
||||
var instanceID string
|
||||
if !model.InstanceId.IsNull() && !model.InstanceId.IsUnknown() {
|
||||
instanceId = model.InstanceId.ValueString()
|
||||
instanceID = model.InstanceId.ValueString()
|
||||
}
|
||||
|
||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
||||
ctx = tflog.SetField(ctx, "project_id", projectID)
|
||||
ctx = tflog.SetField(ctx, "instance_id", instanceID)
|
||||
ctx = tflog.SetField(ctx, "region", region)
|
||||
|
||||
instanceResp, err := r.client.DefaultAPI.GetInstanceRequest(ctx, projectId, region, instanceId).Execute()
|
||||
instanceResp, err := r.client.DefaultAPI.GetInstanceRequest(ctx, projectID, region, instanceID).Execute()
|
||||
if err != nil {
|
||||
oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped
|
||||
if ok && oapiErr.StatusCode == http.StatusNotFound {
|
||||
|
|
@ -361,7 +330,7 @@ func (r *instanceResource) Read(
|
|||
return
|
||||
}
|
||||
if !model.InstanceId.IsUnknown() && !model.InstanceId.IsNull() {
|
||||
if *respInstanceID != instanceId {
|
||||
if *respInstanceID != instanceID {
|
||||
core.LogAndAddError(
|
||||
ctx,
|
||||
&resp.Diagnostics,
|
||||
|
|
@ -372,6 +341,10 @@ func (r *instanceResource) Read(
|
|||
}
|
||||
}
|
||||
|
||||
if model.Id.IsUnknown() || model.Id.IsNull() {
|
||||
model.Id = utils.BuildInternalTerraformId(projectID, region, instanceID)
|
||||
}
|
||||
|
||||
err = mapGetInstanceResponseToModel(ctx, &model, instanceResp)
|
||||
if err != nil {
|
||||
core.LogAndAddError(
|
||||
|
|
@ -389,17 +362,6 @@ func (r *instanceResource) Read(
|
|||
return
|
||||
}
|
||||
|
||||
// Set data returned by API in identity
|
||||
identity := InstanceResourceIdentityModel{
|
||||
ProjectID: types.StringValue(projectId),
|
||||
Region: types.StringValue(region),
|
||||
InstanceID: types.StringValue(instanceId),
|
||||
}
|
||||
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
tflog.Info(ctx, "Postgres Flex instance read")
|
||||
}
|
||||
|
||||
|
|
@ -409,7 +371,7 @@ func (r *instanceResource) Update(
|
|||
req resource.UpdateRequest,
|
||||
resp *resource.UpdateResponse,
|
||||
) { // nolint:gocritic // function signature required by Terraform
|
||||
var model resourceModel
|
||||
var model postgresflexalpha.InstanceModel
|
||||
|
||||
diags := req.Plan.Get(ctx, &model)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
|
|
@ -419,15 +381,8 @@ func (r *instanceResource) Update(
|
|||
|
||||
ctx = core.InitProviderContext(ctx)
|
||||
|
||||
// Read identity data
|
||||
var identityData InstanceResourceIdentityModel
|
||||
resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
projectID := identityData.ProjectID.ValueString()
|
||||
instanceID := identityData.InstanceID.ValueString()
|
||||
projectID := model.ProjectId.ValueString()
|
||||
instanceID := model.InstanceId.ValueString()
|
||||
region := model.Region.ValueString()
|
||||
ctx = tflog.SetField(ctx, "project_id", projectID)
|
||||
ctx = tflog.SetField(ctx, "instance_id", instanceID)
|
||||
|
|
@ -490,7 +445,10 @@ func (r *instanceResource) Update(
|
|||
projectID,
|
||||
region,
|
||||
instanceID,
|
||||
).WaitWithContext(ctx)
|
||||
).
|
||||
SetTimeout(30 * time.Minute).
|
||||
SetSleepBeforeWait(10 * time.Second).
|
||||
WaitWithContext(ctx)
|
||||
if err != nil {
|
||||
core.LogAndAddError(
|
||||
ctx,
|
||||
|
|
@ -526,7 +484,7 @@ func (r *instanceResource) Delete(
|
|||
req resource.DeleteRequest,
|
||||
resp *resource.DeleteResponse,
|
||||
) { // nolint:gocritic // function signature required by Terraform
|
||||
var model resourceModel
|
||||
var model postgresflexalpha.InstanceModel
|
||||
|
||||
diags := req.State.Get(ctx, &model)
|
||||
resp.Diagnostics.Append(diags...)
|
||||
|
|
@ -536,15 +494,15 @@ func (r *instanceResource) Delete(
|
|||
|
||||
ctx = core.InitProviderContext(ctx)
|
||||
|
||||
projectId := model.ProjectId.ValueString()
|
||||
instanceId := model.InstanceId.ValueString()
|
||||
projectID := model.ProjectId.ValueString()
|
||||
instanceID := model.InstanceId.ValueString()
|
||||
region := model.Region.ValueString()
|
||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
||||
ctx = tflog.SetField(ctx, "project_id", projectID)
|
||||
ctx = tflog.SetField(ctx, "instance_id", instanceID)
|
||||
ctx = tflog.SetField(ctx, "region", region)
|
||||
|
||||
// Delete existing instance
|
||||
err := r.client.DefaultAPI.DeleteInstanceRequest(ctx, projectId, region, instanceId).Execute()
|
||||
err := r.client.DefaultAPI.DeleteInstanceRequest(ctx, projectID, region, instanceID).Execute()
|
||||
if err != nil {
|
||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting instance", fmt.Sprintf("Calling API: %v", err))
|
||||
return
|
||||
|
|
@ -552,7 +510,7 @@ func (r *instanceResource) Delete(
|
|||
|
||||
ctx = core.LogResponse(ctx)
|
||||
|
||||
_, err = r.client.DefaultAPI.GetInstanceRequest(ctx, projectId, region, instanceId).Execute()
|
||||
_, err = r.client.DefaultAPI.GetInstanceRequest(ctx, projectID, region, instanceID).Execute()
|
||||
if err != nil {
|
||||
oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped
|
||||
if ok && oapiErr.StatusCode != http.StatusNotFound {
|
||||
|
|
@ -574,41 +532,30 @@ func (r *instanceResource) ImportState(
|
|||
) {
|
||||
ctx = core.InitProviderContext(ctx)
|
||||
|
||||
if req.ID != "" {
|
||||
idParts := strings.Split(req.ID, core.Separator)
|
||||
idParts := strings.Split(req.ID, core.Separator)
|
||||
|
||||
if len(idParts) != 3 || idParts[0] == "" || idParts[1] == "" || idParts[2] == "" {
|
||||
core.LogAndAddError(
|
||||
ctx, &resp.Diagnostics,
|
||||
"Error importing instance",
|
||||
fmt.Sprintf(
|
||||
"Expected import identifier with format [project_id],[region],[instance_id] Got: %q",
|
||||
req.ID,
|
||||
),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), idParts[0])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), idParts[1])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), idParts[2])...)
|
||||
if len(idParts) != 3 || idParts[0] == "" || idParts[1] == "" || idParts[2] == "" {
|
||||
core.LogAndAddError(
|
||||
ctx, &resp.Diagnostics,
|
||||
"Error importing instance",
|
||||
fmt.Sprintf(
|
||||
"Expected import identifier with format [project_id],[region],[instance_id] Got: %q",
|
||||
req.ID,
|
||||
),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// If no ID is provided, attempt to read identity attributes from the import configuration
|
||||
var identityData InstanceResourceIdentityModel
|
||||
resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
projectId := identityData.ProjectID.ValueString()
|
||||
region := identityData.Region.ValueString()
|
||||
instanceId := identityData.InstanceID.ValueString()
|
||||
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), projectId)...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), region)...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), instanceId)...)
|
||||
resp.Diagnostics.Append(
|
||||
resp.State.SetAttribute(
|
||||
ctx,
|
||||
path.Root("id"),
|
||||
utils.BuildInternalTerraformId(idParts...),
|
||||
)...,
|
||||
)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), idParts[0])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), idParts[1])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), idParts[2])...)
|
||||
|
||||
tflog.Info(ctx, "Postgres Flex instance state imported")
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -23,16 +23,21 @@ resource "stackitprivatepreview_postgresflexalpha_instance" "{{ .TfName }}" {
|
|||
}
|
||||
{{ end }}
|
||||
network = {
|
||||
acl = ["{{ .ACLString }}"]
|
||||
acl = [{{ range $i, $v := .ACLStrings }}{{if $i}},{{end}}"{{$v}}"{{end}}]
|
||||
access_scope = "{{ .AccessScope }}"
|
||||
}
|
||||
version = {{ .Version }}
|
||||
{{ if .Version }}
|
||||
version = "{{ .Version }}"
|
||||
{{ end }}
|
||||
}
|
||||
|
||||
{{ if .Users }}
|
||||
{{ $tfName := .TfName }}
|
||||
{{ range $user := .Users }}
|
||||
resource "stackitprivatepreview_postgresflexalpha_user" "{{ $user.Name }}" {
|
||||
depends_on = [
|
||||
stackitprivatepreview_postgresflexalpha_instance.{{ $tfName }}
|
||||
]
|
||||
project_id = "{{ $user.ProjectID }}"
|
||||
instance_id = stackitprivatepreview_postgresflexalpha_instance.{{ $tfName }}.instance_id
|
||||
name = "{{ $user.Name }}"
|
||||
|
|
@ -45,6 +50,10 @@ resource "stackitprivatepreview_postgresflexalpha_user" "{{ $user.Name }}" {
|
|||
{{ $tfName := .TfName }}
|
||||
{{ range $db := .Databases }}
|
||||
resource "stackitprivatepreview_postgresflexalpha_database" "{{ $db.Name }}" {
|
||||
depends_on = [
|
||||
stackitprivatepreview_postgresflexalpha_instance.{{ $tfName }},
|
||||
stackitprivatepreview_postgresflexalpha_user.{{ $db.Owner }}
|
||||
]
|
||||
project_id = "{{ $db.ProjectID }}"
|
||||
instance_id = stackitprivatepreview_postgresflexalpha_instance.{{ $tfName }}.instance_id
|
||||
name = "{{ $db.Name }}"
|
||||
|
|
@ -52,3 +61,32 @@ resource "stackitprivatepreview_postgresflexalpha_database" "{{ $db.Name }}" {
|
|||
}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ if .DataSourceTest }}
|
||||
data "stackitprivatepreview_postgresflexalpha_instance" "{{ .TfName }}" {
|
||||
project_id = stackitprivatepreview_postgresflexalpha_instance.{{ .TfName }}.project_id
|
||||
instance_id = stackitprivatepreview_postgresflexalpha_instance.{{ .TfName }}.instance_id
|
||||
}
|
||||
|
||||
{{ if .Users }}
|
||||
{{ $tfName := .TfName }}
|
||||
{{ range $user := .Users }}
|
||||
data "stackitprivatepreview_postgresflexalpha_user" "{{ $user.Name }}" {
|
||||
project_id = stackitprivatepreview_postgresflexalpha_instance.{{ $tfName }}.project_id
|
||||
instance_id = stackitprivatepreview_postgresflexalpha_instance.{{ $tfName }}.instance_id
|
||||
user_id = stackitprivatepreview_postgresflexalpha_user.{{ $user.Name }}.user_id
|
||||
}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
{{ if .Databases }}
|
||||
{{ $tfName := .TfName }}
|
||||
{{ range $db := .Databases }}
|
||||
data "stackitprivatepreview_postgresflexalpha_database" "{{ $db.Name }}" {
|
||||
project_id = stackitprivatepreview_postgresflexalpha_instance.{{ $tfName }}.project_id
|
||||
instance_id = stackitprivatepreview_postgresflexalpha_instance.{{ $tfName }}.instance_id
|
||||
database_id = stackitprivatepreview_postgresflexalpha_database.{{ $db.Name }}.database_id
|
||||
}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ func UserDataSourceSchema(ctx context.Context) schema.Schema {
|
|||
MarkdownDescription: "The STACKIT project ID.",
|
||||
},
|
||||
"region": schema.StringAttribute{
|
||||
Required: true,
|
||||
Optional: true,
|
||||
Description: "The region which should be addressed",
|
||||
MarkdownDescription: "The region which should be addressed",
|
||||
Validators: []validator.String{
|
||||
|
|
|
|||
|
|
@ -116,7 +116,12 @@ func mapResourceFields(userResp *v3alpha1api.GetUserResponse, model *resourceMod
|
|||
return fmt.Errorf("user id not present")
|
||||
}
|
||||
|
||||
model.Id = types.Int64Value(userID)
|
||||
model.Id = utils.BuildInternalTerraformId(
|
||||
model.ProjectId.ValueString(),
|
||||
model.Region.ValueString(),
|
||||
model.InstanceId.ValueString(),
|
||||
strconv.FormatInt(userID, 10),
|
||||
)
|
||||
model.UserId = types.Int64Value(userID)
|
||||
model.Name = types.StringValue(user.Name)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package postgresflexalpha
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
|
|
@ -165,7 +166,7 @@ func TestMapFieldsCreate(t *testing.T) {
|
|||
},
|
||||
testRegion,
|
||||
resourceModel{
|
||||
Id: types.Int64Value(1),
|
||||
Id: types.StringValue(fmt.Sprintf("%s,%s,%s,%d", "pid", testRegion, "iid", 1)),
|
||||
UserId: types.Int64Value(1),
|
||||
InstanceId: types.StringValue("iid"),
|
||||
ProjectId: types.StringValue("pid"),
|
||||
|
|
@ -187,7 +188,7 @@ func TestMapFieldsCreate(t *testing.T) {
|
|||
},
|
||||
testRegion,
|
||||
resourceModel{
|
||||
Id: types.Int64Value(1),
|
||||
Id: types.StringValue(fmt.Sprintf("%s,%s,%s,%d", "pid", testRegion, "iid", 1)),
|
||||
UserId: types.Int64Value(1),
|
||||
InstanceId: types.StringValue("iid"),
|
||||
ProjectId: types.StringValue("pid"),
|
||||
|
|
@ -209,7 +210,7 @@ func TestMapFieldsCreate(t *testing.T) {
|
|||
},
|
||||
testRegion,
|
||||
resourceModel{
|
||||
Id: types.Int64Value(1),
|
||||
Id: types.StringValue(fmt.Sprintf("%s,%s,%s,%d", "pid", testRegion, "iid", 1)),
|
||||
UserId: types.Int64Value(1),
|
||||
InstanceId: types.StringValue("iid"),
|
||||
ProjectId: types.StringValue("pid"),
|
||||
|
|
@ -249,6 +250,7 @@ func TestMapFieldsCreate(t *testing.T) {
|
|||
tt.description, func(t *testing.T) {
|
||||
state := &resourceModel{
|
||||
ProjectId: tt.expected.ProjectId,
|
||||
Region: types.StringValue(testRegion),
|
||||
InstanceId: tt.expected.InstanceId,
|
||||
}
|
||||
|
||||
|
|
@ -286,7 +288,7 @@ func TestMapFields(t *testing.T) {
|
|||
},
|
||||
testRegion,
|
||||
resourceModel{
|
||||
Id: types.Int64Value(1),
|
||||
Id: types.StringValue(fmt.Sprintf("%s,%s,%s,%d", "pid", testRegion, "iid", 1)),
|
||||
UserId: types.Int64Value(int64(1)),
|
||||
InstanceId: types.StringValue("iid"),
|
||||
ProjectId: types.StringValue("pid"),
|
||||
|
|
@ -311,7 +313,7 @@ func TestMapFields(t *testing.T) {
|
|||
},
|
||||
testRegion,
|
||||
resourceModel{
|
||||
Id: types.Int64Value(1),
|
||||
Id: types.StringValue(fmt.Sprintf("%s,%s,%s,%d", "pid", testRegion, "iid", 1)),
|
||||
UserId: types.Int64Value(1),
|
||||
InstanceId: types.StringValue("iid"),
|
||||
ProjectId: types.StringValue("pid"),
|
||||
|
|
@ -339,7 +341,7 @@ func TestMapFields(t *testing.T) {
|
|||
},
|
||||
testRegion,
|
||||
resourceModel{
|
||||
Id: types.Int64Value(1),
|
||||
Id: types.StringValue(fmt.Sprintf("%s,%s,%s,%d", "pid", testRegion, "iid", 1)),
|
||||
UserId: types.Int64Value(1),
|
||||
InstanceId: types.StringValue("iid"),
|
||||
ProjectId: types.StringValue("pid"),
|
||||
|
|
@ -379,6 +381,7 @@ func TestMapFields(t *testing.T) {
|
|||
state := &resourceModel{
|
||||
ProjectId: tt.expected.ProjectId,
|
||||
InstanceId: tt.expected.InstanceId,
|
||||
Region: types.StringValue(tt.region),
|
||||
}
|
||||
err := mapResourceFields(tt.input, state, tt.region)
|
||||
if !tt.isValid && err == nil {
|
||||
|
|
@ -388,7 +391,7 @@ func TestMapFields(t *testing.T) {
|
|||
t.Fatalf("Should not have failed: %v", err)
|
||||
}
|
||||
if tt.isValid {
|
||||
diff := cmp.Diff(state, &tt.expected)
|
||||
diff := cmp.Diff(&tt.expected, state)
|
||||
if diff != "" {
|
||||
t.Fatalf("Data does not match: %s", diff)
|
||||
}
|
||||
|
|
@ -476,7 +479,7 @@ func TestToCreatePayload(t *testing.T) {
|
|||
t.Fatalf("Should not have failed: %v", err)
|
||||
}
|
||||
if tt.isValid {
|
||||
diff := cmp.Diff(output, tt.expected)
|
||||
diff := cmp.Diff(tt.expected, output)
|
||||
if diff != "" {
|
||||
t.Fatalf("Data does not match: %s", diff)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource/identityschema"
|
||||
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
|
||||
"github.com/stackitcloud/stackit-sdk-go/services/postgresflex/v3alpha1api"
|
||||
|
||||
postgresflexalpha "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/user/resources_gen"
|
||||
|
|
@ -34,12 +34,7 @@ var (
|
|||
_ resource.ResourceWithConfigure = &userResource{}
|
||||
_ resource.ResourceWithImportState = &userResource{}
|
||||
_ resource.ResourceWithModifyPlan = &userResource{}
|
||||
_ resource.ResourceWithIdentity = &userResource{}
|
||||
_ resource.ResourceWithValidateConfig = &userResource{}
|
||||
|
||||
// Error message constants
|
||||
extractErrorSummary = "extracting failed"
|
||||
extractErrorMessage = "Extracting identity data: %v"
|
||||
)
|
||||
|
||||
// NewUserResource is a helper function to simplify the provider implementation.
|
||||
|
|
@ -50,14 +45,6 @@ func NewUserResource() resource.Resource {
|
|||
// resourceModel represents the Terraform resource state for a PostgreSQL Flex user.
|
||||
type resourceModel = postgresflexalpha.UserModel
|
||||
|
||||
// UserResourceIdentityModel describes the resource's identity attributes.
|
||||
type UserResourceIdentityModel struct {
|
||||
ProjectID types.String `tfsdk:"project_id"`
|
||||
Region types.String `tfsdk:"region"`
|
||||
InstanceID types.String `tfsdk:"instance_id"`
|
||||
UserID types.Int64 `tfsdk:"user_id"`
|
||||
}
|
||||
|
||||
// userResource implements the resource handling for a PostgreSQL Flex user.
|
||||
type userResource struct {
|
||||
client *v3alpha1api.APIClient
|
||||
|
|
@ -232,23 +219,14 @@ func (r *userResource) Create(
|
|||
}
|
||||
arg.userID = int64(*id)
|
||||
|
||||
model.Id = utils.BuildInternalTerraformId(arg.projectID, arg.region, arg.instanceID, strconv.FormatInt(arg.userID, 10))
|
||||
|
||||
ctx = tflog.SetField(ctx, "id", model.Id.ValueString())
|
||||
ctx = tflog.SetField(ctx, "user_id", id)
|
||||
|
||||
ctx = core.LogResponse(ctx)
|
||||
|
||||
// Set data returned by API in identity
|
||||
identity := UserResourceIdentityModel{
|
||||
ProjectID: types.StringValue(arg.projectID),
|
||||
Region: types.StringValue(arg.region),
|
||||
InstanceID: types.StringValue(arg.instanceID),
|
||||
UserID: types.Int64Value(int64(*id)),
|
||||
}
|
||||
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
model.Id = types.Int64Value(int64(*id))
|
||||
model.Id = utils.BuildInternalTerraformId(arg.projectID, arg.region, arg.instanceID, strconv.FormatInt(arg.userID, 10))
|
||||
model.UserId = types.Int64Value(int64(*id))
|
||||
model.Password = types.StringValue(userResp.GetPassword())
|
||||
model.Status = types.StringValue(userResp.GetStatus())
|
||||
|
|
@ -370,15 +348,14 @@ func (r *userResource) Read(
|
|||
|
||||
ctx = core.LogResponse(ctx)
|
||||
|
||||
// Set data returned by API in identity
|
||||
identity := UserResourceIdentityModel{
|
||||
ProjectID: types.StringValue(arg.projectID),
|
||||
Region: types.StringValue(arg.region),
|
||||
InstanceID: types.StringValue(arg.instanceID),
|
||||
UserID: types.Int64Value(arg.userID),
|
||||
}
|
||||
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
err = mapResourceFields(waitResp, &model, model.Region.ValueString())
|
||||
if err != nil {
|
||||
core.LogAndAddError(
|
||||
ctx,
|
||||
&resp.Diagnostics,
|
||||
"read user",
|
||||
fmt.Sprintf("Wait response mapping: %v", err),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -457,18 +434,6 @@ func (r *userResource) Update(
|
|||
|
||||
ctx = core.LogResponse(ctx)
|
||||
|
||||
// Set data returned by API in identity
|
||||
identity := UserResourceIdentityModel{
|
||||
ProjectID: types.StringValue(arg.projectID),
|
||||
Region: types.StringValue(arg.region),
|
||||
InstanceID: types.StringValue(arg.instanceID),
|
||||
UserID: types.Int64Value(userID64),
|
||||
}
|
||||
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
// Verify update
|
||||
waitResp, err := postgresflexalphaWait.GetUserByIdWaitHandler(
|
||||
ctx,
|
||||
|
|
@ -525,26 +490,17 @@ func (r *userResource) Delete(
|
|||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
// Read identity data
|
||||
var identityData UserResourceIdentityModel
|
||||
resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
ctx = core.InitProviderContext(ctx)
|
||||
|
||||
arg, errExt := r.extractIdentityData(model, identityData)
|
||||
if errExt != nil {
|
||||
core.LogAndAddError(
|
||||
ctx,
|
||||
&resp.Diagnostics,
|
||||
extractErrorSummary,
|
||||
fmt.Sprintf(extractErrorMessage, errExt),
|
||||
)
|
||||
arg := clientArg{
|
||||
projectID: model.ProjectId.ValueString(),
|
||||
instanceID: model.InstanceId.ValueString(),
|
||||
region: model.Region.ValueString(),
|
||||
userID: model.UserId.ValueInt64(),
|
||||
}
|
||||
|
||||
ctx = r.setTFLogFields(ctx, arg)
|
||||
ctx = r.setTFLogFields(ctx, &arg)
|
||||
ctx = core.InitProviderContext(ctx)
|
||||
|
||||
userID64 := arg.userID
|
||||
|
|
@ -557,7 +513,14 @@ func (r *userResource) Delete(
|
|||
// Delete existing record set
|
||||
err := r.client.DefaultAPI.DeleteUserRequest(ctx, arg.projectID, arg.region, arg.instanceID, userID).Execute()
|
||||
if err != nil {
|
||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting user", fmt.Sprintf("Calling API: %v", err))
|
||||
oapiErr, ok := err.(*oapierror.GenericOpenAPIError) // nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped
|
||||
if ok {
|
||||
if oapiErr.StatusCode == 404 {
|
||||
resp.State.RemoveResource(ctx)
|
||||
return
|
||||
}
|
||||
}
|
||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting user", fmt.Sprintf("error from API: %v", err))
|
||||
}
|
||||
|
||||
ctx = core.LogResponse(ctx)
|
||||
|
|
@ -581,30 +544,6 @@ func (r *userResource) Delete(
|
|||
tflog.Info(ctx, "Postgres Flex user deleted")
|
||||
}
|
||||
|
||||
// IdentitySchema defines the fields that are required to uniquely identify a resource.
|
||||
func (r *userResource) IdentitySchema(
|
||||
_ context.Context,
|
||||
_ resource.IdentitySchemaRequest,
|
||||
response *resource.IdentitySchemaResponse,
|
||||
) {
|
||||
response.IdentitySchema = identityschema.Schema{
|
||||
Attributes: map[string]identityschema.Attribute{
|
||||
"project_id": identityschema.StringAttribute{
|
||||
RequiredForImport: true,
|
||||
},
|
||||
"region": identityschema.StringAttribute{
|
||||
RequiredForImport: true,
|
||||
},
|
||||
"instance_id": identityschema.StringAttribute{
|
||||
RequiredForImport: true,
|
||||
},
|
||||
"user_id": identityschema.Int64Attribute{
|
||||
RequiredForImport: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// clientArg holds the arguments for API calls.
|
||||
type clientArg struct {
|
||||
projectID string
|
||||
|
|
@ -622,112 +561,41 @@ func (r *userResource) ImportState(
|
|||
) {
|
||||
ctx = core.InitProviderContext(ctx)
|
||||
|
||||
if req.ID != "" {
|
||||
idParts := strings.Split(req.ID, core.Separator)
|
||||
|
||||
if len(idParts) != 4 || idParts[0] == "" || idParts[1] == "" || idParts[2] == "" || idParts[3] == "" {
|
||||
core.LogAndAddError(
|
||||
ctx, &resp.Diagnostics,
|
||||
"Error importing user",
|
||||
fmt.Sprintf(
|
||||
"Expected import identifier with format [project_id],[region],[instance_id],[user_id], got %q",
|
||||
req.ID,
|
||||
),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
userID, err := strconv.ParseInt(idParts[3], 10, 64)
|
||||
if err != nil {
|
||||
core.LogAndAddError(
|
||||
ctx,
|
||||
&resp.Diagnostics,
|
||||
"Error importing user",
|
||||
fmt.Sprintf("Invalid user_id format: %q. It must be a valid integer.", idParts[3]),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), idParts[0])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), idParts[1])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), idParts[2])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("user_id"), userID)...)
|
||||
|
||||
tflog.Info(ctx, "Postgres Flex user state imported")
|
||||
idParts := strings.Split(req.ID, core.Separator)
|
||||
|
||||
if len(idParts) != 4 || idParts[0] == "" || idParts[1] == "" || idParts[2] == "" || idParts[3] == "" {
|
||||
core.LogAndAddError(
|
||||
ctx, &resp.Diagnostics,
|
||||
"Error importing user",
|
||||
fmt.Sprintf(
|
||||
"Expected import identifier with format [project_id],[region],[instance_id],[user_id], got %q",
|
||||
req.ID,
|
||||
),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// If no ID is provided, attempt to read identity attributes from the import configuration
|
||||
var identityData UserResourceIdentityModel
|
||||
resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
userID, err := strconv.ParseInt(idParts[3], 10, 64)
|
||||
if err != nil {
|
||||
core.LogAndAddError(
|
||||
ctx,
|
||||
&resp.Diagnostics,
|
||||
"Error importing user",
|
||||
fmt.Sprintf("Invalid user_id format: %q. It must be a valid integer.", idParts[3]),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
projectID := identityData.ProjectID.ValueString()
|
||||
region := identityData.Region.ValueString()
|
||||
instanceID := identityData.InstanceID.ValueString()
|
||||
userID := identityData.UserID.ValueInt64()
|
||||
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), projectID)...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), region)...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), instanceID)...)
|
||||
idString := utils.BuildInternalTerraformId(idParts...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("id"), idString)...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), idParts[0])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), idParts[1])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), idParts[2])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("user_id"), userID)...)
|
||||
|
||||
tflog.Info(ctx, "Postgres Flex user state imported")
|
||||
}
|
||||
|
||||
// extractIdentityData extracts essential identifiers from the resource model, falling back to the identity model.
|
||||
func (r *userResource) extractIdentityData(
|
||||
model resourceModel,
|
||||
identity UserResourceIdentityModel,
|
||||
) (*clientArg, error) {
|
||||
var projectID, region, instanceID string
|
||||
var userID int64
|
||||
if !model.UserId.IsNull() && !model.UserId.IsUnknown() {
|
||||
userID = model.UserId.ValueInt64()
|
||||
} else {
|
||||
if identity.UserID.IsNull() || identity.UserID.IsUnknown() {
|
||||
return nil, fmt.Errorf("user_id not found in config")
|
||||
}
|
||||
userID = identity.UserID.ValueInt64()
|
||||
}
|
||||
|
||||
if !model.ProjectId.IsNull() && !model.ProjectId.IsUnknown() {
|
||||
projectID = model.ProjectId.ValueString()
|
||||
} else {
|
||||
if identity.ProjectID.IsNull() || identity.ProjectID.IsUnknown() {
|
||||
return nil, fmt.Errorf("project_id not found in config")
|
||||
}
|
||||
projectID = identity.ProjectID.ValueString()
|
||||
}
|
||||
|
||||
if !model.Region.IsNull() && !model.Region.IsUnknown() {
|
||||
region = r.providerData.GetRegionWithOverride(model.Region)
|
||||
} else {
|
||||
if identity.Region.IsNull() || identity.Region.IsUnknown() {
|
||||
return nil, fmt.Errorf("region not found in config")
|
||||
}
|
||||
region = r.providerData.GetRegionWithOverride(identity.Region)
|
||||
}
|
||||
|
||||
if !model.InstanceId.IsNull() && !model.InstanceId.IsUnknown() {
|
||||
instanceID = model.InstanceId.ValueString()
|
||||
} else {
|
||||
if identity.InstanceID.IsNull() || identity.InstanceID.IsUnknown() {
|
||||
return nil, fmt.Errorf("instance_id not found in config")
|
||||
}
|
||||
instanceID = identity.InstanceID.ValueString()
|
||||
}
|
||||
return &clientArg{
|
||||
projectID: projectID,
|
||||
instanceID: instanceID,
|
||||
region: region,
|
||||
userID: userID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// setTFLogFields adds relevant fields to the context for terraform logging purposes.
|
||||
func (r *userResource) setTFLogFields(ctx context.Context, arg *clientArg) context.Context {
|
||||
ctx = tflog.SetField(ctx, "project_id", arg.projectID)
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import (
|
|||
func UserResourceSchema(ctx context.Context) schema.Schema {
|
||||
return schema.Schema{
|
||||
Attributes: map[string]schema.Attribute{
|
||||
"id": schema.Int64Attribute{
|
||||
"id": schema.StringAttribute{
|
||||
Computed: true,
|
||||
Description: "The ID of the user.",
|
||||
MarkdownDescription: "The ID of the user.",
|
||||
|
|
@ -75,7 +75,7 @@ func UserResourceSchema(ctx context.Context) schema.Schema {
|
|||
}
|
||||
|
||||
type UserModel struct {
|
||||
Id types.Int64 `tfsdk:"id"`
|
||||
Id types.String `tfsdk:"id"`
|
||||
InstanceId types.String `tfsdk:"instance_id"`
|
||||
Name types.String `tfsdk:"name"`
|
||||
Password types.String `tfsdk:"password"`
|
||||
|
|
|
|||
|
|
@ -198,10 +198,10 @@ func TestAccInstanceNoEncryption(t *testing.T) {
|
|||
Roles: []string{
|
||||
"##STACKIT_DatabaseManager##",
|
||||
"##STACKIT_LoginManager##",
|
||||
//"##STACKIT_ProcessManager##",
|
||||
//"##STACKIT_SQLAgentManager##",
|
||||
//"##STACKIT_SQLAgentUser##",
|
||||
//"##STACKIT_ServerManager##",
|
||||
// "##STACKIT_ProcessManager##",
|
||||
// "##STACKIT_SQLAgentManager##",
|
||||
// "##STACKIT_SQLAgentUser##",
|
||||
// "##STACKIT_ServerManager##",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ import (
|
|||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
|
||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
||||
|
||||
"github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex/v3beta1api"
|
||||
|
||||
sqlserverflexbetaDataGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/instance/datasources_gen"
|
||||
|
|
@ -27,7 +29,7 @@ func mapResponseToModel(
|
|||
m.Edition = types.StringValue(string(resp.GetEdition()))
|
||||
m.Encryption = handleEncryption(ctx, m, resp)
|
||||
m.FlavorId = types.StringValue(resp.GetFlavorId())
|
||||
m.Id = types.StringValue(resp.GetId())
|
||||
m.Id = utils.BuildInternalTerraformId(m.ProjectId.ValueString(), m.Region.ValueString(), resp.GetId())
|
||||
m.InstanceId = types.StringValue(resp.GetId())
|
||||
m.IsDeletable = types.BoolValue(resp.GetIsDeletable())
|
||||
m.Name = types.StringValue(resp.GetName())
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import (
|
|||
|
||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
"github.com/hashicorp/terraform-plugin-framework/resource/identityschema"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"github.com/hashicorp/terraform-plugin-log/tflog"
|
||||
"github.com/stackitcloud/stackit-sdk-go/core/config"
|
||||
|
|
@ -32,7 +31,6 @@ var (
|
|||
_ resource.ResourceWithConfigure = &instanceResource{}
|
||||
_ resource.ResourceWithImportState = &instanceResource{}
|
||||
_ resource.ResourceWithModifyPlan = &instanceResource{}
|
||||
_ resource.ResourceWithIdentity = &instanceResource{}
|
||||
)
|
||||
|
||||
func NewInstanceResource() resource.Resource {
|
||||
|
|
@ -47,12 +45,6 @@ type instanceResource struct {
|
|||
// resourceModel describes the resource data model.
|
||||
type resourceModel = sqlserverflexbetaResGen.InstanceModel
|
||||
|
||||
type InstanceResourceIdentityModel struct {
|
||||
ProjectID types.String `tfsdk:"project_id"`
|
||||
Region types.String `tfsdk:"region"`
|
||||
InstanceID types.String `tfsdk:"instance_id"`
|
||||
}
|
||||
|
||||
func (r *instanceResource) Metadata(
|
||||
_ context.Context,
|
||||
req resource.MetadataRequest,
|
||||
|
|
@ -81,26 +73,6 @@ func (r *instanceResource) Schema(ctx context.Context, _ resource.SchemaRequest,
|
|||
resp.Schema = s
|
||||
}
|
||||
|
||||
func (r *instanceResource) IdentitySchema(
|
||||
_ context.Context,
|
||||
_ resource.IdentitySchemaRequest,
|
||||
resp *resource.IdentitySchemaResponse,
|
||||
) {
|
||||
resp.IdentitySchema = identityschema.Schema{
|
||||
Attributes: map[string]identityschema.Attribute{
|
||||
"project_id": identityschema.StringAttribute{
|
||||
RequiredForImport: true, // must be set during import by the practitioner
|
||||
},
|
||||
"region": identityschema.StringAttribute{
|
||||
RequiredForImport: true, // can be defaulted by the provider configuration
|
||||
},
|
||||
"instance_id": identityschema.StringAttribute{
|
||||
RequiredForImport: true, // can be defaulted by the provider configuration
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Configure adds the provider configured client to the resource.
|
||||
func (r *instanceResource) Configure(
|
||||
ctx context.Context,
|
||||
|
|
@ -190,9 +162,9 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques
|
|||
|
||||
ctx = core.InitProviderContext(ctx)
|
||||
|
||||
projectId := data.ProjectId.ValueString()
|
||||
projectID := data.ProjectId.ValueString()
|
||||
region := data.Region.ValueString()
|
||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||
ctx = tflog.SetField(ctx, "project_id", projectID)
|
||||
ctx = tflog.SetField(ctx, "region", region)
|
||||
|
||||
// Generate API request body from model
|
||||
|
|
@ -210,7 +182,7 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques
|
|||
// Create new Instance
|
||||
createResp, err := r.client.DefaultAPI.CreateInstanceRequest(
|
||||
ctx,
|
||||
projectId,
|
||||
projectID,
|
||||
region,
|
||||
).CreateInstanceRequestPayload(*payload).Execute()
|
||||
if err != nil {
|
||||
|
|
@ -220,24 +192,25 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques
|
|||
|
||||
ctx = core.LogResponse(ctx)
|
||||
|
||||
instanceId := createResp.Id
|
||||
data.InstanceId = types.StringValue(instanceId)
|
||||
instanceID := createResp.Id
|
||||
data.InstanceId = types.StringValue(instanceID)
|
||||
data.Id = utils.BuildInternalTerraformId(projectID, region, instanceID)
|
||||
|
||||
identity := InstanceResourceIdentityModel{
|
||||
ProjectID: types.StringValue(projectId),
|
||||
Region: types.StringValue(region),
|
||||
InstanceID: types.StringValue(instanceId),
|
||||
}
|
||||
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
// Set data returned by API in id
|
||||
resp.Diagnostics.Append(
|
||||
resp.State.SetAttribute(
|
||||
ctx,
|
||||
path.Root("id"),
|
||||
utils.BuildInternalTerraformId(projectID, region, instanceID),
|
||||
)...,
|
||||
)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), instanceID)...)
|
||||
|
||||
waitResp, err := wait.CreateInstanceWaitHandler(
|
||||
ctx,
|
||||
r.client.DefaultAPI,
|
||||
projectId,
|
||||
instanceId,
|
||||
projectID,
|
||||
instanceID,
|
||||
region,
|
||||
).SetSleepBeforeWait(
|
||||
10 * time.Second,
|
||||
|
|
@ -293,15 +266,15 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r
|
|||
|
||||
ctx = core.InitProviderContext(ctx)
|
||||
|
||||
projectId := data.ProjectId.ValueString()
|
||||
projectID := data.ProjectId.ValueString()
|
||||
region := data.Region.ValueString()
|
||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||
ctx = tflog.SetField(ctx, "project_id", projectID)
|
||||
ctx = tflog.SetField(ctx, "region", region)
|
||||
|
||||
instanceId := data.InstanceId.ValueString()
|
||||
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
||||
instanceID := data.InstanceId.ValueString()
|
||||
ctx = tflog.SetField(ctx, "instance_id", instanceID)
|
||||
|
||||
instanceResp, err := r.client.DefaultAPI.GetInstanceRequest(ctx, projectId, region, instanceId).Execute()
|
||||
instanceResp, err := r.client.DefaultAPI.GetInstanceRequest(ctx, projectID, region, instanceID).Execute()
|
||||
if err != nil {
|
||||
oapiErr, ok := err.(*oapierror.GenericOpenAPIError) //nolint:errorlint //complaining that error.As should be used to catch wrapped errors, but this error should not be wrapped
|
||||
if ok && oapiErr.StatusCode == http.StatusNotFound {
|
||||
|
|
@ -326,17 +299,6 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r
|
|||
return
|
||||
}
|
||||
|
||||
// Save identity into Terraform state
|
||||
identity := InstanceResourceIdentityModel{
|
||||
ProjectID: types.StringValue(projectId),
|
||||
Region: types.StringValue(region),
|
||||
InstanceID: types.StringValue(instanceId),
|
||||
}
|
||||
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
// Save updated data into Terraform state
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
|
|
@ -357,13 +319,13 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques
|
|||
|
||||
ctx = core.InitProviderContext(ctx)
|
||||
|
||||
projectId := data.ProjectId.ValueString()
|
||||
projectID := data.ProjectId.ValueString()
|
||||
region := data.Region.ValueString()
|
||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||
ctx = tflog.SetField(ctx, "project_id", projectID)
|
||||
ctx = tflog.SetField(ctx, "region", region)
|
||||
|
||||
instanceId := data.InstanceId.ValueString()
|
||||
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
||||
instanceID := data.InstanceId.ValueString()
|
||||
ctx = tflog.SetField(ctx, "instance_id", instanceID)
|
||||
|
||||
// Generate API request body from model
|
||||
payload, err := toUpdatePayload(ctx, &data, resp)
|
||||
|
|
@ -379,9 +341,9 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques
|
|||
// Update existing instance
|
||||
err = r.client.DefaultAPI.UpdateInstanceRequest(
|
||||
ctx,
|
||||
projectId,
|
||||
projectID,
|
||||
region,
|
||||
instanceId,
|
||||
instanceID,
|
||||
).UpdateInstanceRequestPayload(*payload).Execute()
|
||||
if err != nil {
|
||||
core.LogAndAddError(ctx, &resp.Diagnostics, updateInstanceError, err.Error())
|
||||
|
|
@ -391,7 +353,7 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques
|
|||
ctx = core.LogResponse(ctx)
|
||||
|
||||
waitResp, err := wait.
|
||||
UpdateInstanceWaitHandler(ctx, r.client.DefaultAPI, projectId, instanceId, region).
|
||||
UpdateInstanceWaitHandler(ctx, r.client.DefaultAPI, projectID, instanceID, region).
|
||||
SetSleepBeforeWait(15 * time.Second).
|
||||
SetTimeout(45 * time.Minute).
|
||||
WaitWithContext(ctx)
|
||||
|
|
@ -417,16 +379,6 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques
|
|||
return
|
||||
}
|
||||
|
||||
identity := InstanceResourceIdentityModel{
|
||||
ProjectID: types.StringValue(projectId),
|
||||
Region: types.StringValue(region),
|
||||
InstanceID: types.StringValue(instanceId),
|
||||
}
|
||||
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
// Save updated data into Terraform state
|
||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
|
|
@ -445,25 +397,18 @@ func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteReques
|
|||
return
|
||||
}
|
||||
|
||||
// Read identity data
|
||||
var identityData InstanceResourceIdentityModel
|
||||
resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
ctx = core.InitProviderContext(ctx)
|
||||
|
||||
projectId := identityData.ProjectID.ValueString()
|
||||
region := identityData.Region.ValueString()
|
||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||
projectID := data.ProjectId.ValueString()
|
||||
region := data.Region.ValueString()
|
||||
ctx = tflog.SetField(ctx, "project_id", projectID)
|
||||
ctx = tflog.SetField(ctx, "region", region)
|
||||
|
||||
instanceId := identityData.InstanceID.ValueString()
|
||||
ctx = tflog.SetField(ctx, "instance_id", instanceId)
|
||||
instanceID := data.InstanceId.ValueString()
|
||||
ctx = tflog.SetField(ctx, "instance_id", instanceID)
|
||||
|
||||
// Delete existing instance
|
||||
err := r.client.DefaultAPI.DeleteInstanceRequest(ctx, projectId, region, instanceId).Execute()
|
||||
err := r.client.DefaultAPI.DeleteInstanceRequest(ctx, projectID, region, instanceID).Execute()
|
||||
if err != nil {
|
||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting instance", fmt.Sprintf("Calling API: %v", err))
|
||||
return
|
||||
|
|
@ -471,7 +416,7 @@ func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteReques
|
|||
|
||||
ctx = core.LogResponse(ctx)
|
||||
|
||||
delResp, err := wait.DeleteInstanceWaitHandler(ctx, r.client.DefaultAPI, projectId, instanceId, region).WaitWithContext(ctx)
|
||||
delResp, err := wait.DeleteInstanceWaitHandler(ctx, r.client.DefaultAPI, projectID, instanceID, region).WaitWithContext(ctx)
|
||||
if err != nil {
|
||||
core.LogAndAddError(
|
||||
ctx,
|
||||
|
|
@ -506,41 +451,24 @@ func (r *instanceResource) ImportState(
|
|||
) {
|
||||
ctx = core.InitProviderContext(ctx)
|
||||
|
||||
if req.ID != "" {
|
||||
idParts := strings.Split(req.ID, core.Separator)
|
||||
idParts := strings.Split(req.ID, core.Separator)
|
||||
|
||||
if len(idParts) != 3 || idParts[0] == "" || idParts[1] == "" || idParts[2] == "" {
|
||||
core.LogAndAddError(
|
||||
ctx, &resp.Diagnostics,
|
||||
"Error importing instance",
|
||||
fmt.Sprintf(
|
||||
"Expected import identifier with format [project_id],[region],[instance_id] Got: %q",
|
||||
req.ID,
|
||||
),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), idParts[0])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), idParts[1])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), idParts[2])...)
|
||||
if len(idParts) != 3 || idParts[0] == "" || idParts[1] == "" || idParts[2] == "" {
|
||||
core.LogAndAddError(
|
||||
ctx, &resp.Diagnostics,
|
||||
"Error importing instance",
|
||||
fmt.Sprintf(
|
||||
"Expected import identifier with format [project_id],[region],[instance_id] Got: %q",
|
||||
req.ID,
|
||||
),
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
// If no ID is provided, attempt to read identity attributes from the import configuration
|
||||
var identityData InstanceResourceIdentityModel
|
||||
resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...)
|
||||
if resp.Diagnostics.HasError() {
|
||||
return
|
||||
}
|
||||
|
||||
projectId := identityData.ProjectID.ValueString()
|
||||
region := identityData.Region.ValueString()
|
||||
instanceId := identityData.InstanceID.ValueString()
|
||||
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), projectId)...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), region)...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), instanceId)...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("id"), utils.BuildInternalTerraformId(idParts...).ValueString())...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("project_id"), idParts[0])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("region"), idParts[1])...)
|
||||
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("instance_id"), idParts[2])...)
|
||||
|
||||
tflog.Info(ctx, "Sqlserverflexbeta instance state imported")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,13 +3,32 @@ package sqlserverflexbeta_test
|
|||
import (
|
||||
"context"
|
||||
_ "embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-testing/compare"
|
||||
"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
|
||||
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
|
||||
"github.com/hashicorp/terraform-plugin-testing/knownvalue"
|
||||
"github.com/hashicorp/terraform-plugin-testing/plancheck"
|
||||
"github.com/hashicorp/terraform-plugin-testing/statecheck"
|
||||
"github.com/hashicorp/terraform-plugin-testing/terraform"
|
||||
"github.com/hashicorp/terraform-plugin-testing/tfjsonpath"
|
||||
"github.com/stackitcloud/stackit-sdk-go/core/config"
|
||||
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
|
||||
"github.com/stackitcloud/stackit-sdk-go/core/utils"
|
||||
|
||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||
wait "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/wait/sqlserverflexbeta"
|
||||
|
||||
"github.com/stackitcloud/stackit-sdk-go/services/sqlserverflex/v3beta1api"
|
||||
|
||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/internal/testutils"
|
||||
sqlserverflexbeta "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/instance"
|
||||
|
|
@ -20,7 +39,7 @@ import (
|
|||
fwresource "github.com/hashicorp/terraform-plugin-framework/resource"
|
||||
)
|
||||
|
||||
const providerPrefix = "stackitprivatepreview_sqlserverflexbeta"
|
||||
const pfx = "stackitprivatepreview_sqlserverflexbeta"
|
||||
|
||||
func TestInstanceResourceSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
|
@ -59,20 +78,20 @@ func testAccPreCheck(t *testing.T) {
|
|||
|
||||
type resData struct {
|
||||
ServiceAccountFilePath string
|
||||
ProjectId string
|
||||
ProjectID string
|
||||
Region string
|
||||
Name string
|
||||
TfName string
|
||||
FlavorId string
|
||||
FlavorID string
|
||||
BackupSchedule string
|
||||
UseEncryption bool
|
||||
KekKeyId string
|
||||
KekKeyRingId string
|
||||
KekKeyID string
|
||||
KekKeyRingID string
|
||||
KekKeyVersion uint8
|
||||
KekServiceAccount string
|
||||
PerformanceClass string
|
||||
Size uint32
|
||||
AclString string
|
||||
ACLStrings []string
|
||||
AccessScope string
|
||||
RetentionDays uint32
|
||||
Version string
|
||||
|
|
@ -82,37 +101,33 @@ type resData struct {
|
|||
|
||||
type User struct {
|
||||
Name string
|
||||
ProjectId string
|
||||
ProjectID string
|
||||
Roles []string
|
||||
}
|
||||
|
||||
type Database struct {
|
||||
Name string
|
||||
ProjectId string
|
||||
ProjectID string
|
||||
Owner string
|
||||
Collation string
|
||||
Compatibility string
|
||||
}
|
||||
|
||||
func resName(res, name string) string {
|
||||
return fmt.Sprintf("%s_%s.%s", providerPrefix, res, name)
|
||||
}
|
||||
|
||||
func getExample() resData {
|
||||
name := acctest.RandomWithPrefix("tf-acc")
|
||||
return resData{
|
||||
Region: os.Getenv("TF_ACC_REGION"),
|
||||
ServiceAccountFilePath: os.Getenv("TF_ACC_SERVICE_ACCOUNT_FILE"),
|
||||
ProjectId: os.Getenv("TF_ACC_PROJECT_ID"),
|
||||
ProjectID: os.Getenv("TF_ACC_PROJECT_ID"),
|
||||
Name: name,
|
||||
TfName: name,
|
||||
FlavorId: "4.16-Single",
|
||||
FlavorID: "4.16-Single",
|
||||
BackupSchedule: "0 0 * * *",
|
||||
UseEncryption: false,
|
||||
RetentionDays: 33,
|
||||
PerformanceClass: "premium-perf2-stackit",
|
||||
Size: 10,
|
||||
AclString: "0.0.0.0/0",
|
||||
ACLStrings: []string{"0.0.0.0/0"},
|
||||
AccessScope: "PUBLIC",
|
||||
Version: "2022",
|
||||
}
|
||||
|
|
@ -127,118 +142,160 @@ func TestAccInstance(t *testing.T) {
|
|||
updSizeData := exData
|
||||
updSizeData.Size = 25
|
||||
|
||||
testInstanceID := testutils.ResStr(pfx, "instance", exData.TfName)
|
||||
|
||||
compareValuesSame := statecheck.CompareValue(compare.ValuesSame())
|
||||
resource.ParallelTest(t, resource.TestCase{
|
||||
PreCheck: func() {
|
||||
testAccPreCheck(t)
|
||||
t.Logf(" ... working on instance %s", exData.TfName)
|
||||
t.Logf(" ... %s - %s", t.Name(), exData.TfName)
|
||||
},
|
||||
CheckDestroy: testAccCheckSQLServerFlexDestroy,
|
||||
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
|
||||
Steps: []resource.TestStep{
|
||||
// Create and verify
|
||||
{
|
||||
PreConfig: func() {
|
||||
t.Logf("testing: %s - %s", t.Name(), "create and verify")
|
||||
},
|
||||
ExpectNonEmptyPlan: true,
|
||||
Config: testutils.StringFromTemplateMust(
|
||||
"testdata/instance_template.gompl",
|
||||
exData,
|
||||
),
|
||||
Check: resource.ComposeAggregateTestCheckFunc(
|
||||
resource.TestCheckResourceAttr(resName("instance", exData.TfName), "name", exData.Name),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", exData.TfName), "id"),
|
||||
// TODO: check all fields
|
||||
),
|
||||
ConfigStateChecks: []statecheck.StateCheck{
|
||||
compareValuesSame.AddStateValue(
|
||||
testInstanceID,
|
||||
tfjsonpath.New("id"),
|
||||
),
|
||||
statecheck.ExpectKnownValue(
|
||||
testInstanceID,
|
||||
tfjsonpath.New("is_deletable"),
|
||||
knownvalue.Bool(true),
|
||||
),
|
||||
},
|
||||
Check: defaultNoEncInstanceTestChecks(testInstanceID, exData),
|
||||
},
|
||||
// Update name and verify
|
||||
{
|
||||
PreConfig: func() {
|
||||
t.Logf("testing: %s - %s", t.Name(), "update name and verify")
|
||||
},
|
||||
ExpectNonEmptyPlan: true,
|
||||
Config: testutils.StringFromTemplateMust(
|
||||
"testdata/instance_template.gompl",
|
||||
updNameData,
|
||||
),
|
||||
ConfigPlanChecks: resource.ConfigPlanChecks{
|
||||
PreApply: []plancheck.PlanCheck{
|
||||
plancheck.ExpectNonEmptyPlan(),
|
||||
},
|
||||
},
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttr(resName("instance", exData.TfName), "name", updNameData.Name),
|
||||
defaultNoEncInstanceTestChecks(testInstanceID, updNameData),
|
||||
),
|
||||
},
|
||||
// Update size and verify
|
||||
{
|
||||
PreConfig: func() {
|
||||
t.Logf("testing: %s - %s", t.Name(), "update storage.size and verify")
|
||||
},
|
||||
ExpectNonEmptyPlan: true,
|
||||
Config: testutils.StringFromTemplateMust(
|
||||
"testdata/instance_template.gompl",
|
||||
updSizeData,
|
||||
),
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
resource.TestCheckResourceAttr(
|
||||
testutils.ResStr(providerPrefix, "instance", exData.TfName),
|
||||
"storage.size",
|
||||
strconv.Itoa(int(updSizeData.Size)),
|
||||
),
|
||||
defaultNoEncInstanceTestChecks(testInstanceID, updSizeData),
|
||||
),
|
||||
},
|
||||
// Import test
|
||||
// test instance imports
|
||||
{
|
||||
RefreshState: true,
|
||||
PreConfig: func() {
|
||||
t.Logf("testing: %s - %s", t.Name(), "import instance")
|
||||
},
|
||||
ResourceName: testInstanceID,
|
||||
// ImportStateIdPrefix: "",
|
||||
// ImportStateVerifyIdentifierAttribute: "id",
|
||||
ImportStateIdFunc: getInstanceTestID(exData.TfName),
|
||||
ImportStateKind: resource.ImportCommandWithID,
|
||||
ImportState: true,
|
||||
ImportStateVerify: true,
|
||||
},
|
||||
//// Import test
|
||||
//{
|
||||
// ResourceName: resName("instance", exData.TfName),
|
||||
// ImportState: true,
|
||||
// ImportStateVerify: true,
|
||||
// },
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func TestAccInstanceReApply(t *testing.T) {
|
||||
exData := getExample()
|
||||
testInstanceID := testutils.ResStr(pfx, "instance", exData.TfName)
|
||||
compareValuesSame := statecheck.CompareValue(compare.ValuesSame())
|
||||
resource.ParallelTest(t, resource.TestCase{
|
||||
PreCheck: func() {
|
||||
testAccPreCheck(t)
|
||||
t.Logf(" ... working on instance %s", exData.TfName)
|
||||
t.Logf(" ... %s - %s", t.Name(), exData.TfName)
|
||||
},
|
||||
CheckDestroy: testAccCheckSQLServerFlexDestroy,
|
||||
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
|
||||
Steps: []resource.TestStep{
|
||||
// Create and verify
|
||||
{
|
||||
PreConfig: func() {
|
||||
t.Logf("testing: %s - %s", t.Name(), "create and verify")
|
||||
},
|
||||
Config: testutils.StringFromTemplateMust(
|
||||
"testdata/instance_template.gompl",
|
||||
exData,
|
||||
),
|
||||
Check: resource.ComposeAggregateTestCheckFunc(
|
||||
resource.TestCheckResourceAttr(resName("instance", exData.TfName), "name", exData.Name),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", exData.TfName), "id"),
|
||||
// TODO: check all fields
|
||||
),
|
||||
ConfigStateChecks: []statecheck.StateCheck{
|
||||
compareValuesSame.AddStateValue(
|
||||
testInstanceID,
|
||||
tfjsonpath.New("id"),
|
||||
),
|
||||
statecheck.ExpectKnownValue(
|
||||
testInstanceID,
|
||||
tfjsonpath.New("is_deletable"),
|
||||
knownvalue.Bool(true),
|
||||
),
|
||||
},
|
||||
Check: defaultNoEncInstanceTestChecks(testInstanceID, exData),
|
||||
},
|
||||
// Create and verify
|
||||
// Second apply should not have changes
|
||||
{
|
||||
PreConfig: func() {
|
||||
t.Logf("testing: %s - %s", t.Name(), "second apply")
|
||||
},
|
||||
ExpectNonEmptyPlan: false,
|
||||
ResourceName: testInstanceID,
|
||||
Config: testutils.StringFromTemplateMust(
|
||||
"testdata/instance_template.gompl",
|
||||
exData,
|
||||
),
|
||||
Check: resource.ComposeAggregateTestCheckFunc(
|
||||
resource.TestCheckResourceAttr(resName("instance", exData.TfName), "name", exData.Name),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", exData.TfName), "id"),
|
||||
// TODO: check all fields
|
||||
),
|
||||
ConfigPlanChecks: resource.ConfigPlanChecks{
|
||||
PreApply: []plancheck.PlanCheck{
|
||||
plancheck.ExpectEmptyPlan(),
|
||||
},
|
||||
},
|
||||
ConfigStateChecks: []statecheck.StateCheck{
|
||||
compareValuesSame.AddStateValue(
|
||||
testInstanceID,
|
||||
tfjsonpath.New("id"),
|
||||
),
|
||||
statecheck.ExpectKnownValue(
|
||||
testInstanceID,
|
||||
tfjsonpath.New("is_deletable"),
|
||||
knownvalue.Bool(true),
|
||||
),
|
||||
},
|
||||
},
|
||||
// Refresh state test
|
||||
{
|
||||
PreConfig: func() {
|
||||
t.Logf("testing: %s - %s", t.Name(), "refresh state")
|
||||
},
|
||||
RefreshState: true,
|
||||
},
|
||||
// Create and verify
|
||||
{
|
||||
Config: testutils.StringFromTemplateMust(
|
||||
"testdata/instance_template.gompl",
|
||||
exData,
|
||||
),
|
||||
Check: resource.ComposeAggregateTestCheckFunc(
|
||||
resource.TestCheckResourceAttr(resName("instance", exData.TfName), "name", exData.Name),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", exData.TfName), "id"),
|
||||
// TODO: check all fields
|
||||
),
|
||||
},
|
||||
// Import test
|
||||
{
|
||||
ResourceName: resName("instance", exData.TfName),
|
||||
ImportStateKind: resource.ImportBlockWithResourceIdentity,
|
||||
ImportState: true,
|
||||
// ImportStateVerify is not supported with plannable import blocks
|
||||
// ImportStateVerify: true,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
|
@ -251,7 +308,7 @@ func TestAccInstanceNoEncryption(t *testing.T) {
|
|||
data.Users = []User{
|
||||
{
|
||||
Name: userName,
|
||||
ProjectId: os.Getenv("TF_ACC_PROJECT_ID"),
|
||||
ProjectID: os.Getenv("TF_ACC_PROJECT_ID"),
|
||||
Roles: []string{
|
||||
"##STACKIT_DatabaseManager##",
|
||||
"##STACKIT_LoginManager##",
|
||||
|
|
@ -265,16 +322,19 @@ func TestAccInstanceNoEncryption(t *testing.T) {
|
|||
data.Databases = []Database{
|
||||
{
|
||||
Name: dbName,
|
||||
ProjectId: os.Getenv("TF_ACC_PROJECT_ID"),
|
||||
ProjectID: os.Getenv("TF_ACC_PROJECT_ID"),
|
||||
Owner: userName,
|
||||
},
|
||||
}
|
||||
|
||||
testInstanceID := testutils.ResStr(pfx, "instance", data.TfName)
|
||||
testDatabaseID := testutils.ResStr(pfx, "database", dbName)
|
||||
testUserID := testutils.ResStr(pfx, "user", userName)
|
||||
resource.ParallelTest(t, resource.TestCase{
|
||||
PreCheck: func() {
|
||||
testAccPreCheck(t)
|
||||
t.Logf(" ... working on instance %s", data.TfName)
|
||||
t.Logf(" ... %s - %s", t.Name(), data.TfName)
|
||||
},
|
||||
CheckDestroy: testAccCheckSQLServerFlexDestroy,
|
||||
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
|
||||
Steps: []resource.TestStep{
|
||||
// Create and verify
|
||||
|
|
@ -284,62 +344,22 @@ func TestAccInstanceNoEncryption(t *testing.T) {
|
|||
data,
|
||||
),
|
||||
Check: resource.ComposeAggregateTestCheckFunc(
|
||||
// check instance values are set
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "id"),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "backup_schedule"),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "edition"),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "flavor_id"),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "instance_id"),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "is_deletable"),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "name"),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "replicas"),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "retention_days"),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "status"),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "version"),
|
||||
|
||||
resource.TestCheckNoResourceAttr(resName("instance", data.TfName), "encryption"),
|
||||
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption"),
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_id"),
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_version"),
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"),
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"),
|
||||
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.access_scope"),
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.acl"),
|
||||
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.instance_address"),
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.router_address"),
|
||||
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "storage.class"),
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "storage.size"),
|
||||
|
||||
// check instance values are correct
|
||||
resource.TestCheckResourceAttr(resName("instance", data.TfName), "name", data.Name),
|
||||
|
||||
// check user values are set
|
||||
resource.TestCheckResourceAttrSet(resName("user", userName), "id"),
|
||||
resource.TestCheckResourceAttrSet(resName("user", userName), "username"),
|
||||
// resource.TestCheckResourceAttrSet(resName("user", userName), "roles"),
|
||||
|
||||
// func(s *terraform.State) error {
|
||||
// return nil
|
||||
// },
|
||||
defaultNoEncInstanceTestChecks(testInstanceID, data),
|
||||
|
||||
// check user values are correct
|
||||
resource.TestCheckResourceAttr(resName("user", userName), "username", userName),
|
||||
resource.TestCheckResourceAttr(resName("user", userName), "roles.#", strconv.Itoa(len(data.Users[0].Roles))),
|
||||
resource.TestCheckResourceAttr(testUserID, "username", userName),
|
||||
resource.TestCheckResourceAttr(testUserID, "roles.#", strconv.Itoa(len(data.Users[0].Roles))),
|
||||
|
||||
// check database values are set
|
||||
resource.TestCheckResourceAttrSet(resName("database", dbName), "id"),
|
||||
resource.TestCheckResourceAttrSet(resName("database", dbName), "name"),
|
||||
resource.TestCheckResourceAttrSet(resName("database", dbName), "owner"),
|
||||
resource.TestCheckResourceAttrSet(resName("database", dbName), "compatibility"),
|
||||
resource.TestCheckResourceAttrSet(resName("database", dbName), "collation"),
|
||||
resource.TestCheckResourceAttrSet(testDatabaseID, "id"),
|
||||
resource.TestCheckResourceAttrSet(testDatabaseID, "name"),
|
||||
resource.TestCheckResourceAttrSet(testDatabaseID, "owner"),
|
||||
resource.TestCheckResourceAttrSet(testDatabaseID, "compatibility"),
|
||||
resource.TestCheckResourceAttrSet(testDatabaseID, "collation"),
|
||||
|
||||
// check database values are correct
|
||||
resource.TestCheckResourceAttr(resName("database", dbName), "name", dbName),
|
||||
resource.TestCheckResourceAttr(resName("database", dbName), "owner", userName),
|
||||
resource.TestCheckResourceAttr(testDatabaseID, "name", dbName),
|
||||
resource.TestCheckResourceAttr(testDatabaseID, "owner", userName),
|
||||
),
|
||||
},
|
||||
},
|
||||
|
|
@ -354,29 +374,34 @@ func TestAccInstanceEncryption(t *testing.T) {
|
|||
data.Users = []User{
|
||||
{
|
||||
Name: userName,
|
||||
ProjectId: os.Getenv("TF_ACC_PROJECT_ID"),
|
||||
ProjectID: os.Getenv("TF_ACC_PROJECT_ID"),
|
||||
Roles: []string{"##STACKIT_DatabaseManager##", "##STACKIT_LoginManager##"},
|
||||
},
|
||||
}
|
||||
data.Databases = []Database{
|
||||
{
|
||||
Name: dbName,
|
||||
ProjectId: os.Getenv("TF_ACC_PROJECT_ID"),
|
||||
ProjectID: os.Getenv("TF_ACC_PROJECT_ID"),
|
||||
Owner: userName,
|
||||
},
|
||||
}
|
||||
|
||||
data.UseEncryption = true
|
||||
data.KekKeyId = "fe039bcf-8d7b-431a-801d-9e81371a6b7b"
|
||||
data.KekKeyRingId = "6a2d95ab-3c4c-4963-a2bb-08d17a320e27"
|
||||
data.KekKeyID = "fe039bcf-8d7b-431a-801d-9e81371a6b7b"
|
||||
data.KekKeyRingID = "6a2d95ab-3c4c-4963-a2bb-08d17a320e27"
|
||||
data.KekKeyVersion = 1
|
||||
data.KekServiceAccount = "henselinm-u2v3ex1@sa.stackit.cloud"
|
||||
|
||||
testInstanceID := testutils.ResStr(pfx, "instance", data.TfName)
|
||||
testDatabaseID := testutils.ResStr(pfx, "database", dbName)
|
||||
testUserID := testutils.ResStr(pfx, "user", userName)
|
||||
|
||||
resource.ParallelTest(t, resource.TestCase{
|
||||
PreCheck: func() {
|
||||
testAccPreCheck(t)
|
||||
t.Logf(" ... working on instance %s", data.TfName)
|
||||
t.Logf(" ... %s - %s", t.Name(), data.TfName)
|
||||
},
|
||||
CheckDestroy: testAccCheckSQLServerFlexDestroy,
|
||||
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
|
||||
Steps: []resource.TestStep{
|
||||
// Create and verify
|
||||
|
|
@ -386,61 +411,296 @@ func TestAccInstanceEncryption(t *testing.T) {
|
|||
data,
|
||||
),
|
||||
Check: resource.ComposeAggregateTestCheckFunc(
|
||||
// check instance values are set
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "id"),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "backup_schedule"),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "edition"),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "flavor_id"),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "instance_id"),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "is_deletable"),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "name"),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "replicas"),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "retention_days"),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "status"),
|
||||
resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "version"),
|
||||
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption"),
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_id"),
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_version"),
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"),
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"),
|
||||
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.access_scope"),
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.acl"),
|
||||
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.instance_address"),
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.router_address"),
|
||||
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "storage.class"),
|
||||
// resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "storage.size"),
|
||||
|
||||
// check instance values are correct
|
||||
resource.TestCheckResourceAttr(resName("instance", data.TfName), "name", data.Name),
|
||||
defaultEncInstanceTestChecks(testInstanceID, data),
|
||||
|
||||
// check user values are set
|
||||
resource.TestCheckResourceAttrSet(resName("user", userName), "id"),
|
||||
resource.TestCheckResourceAttrSet(resName("user", userName), "username"),
|
||||
resource.TestCheckResourceAttrSet(testUserID, "id"),
|
||||
resource.TestCheckResourceAttrSet(testUserID, "username"),
|
||||
|
||||
// func(s *terraform.State) error {
|
||||
// return nil
|
||||
// },
|
||||
|
||||
// check user values are correct
|
||||
resource.TestCheckResourceAttr(resName("user", userName), "username", userName),
|
||||
resource.TestCheckResourceAttr(resName("user", userName), "roles.#", "2"),
|
||||
resource.TestCheckResourceAttr(testUserID, "username", userName),
|
||||
resource.TestCheckResourceAttr(testUserID, "roles.#", "2"),
|
||||
|
||||
// check database values are set
|
||||
resource.TestCheckResourceAttrSet(resName("database", dbName), "id"),
|
||||
resource.TestCheckResourceAttrSet(resName("database", dbName), "name"),
|
||||
resource.TestCheckResourceAttrSet(resName("database", dbName), "owner"),
|
||||
resource.TestCheckResourceAttrSet(resName("database", dbName), "compatibility"),
|
||||
resource.TestCheckResourceAttrSet(resName("database", dbName), "collation"),
|
||||
resource.TestCheckResourceAttrSet(testDatabaseID, "id"),
|
||||
resource.TestCheckResourceAttrSet(testDatabaseID, "name"),
|
||||
resource.TestCheckResourceAttrSet(testDatabaseID, "owner"),
|
||||
resource.TestCheckResourceAttrSet(testDatabaseID, "compatibility"),
|
||||
resource.TestCheckResourceAttrSet(testDatabaseID, "collation"),
|
||||
|
||||
// check database values are correct
|
||||
resource.TestCheckResourceAttr(resName("database", dbName), "name", dbName),
|
||||
resource.TestCheckResourceAttr(resName("database", dbName), "owner", userName),
|
||||
resource.TestCheckResourceAttr(testDatabaseID, "name", dbName),
|
||||
resource.TestCheckResourceAttr(testDatabaseID, "owner", userName),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func defaultNoEncInstanceTestChecks(testItemID string, data resData) resource.TestCheckFunc {
|
||||
return resource.ComposeAggregateTestCheckFunc(
|
||||
defaultInstanceTestChecks(testItemID, data),
|
||||
|
||||
// check absent attr
|
||||
resource.TestCheckNoResourceAttr(testItemID, "encryption"),
|
||||
resource.TestCheckNoResourceAttr(testItemID, "encryption.kek_key_id"),
|
||||
resource.TestCheckNoResourceAttr(testItemID, "encryption.kek_key_ring_id"),
|
||||
resource.TestCheckNoResourceAttr(testItemID, "encryption.kek_key_version"),
|
||||
resource.TestCheckNoResourceAttr(testItemID, "encryption.service_account"),
|
||||
)
|
||||
}
|
||||
|
||||
func defaultEncInstanceTestChecks(testItemID string, data resData) resource.TestCheckFunc {
|
||||
return resource.ComposeAggregateTestCheckFunc(
|
||||
defaultInstanceTestChecks(testItemID, data),
|
||||
|
||||
// check absent attr
|
||||
resource.TestCheckResourceAttr(testItemID, "encryption.%", "4"),
|
||||
resource.TestCheckResourceAttrSet(testItemID, "encryption.kek_key_id"),
|
||||
resource.TestCheckResourceAttr(testItemID, "encryption.kek_key_id", data.KekKeyID),
|
||||
resource.TestCheckResourceAttrSet(testItemID, "encryption.kek_key_ring_id"),
|
||||
resource.TestCheckResourceAttr(testItemID, "encryption.kek_key_ring_id", data.KekKeyRingID),
|
||||
resource.TestCheckResourceAttrSet(testItemID, "encryption.kek_key_version"),
|
||||
resource.TestCheckResourceAttr(testItemID, "encryption.kek_key_version", strconv.Itoa(int(data.KekKeyVersion))),
|
||||
resource.TestCheckResourceAttrSet(testItemID, "encryption.service_account"),
|
||||
resource.TestCheckResourceAttr(testItemID, "encryption.service_account", data.KekServiceAccount),
|
||||
)
|
||||
}
|
||||
|
||||
func defaultInstanceTestChecks(testItemID string, data resData) resource.TestCheckFunc {
|
||||
// if AccessScope == SNA these are set
|
||||
if data.AccessScope == "SNA" {
|
||||
return resource.ComposeAggregateTestCheckFunc(
|
||||
basicInstanceTestChecks(testItemID, data),
|
||||
resource.TestCheckResourceAttrSet(testItemID, "network.instance_address"),
|
||||
resource.TestCheckResourceAttrSet(testItemID, "network.router_address"),
|
||||
)
|
||||
}
|
||||
|
||||
// if AccessScope == PUBLIC these are empty - but they are set
|
||||
return resource.ComposeAggregateTestCheckFunc(
|
||||
basicInstanceTestChecks(testItemID, data),
|
||||
resource.TestCheckResourceAttr(testItemID, "network.instance_address", ""),
|
||||
resource.TestCheckResourceAttr(testItemID, "network.router_address", ""),
|
||||
)
|
||||
}
|
||||
|
||||
func basicInstanceTestChecks(testItemID string, data resData) resource.TestCheckFunc {
|
||||
return resource.ComposeAggregateTestCheckFunc(
|
||||
resource.TestCheckResourceAttrSet(testItemID, "backup_schedule"),
|
||||
resource.TestCheckResourceAttr(testItemID, "backup_schedule", data.BackupSchedule),
|
||||
|
||||
resource.TestCheckResourceAttrSet(testItemID, "flavor_id"),
|
||||
resource.TestCheckResourceAttr(testItemID, "flavor_id", data.FlavorID),
|
||||
|
||||
resource.TestCheckResourceAttrSet(testItemID, "id"),
|
||||
resource.TestCheckResourceAttrSet(testItemID, "instance_id"),
|
||||
|
||||
resource.TestCheckResourceAttrSet(testItemID, "edition"),
|
||||
|
||||
resource.TestCheckResourceAttrSet(testItemID, "is_deletable"),
|
||||
resource.TestCheckResourceAttr(testItemID, "is_deletable", "true"),
|
||||
|
||||
resource.TestCheckResourceAttrSet(testItemID, "name"),
|
||||
resource.TestCheckResourceAttr(testItemID, "name", data.Name),
|
||||
|
||||
// network params check
|
||||
resource.TestCheckResourceAttr(testItemID, "network.%", "4"),
|
||||
resource.TestCheckResourceAttrSet(testItemID, "network.access_scope"),
|
||||
resource.TestCheckResourceAttr(testItemID, "network.access_scope", data.AccessScope),
|
||||
// resource.TestCheckResourceAttrSet(testItemID, "network.acl"),
|
||||
resource.TestCheckResourceAttr(testItemID, "network.acl.#", strconv.Itoa(len(data.ACLStrings))),
|
||||
// instance_address and router_address are only checked in enc
|
||||
|
||||
resource.TestCheckResourceAttrSet(testItemID, "project_id"),
|
||||
resource.TestCheckResourceAttr(testItemID, "project_id", data.ProjectID),
|
||||
|
||||
resource.TestCheckResourceAttrSet(testItemID, "region"),
|
||||
resource.TestCheckResourceAttr(testItemID, "region", data.Region),
|
||||
|
||||
resource.TestCheckResourceAttrSet(testItemID, "retention_days"),
|
||||
resource.TestCheckResourceAttr(testItemID, "retention_days", strconv.Itoa(int(data.RetentionDays))),
|
||||
|
||||
resource.TestCheckResourceAttrSet(testItemID, "status"),
|
||||
resource.TestCheckResourceAttr(testItemID, "status", "READY"),
|
||||
|
||||
// storage params check
|
||||
resource.TestCheckResourceAttr(testItemID, "storage.%", "2"),
|
||||
resource.TestCheckResourceAttrSet(testItemID, "storage.class"),
|
||||
resource.TestCheckResourceAttr(testItemID, "storage.class", data.PerformanceClass),
|
||||
resource.TestCheckResourceAttrSet(testItemID, "storage.size"),
|
||||
resource.TestCheckResourceAttr(testItemID, "storage.size", strconv.Itoa(int(data.Size))),
|
||||
|
||||
resource.TestCheckResourceAttrSet(testItemID, "version"),
|
||||
resource.TestCheckResourceAttr(testItemID, "version", data.Version),
|
||||
)
|
||||
}
|
||||
|
||||
func getInstanceTestID(name string) func(s *terraform.State) (string, error) {
|
||||
return func(s *terraform.State) (string, error) {
|
||||
r, ok := s.RootModule().Resources[testutils.ResStr(pfx, "instance", name)]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("couldn't find resource stackitprivatepreview_postgresflexalpha_instance.%s", name)
|
||||
}
|
||||
projectID, ok := r.Primary.Attributes["project_id"]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("couldn't find attribute project_id")
|
||||
}
|
||||
region, ok := r.Primary.Attributes["region"]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("couldn't find attribute region")
|
||||
}
|
||||
instanceID, ok := r.Primary.Attributes["instance_id"]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("couldn't find attribute instance_id")
|
||||
}
|
||||
return fmt.Sprintf("%s,%s,%s", projectID, region, instanceID), nil
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
func getDatabaseTestID(name string) func(s *terraform.State) (string, error) {
|
||||
return func(s *terraform.State) (string, error) {
|
||||
r, ok := s.RootModule().Resources[testutils.ResStr(pfx, "database", name)]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("couldn't find resource stackitprivatepreview_postgresflexalpha_instance.%s", name)
|
||||
}
|
||||
projectID, ok := r.Primary.Attributes["project_id"]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("couldn't find attribute project_id")
|
||||
}
|
||||
region, ok := r.Primary.Attributes["region"]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("couldn't find attribute region")
|
||||
}
|
||||
instanceID, ok := r.Primary.Attributes["instance_id"]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("couldn't find attribute instance_id")
|
||||
}
|
||||
databaseID, ok := r.Primary.Attributes["database_id"]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("couldn't find attribute database_id")
|
||||
}
|
||||
return fmt.Sprintf("%s,%s,%s,%s", projectID, region, instanceID, databaseID), nil
|
||||
}
|
||||
}
|
||||
|
||||
func getUserTestID(name string) func(s *terraform.State) (string, error) {
|
||||
return func(s *terraform.State) (string, error) {
|
||||
r, ok := s.RootModule().Resources[testutils.ResStr(pfx, "user", name)]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("couldn't find resource stackitprivatepreview_postgresflexalpha_instance.%s", name)
|
||||
}
|
||||
projectID, ok := r.Primary.Attributes["project_id"]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("couldn't find attribute project_id")
|
||||
}
|
||||
region, ok := r.Primary.Attributes["region"]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("couldn't find attribute region")
|
||||
}
|
||||
instanceID, ok := r.Primary.Attributes["instance_id"]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("couldn't find attribute instance_id")
|
||||
}
|
||||
userID, ok := r.Primary.Attributes["user_id"]
|
||||
if !ok {
|
||||
return "", fmt.Errorf("couldn't find attribute user_id")
|
||||
}
|
||||
return fmt.Sprintf("%s,%s,%s,%s", projectID, region, instanceID, userID), nil
|
||||
}
|
||||
}
|
||||
*/
|
||||
func testAccCheckSQLServerFlexDestroy(s *terraform.State) error {
|
||||
testutils.Setup()
|
||||
|
||||
pID, ok := os.LookupEnv("TF_ACC_PROJECT_ID")
|
||||
if !ok {
|
||||
log.Fatalln("unable to read TF_ACC_PROJECT_ID")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
var client *v3beta1api.APIClient
|
||||
var err error
|
||||
|
||||
var region, projectID string
|
||||
region = testutils.Region
|
||||
if region == "" {
|
||||
region = "eu01"
|
||||
}
|
||||
|
||||
projectID = pID
|
||||
if projectID == "" {
|
||||
return fmt.Errorf("projectID could not be determined in destroy function")
|
||||
}
|
||||
|
||||
apiClientConfigOptions := []config.ConfigurationOption{
|
||||
config.WithServiceAccountKeyPath(os.Getenv("TF_ACC_SERVICE_ACCOUNT_FILE")),
|
||||
config.WithRegion(region),
|
||||
}
|
||||
if testutils.PostgresFlexCustomEndpoint != "" {
|
||||
apiClientConfigOptions = append(
|
||||
apiClientConfigOptions,
|
||||
config.WithEndpoint(testutils.PostgresFlexCustomEndpoint),
|
||||
)
|
||||
}
|
||||
client, err = v3beta1api.NewAPIClient(apiClientConfigOptions...)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
instancesToDestroy := []string{}
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "stackitprivatepreview_postgresflexalpha_instance" &&
|
||||
rs.Type != "stackitprivatepreview_postgresflexbeta_instance" {
|
||||
continue
|
||||
}
|
||||
|
||||
// instance terraform ID: = "[project_id],[region],[instance_id]"
|
||||
instanceID := strings.Split(rs.Primary.ID, core.Separator)[2]
|
||||
instancesToDestroy = append(instancesToDestroy, instanceID)
|
||||
}
|
||||
|
||||
instancesResp, err := client.DefaultAPI.ListInstancesRequest(ctx, projectID, region).
|
||||
Size(100).
|
||||
Execute()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting instancesResp: %w", err)
|
||||
}
|
||||
|
||||
items := instancesResp.GetInstances()
|
||||
for i := range items {
|
||||
if items[i].Id == "" {
|
||||
continue
|
||||
}
|
||||
if utils.Contains(instancesToDestroy, items[i].Id) {
|
||||
err := client.DefaultAPI.DeleteInstanceRequest(ctx, projectID, region, items[i].Id).Execute()
|
||||
if err != nil {
|
||||
return fmt.Errorf("deleting instance %s during CheckDestroy: %w", items[i].Id, err)
|
||||
}
|
||||
w := wait.DeleteInstanceWaitHandler(
|
||||
ctx,
|
||||
client.DefaultAPI,
|
||||
testutils.ProjectId,
|
||||
testutils.Region,
|
||||
items[i].Id,
|
||||
)
|
||||
_, waitErr := w.SetTimeout(90 * time.Second).WaitWithContext(context.Background())
|
||||
if waitErr != nil {
|
||||
var oapiErr *oapierror.GenericOpenAPIError
|
||||
isOapiErr := errors.As(waitErr, &oapiErr)
|
||||
if !isOapiErr {
|
||||
return fmt.Errorf("could not convert error to oapierror.GenericOpenAPIError")
|
||||
}
|
||||
if oapiErr.StatusCode != http.StatusNotFound {
|
||||
return waitErr
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,35 +4,37 @@ provider "stackitprivatepreview" {
|
|||
}
|
||||
|
||||
resource "stackitprivatepreview_sqlserverflexbeta_instance" "{{ .TfName }}" {
|
||||
project_id = "{{ .ProjectId }}"
|
||||
project_id = "{{ .ProjectID }}"
|
||||
name = "{{ .Name }}"
|
||||
backup_schedule = "{{ .BackupSchedule }}"
|
||||
retention_days = {{ .RetentionDays }}
|
||||
flavor_id = "{{ .FlavorId }}"
|
||||
flavor_id = "{{ .FlavorID }}"
|
||||
storage = {
|
||||
class = "{{ .PerformanceClass }}"
|
||||
size = {{ .Size }}
|
||||
}
|
||||
{{ if .UseEncryption }}
|
||||
encryption = {
|
||||
kek_key_id = "{{ .KekKeyId }}"
|
||||
kek_key_ring_id = "{{ .KekKeyRingId }}"
|
||||
kek_key_id = "{{ .KekKeyID }}"
|
||||
kek_key_ring_id = "{{ .KekKeyRingID }}"
|
||||
kek_key_version = {{ .KekKeyVersion }}
|
||||
service_account = "{{ .KekServiceAccount }}"
|
||||
}
|
||||
{{ end }}
|
||||
network = {
|
||||
acl = ["{{ .AclString }}"]
|
||||
acl = [{{ range $i, $v := .ACLStrings }}{{if $i}},{{end}}"{{$v}}"{{end}}]
|
||||
access_scope = "{{ .AccessScope }}"
|
||||
}
|
||||
{{ if .Version }}
|
||||
version = "{{ .Version }}"
|
||||
{{ end }}
|
||||
}
|
||||
|
||||
{{ if .Users }}
|
||||
{{ $tfName := .TfName }}
|
||||
{{ range $user := .Users }}
|
||||
resource "stackitprivatepreview_sqlserverflexbeta_user" "{{ $user.Name }}" {
|
||||
project_id = "{{ $user.ProjectId }}"
|
||||
project_id = "{{ $user.ProjectID }}"
|
||||
instance_id = stackitprivatepreview_sqlserverflexbeta_instance.{{ $tfName }}.instance_id
|
||||
username = "{{ $user.Name }}"
|
||||
roles = [{{ range $i, $v := $user.Roles }}{{if $i}},{{end}}"{{$v}}"{{end}}]
|
||||
|
|
@ -45,7 +47,7 @@ resource "stackitprivatepreview_sqlserverflexbeta_user" "{{ $user.Name }}" {
|
|||
{{ range $db := .Databases }}
|
||||
resource "stackitprivatepreview_sqlserverflexbeta_database" "{{ $db.Name }}" {
|
||||
depends_on = [stackitprivatepreview_sqlserverflexbeta_user.{{ $db.Owner }}]
|
||||
project_id = "{{ $db.ProjectId }}"
|
||||
project_id = "{{ $db.ProjectID }}"
|
||||
instance_id = stackitprivatepreview_sqlserverflexbeta_instance.{{ $tfName }}.instance_id
|
||||
name = "{{ $db.Name }}"
|
||||
owner = "{{ $db.Owner }}"
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@ package postgresflexalpha
|
|||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
|
|
@ -29,45 +31,47 @@ const (
|
|||
|
||||
// APIClientInstanceInterface Interface needed for tests
|
||||
type APIClientInstanceInterface interface {
|
||||
GetInstanceRequest(ctx context.Context, projectId, region, instanceId string) v3alpha1api.ApiGetInstanceRequestRequest
|
||||
GetInstanceRequest(ctx context.Context, projectID, region, instanceID string) v3alpha1api.ApiGetInstanceRequestRequest
|
||||
|
||||
ListUsersRequest(
|
||||
ctx context.Context,
|
||||
projectId string,
|
||||
projectID string,
|
||||
region string,
|
||||
instanceId string,
|
||||
instanceID string,
|
||||
) v3alpha1api.ApiListUsersRequestRequest
|
||||
}
|
||||
|
||||
// APIClientUserInterface Interface needed for tests
|
||||
type APIClientUserInterface interface {
|
||||
GetUserRequest(ctx context.Context, projectId, region, instanceId string, userId int32) v3alpha1api.ApiGetUserRequestRequest
|
||||
GetUserRequest(ctx context.Context, projectID, region, instanceID string, userID int32) v3alpha1api.ApiGetUserRequestRequest
|
||||
}
|
||||
|
||||
// APIClientDatabaseInterface Interface needed for tests
|
||||
type APIClientDatabaseInterface interface {
|
||||
GetDatabaseRequest(ctx context.Context, projectId string, region string, instanceId string, databaseId int32) v3alpha1api.ApiGetDatabaseRequestRequest
|
||||
GetDatabaseRequest(ctx context.Context, projectID string, region string, instanceID string, databaseID int32) v3alpha1api.ApiGetDatabaseRequestRequest
|
||||
}
|
||||
|
||||
// CreateInstanceWaitHandler will wait for instance creation
|
||||
func CreateInstanceWaitHandler(
|
||||
ctx context.Context, a APIClientInstanceInterface, projectId, region,
|
||||
instanceId string,
|
||||
ctx context.Context, a APIClientInstanceInterface, projectID, region,
|
||||
instanceID string,
|
||||
) *wait.AsyncActionHandler[v3alpha1api.GetInstanceResponse] {
|
||||
instanceCreated := false
|
||||
var instanceGetResponse *v3alpha1api.GetInstanceResponse
|
||||
maxWait := time.Minute * 45
|
||||
startTime := time.Now()
|
||||
extendedTimeout := 0
|
||||
maxFailedCount := 3
|
||||
failedCount := 0
|
||||
|
||||
handler := wait.New(
|
||||
func() (waitFinished bool, response *v3alpha1api.GetInstanceResponse, err error) {
|
||||
if !instanceCreated {
|
||||
s, err := a.GetInstanceRequest(ctx, projectId, region, instanceId).Execute()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
s, getErr := a.GetInstanceRequest(ctx, projectID, region, instanceID).Execute()
|
||||
if getErr != nil {
|
||||
return false, nil, getErr
|
||||
}
|
||||
if s == nil || s.Id != instanceId {
|
||||
if s == nil || s.Id != instanceID {
|
||||
return false, nil, nil
|
||||
}
|
||||
tflog.Debug(
|
||||
|
|
@ -77,7 +81,7 @@ func CreateInstanceWaitHandler(
|
|||
)
|
||||
switch s.Status {
|
||||
default:
|
||||
return true, s, fmt.Errorf("instance with id %s has unexpected status %s", instanceId, s.Status)
|
||||
return true, s, fmt.Errorf("instance with id %s has unexpected status %s", instanceID, s.Status)
|
||||
case InstanceStateEmpty:
|
||||
return false, nil, nil
|
||||
case InstanceStatePending:
|
||||
|
|
@ -94,30 +98,15 @@ func CreateInstanceWaitHandler(
|
|||
"Wait handler still got status %s after %v for instance: %s",
|
||||
InstanceStateProgressing,
|
||||
maxWait,
|
||||
instanceId,
|
||||
instanceID,
|
||||
),
|
||||
)
|
||||
if extendedTimeout < 3 {
|
||||
maxWait += time.Minute * 5
|
||||
extendedTimeout++
|
||||
if *s.Network.AccessScope == "SNA" {
|
||||
ready := true
|
||||
if s.Network.InstanceAddress == nil {
|
||||
tflog.Warn(ctx, "Waiting for instance_address")
|
||||
ready = false
|
||||
}
|
||||
if s.Network.RouterAddress == nil {
|
||||
tflog.Warn(ctx, "Waiting for router_address")
|
||||
ready = false
|
||||
}
|
||||
if !ready {
|
||||
return false, nil, nil
|
||||
}
|
||||
}
|
||||
return false, nil, nil
|
||||
}
|
||||
|
||||
instanceCreated = true
|
||||
instanceGetResponse = s
|
||||
return false, nil, fmt.Errorf("instance after max timeout still in state %s", InstanceStateProgressing)
|
||||
case InstanceStateSuccess:
|
||||
if s.Network.AccessScope != nil && *s.Network.AccessScope == "SNA" {
|
||||
if s.Network.InstanceAddress == nil {
|
||||
|
|
@ -132,8 +121,27 @@ func CreateInstanceWaitHandler(
|
|||
instanceCreated = true
|
||||
instanceGetResponse = s
|
||||
case InstanceStateFailed:
|
||||
tflog.Warn(ctx, fmt.Sprintf("Wait handler got status FAILURE for instance: %s", instanceId))
|
||||
return false, nil, nil
|
||||
if failedCount < maxFailedCount {
|
||||
failedCount++
|
||||
tflog.Warn(
|
||||
ctx, "got failed status from API retry", map[string]interface{}{
|
||||
"failedCount": failedCount,
|
||||
},
|
||||
)
|
||||
var waitCounter int64 = 1
|
||||
maxWaitInt := big.NewInt(7)
|
||||
n, randErr := rand.Int(rand.Reader, maxWaitInt)
|
||||
if randErr == nil {
|
||||
waitCounter = n.Int64() + 1
|
||||
}
|
||||
time.Sleep(time.Duration(waitCounter*30) * time.Second) //nolint:gosec // not that important and temporary
|
||||
return false, nil, nil
|
||||
}
|
||||
return true, s, fmt.Errorf(
|
||||
"update got status FAILURE for instance with id %s after %d retries",
|
||||
instanceID,
|
||||
failedCount,
|
||||
)
|
||||
// API responds with FAILURE for some seconds and then the instance goes to READY
|
||||
// return true, s, fmt.Errorf("create failed for instance with id %s", instanceId)
|
||||
}
|
||||
|
|
@ -142,7 +150,7 @@ func CreateInstanceWaitHandler(
|
|||
tflog.Info(ctx, "Waiting for instance (calling list users")
|
||||
// // User operations aren't available right after an instance is deemed successful
|
||||
// // To check if they are, perform a users request
|
||||
_, err = a.ListUsersRequest(ctx, projectId, region, instanceId).Execute()
|
||||
_, err = a.ListUsersRequest(ctx, projectID, region, instanceID).Execute()
|
||||
if err == nil {
|
||||
return true, instanceGetResponse, nil
|
||||
}
|
||||
|
|
@ -150,7 +158,7 @@ func CreateInstanceWaitHandler(
|
|||
if !ok {
|
||||
return false, nil, err
|
||||
}
|
||||
// TODO: refactor and cooperate with api guys to mitigate
|
||||
// TODO: refactor and cooperate with api guys to mitigate // nolint: // reason upfront
|
||||
if oapiErr.StatusCode < 500 {
|
||||
return true, instanceGetResponse, fmt.Errorf(
|
||||
"users request after instance creation returned %d status code",
|
||||
|
|
@ -160,8 +168,6 @@ func CreateInstanceWaitHandler(
|
|||
return false, nil, nil
|
||||
},
|
||||
)
|
||||
// Sleep before wait is set because sometimes API returns 404 right after creation request
|
||||
handler.SetTimeout(90 * time.Minute).SetSleepBeforeWait(30 * time.Second)
|
||||
return handler
|
||||
}
|
||||
|
||||
|
|
@ -170,6 +176,8 @@ func PartialUpdateInstanceWaitHandler(
|
|||
ctx context.Context, a APIClientInstanceInterface, projectID, region,
|
||||
instanceID string,
|
||||
) *wait.AsyncActionHandler[v3alpha1api.GetInstanceResponse] {
|
||||
maxFailedCount := 3
|
||||
failedCount := 0
|
||||
handler := wait.New(
|
||||
func() (waitFinished bool, response *v3alpha1api.GetInstanceResponse, err error) {
|
||||
s, err := a.GetInstanceRequest(ctx, projectID, region, instanceID).Execute()
|
||||
|
|
@ -195,11 +203,30 @@ func PartialUpdateInstanceWaitHandler(
|
|||
case InstanceStateUnknown:
|
||||
return false, nil, nil
|
||||
case InstanceStateFailed:
|
||||
return true, s, fmt.Errorf("update got status FAILURE for instance with id %s", instanceID)
|
||||
if failedCount < maxFailedCount {
|
||||
failedCount++
|
||||
tflog.Warn(
|
||||
ctx, "got failed status from API retry", map[string]interface{}{
|
||||
"failedCount": failedCount,
|
||||
},
|
||||
)
|
||||
var waitCounter int64 = 1
|
||||
maxWait := big.NewInt(7)
|
||||
n, err := rand.Int(rand.Reader, maxWait)
|
||||
if err == nil {
|
||||
waitCounter = n.Int64() + 1
|
||||
}
|
||||
time.Sleep(time.Duration(waitCounter*30) * time.Second) //nolint:gosec // not that important and temporary
|
||||
return false, nil, nil
|
||||
}
|
||||
return true, s, fmt.Errorf(
|
||||
"update got status FAILURE for instance with id %s after %d retries",
|
||||
instanceID,
|
||||
failedCount,
|
||||
)
|
||||
}
|
||||
},
|
||||
)
|
||||
handler.SetTimeout(45 * time.Minute).SetSleepBeforeWait(30 * time.Second)
|
||||
return handler
|
||||
}
|
||||
|
||||
|
|
@ -295,6 +322,8 @@ func DeleteInstanceWaitHandler(
|
|||
instanceID string,
|
||||
timeout, sleepBeforeWait time.Duration,
|
||||
) error {
|
||||
maxFailedCount := 3
|
||||
failedCount := 0
|
||||
handler := wait.New(
|
||||
func() (waitFinished bool, response *v3alpha1api.GetInstanceResponse, err error) {
|
||||
s, err := a.GetInstanceRequest(ctx, projectID, region, instanceID).Execute()
|
||||
|
|
@ -314,6 +343,22 @@ func DeleteInstanceWaitHandler(
|
|||
case InstanceStateEmpty, InstanceStatePending, InstanceStateUnknown, InstanceStateProgressing, InstanceStateSuccess:
|
||||
return false, nil, nil
|
||||
case InstanceStateFailed:
|
||||
if failedCount < maxFailedCount {
|
||||
failedCount++
|
||||
tflog.Warn(
|
||||
ctx, "got failed status from API retry", map[string]interface{}{
|
||||
"failedCount": failedCount,
|
||||
},
|
||||
)
|
||||
var waitCounter int64 = 1
|
||||
maxWait := big.NewInt(7)
|
||||
n, err := rand.Int(rand.Reader, maxWait)
|
||||
if err == nil {
|
||||
waitCounter = n.Int64() + 1
|
||||
}
|
||||
time.Sleep(time.Duration(waitCounter*30) * time.Second) //nolint:gosec // not that important and temporary
|
||||
return false, nil, nil
|
||||
}
|
||||
return true, nil, fmt.Errorf("wait handler got status FAILURE for instance: %s", instanceID)
|
||||
default:
|
||||
return true, s, fmt.Errorf("instance with id %s has unexpected status %s", instanceID, s.Status)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ package postgresflexalpha
|
|||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
|
@ -22,6 +23,8 @@ func TestCreateInstanceWaitHandler(t *testing.T) {
|
|||
usersGetErrorStatus int
|
||||
wantErr bool
|
||||
wantRes *v3alpha1api.GetInstanceResponse
|
||||
timeout time.Duration
|
||||
onlyOnLong bool
|
||||
}{
|
||||
{
|
||||
desc: "create_succeeded",
|
||||
|
|
@ -46,6 +49,7 @@ func TestCreateInstanceWaitHandler(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
onlyOnLong: true,
|
||||
desc: "create_failed",
|
||||
instanceGetFails: false,
|
||||
instanceState: InstanceStateFailed,
|
||||
|
|
@ -56,7 +60,18 @@ func TestCreateInstanceWaitHandler(t *testing.T) {
|
|||
RouterAddress: utils.Ptr("10.0.0.1"),
|
||||
},
|
||||
wantErr: true,
|
||||
wantRes: nil,
|
||||
wantRes: &v3alpha1api.GetInstanceResponse{
|
||||
Id: "foo-bar",
|
||||
Status: InstanceStateFailed,
|
||||
Network: v3alpha1api.InstanceNetwork{
|
||||
AccessScope: nil,
|
||||
Acl: nil,
|
||||
InstanceAddress: utils.Ptr("10.0.0.1"),
|
||||
RouterAddress: utils.Ptr("10.0.0.1"),
|
||||
},
|
||||
},
|
||||
// waiter uses random timeouts up to 8 times 30 secs
|
||||
timeout: 300 * time.Second,
|
||||
},
|
||||
{
|
||||
desc: "create_failed_2",
|
||||
|
|
@ -142,6 +157,13 @@ func TestCreateInstanceWaitHandler(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if tt.onlyOnLong {
|
||||
_, ok := os.LookupEnv("TF_RUN_LONG_TESTS")
|
||||
if !ok {
|
||||
t.Logf("skipping test '%s' because TF_RUN_LONG_TESTS env var is missing", tt.desc)
|
||||
continue
|
||||
}
|
||||
}
|
||||
t.Run(
|
||||
tt.desc, func(t *testing.T) {
|
||||
instanceID := "foo-bar"
|
||||
|
|
@ -181,9 +203,13 @@ func TestCreateInstanceWaitHandler(t *testing.T) {
|
|||
ListUsersRequestExecuteMock: &listUsersMock,
|
||||
}
|
||||
|
||||
handler := CreateInstanceWaitHandler(context.Background(), apiClientMock, "", "", instanceID)
|
||||
handler := CreateInstanceWaitHandler(context.Background(), apiClientMock, "", "", instanceID).
|
||||
SetTimeout(10 * time.Millisecond)
|
||||
if tt.timeout != 0 {
|
||||
handler.SetTimeout(tt.timeout)
|
||||
}
|
||||
|
||||
gotRes, err := handler.SetTimeout(10 * time.Millisecond).SetSleepBeforeWait(1 * time.Millisecond).WaitWithContext(context.Background())
|
||||
gotRes, err := handler.SetSleepBeforeWait(1 * time.Millisecond).WaitWithContext(context.Background())
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
|
|
@ -204,6 +230,8 @@ func TestUpdateInstanceWaitHandler(t *testing.T) {
|
|||
instanceNetwork v3alpha1api.InstanceNetwork
|
||||
wantErr bool
|
||||
wantRes *v3alpha1api.GetInstanceResponse
|
||||
timeout time.Duration
|
||||
onlyOnLong bool
|
||||
}{
|
||||
{
|
||||
desc: "update_succeeded",
|
||||
|
|
@ -228,6 +256,7 @@ func TestUpdateInstanceWaitHandler(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
onlyOnLong: true,
|
||||
desc: "update_failed",
|
||||
instanceGetFails: false,
|
||||
instanceState: InstanceStateFailed,
|
||||
|
|
@ -248,6 +277,7 @@ func TestUpdateInstanceWaitHandler(t *testing.T) {
|
|||
RouterAddress: utils.Ptr("10.0.0.1"),
|
||||
},
|
||||
},
|
||||
timeout: 300 * time.Second,
|
||||
},
|
||||
{
|
||||
desc: "update_failed_2",
|
||||
|
|
@ -283,6 +313,14 @@ func TestUpdateInstanceWaitHandler(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if tt.onlyOnLong {
|
||||
_, ok := os.LookupEnv("TF_RUN_LONG_TESTS")
|
||||
if !ok {
|
||||
t.Logf("skipping test '%s' because TF_RUN_LONG_TESTS env var is missing", tt.desc)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
t.Run(
|
||||
tt.desc, func(t *testing.T) {
|
||||
instanceID := "foo-bar"
|
||||
|
|
@ -316,9 +354,13 @@ func TestUpdateInstanceWaitHandler(t *testing.T) {
|
|||
ListUsersRequestExecuteMock: &listUsersMock,
|
||||
}
|
||||
|
||||
handler := PartialUpdateInstanceWaitHandler(context.Background(), apiClientMock, "", "", instanceID)
|
||||
handler := PartialUpdateInstanceWaitHandler(context.Background(), apiClientMock, "", "", instanceID).
|
||||
SetTimeout(10 * time.Millisecond)
|
||||
if tt.timeout > 0 {
|
||||
handler.SetTimeout(tt.timeout)
|
||||
}
|
||||
|
||||
gotRes, err := handler.SetTimeout(10 * time.Millisecond).WaitWithContext(context.Background())
|
||||
gotRes, err := handler.WaitWithContext(context.Background())
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Fatalf("handler error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,35 +30,35 @@ const (
|
|||
type APIClientInterface interface {
|
||||
GetInstanceRequest(
|
||||
ctx context.Context,
|
||||
projectId, region, instanceId string,
|
||||
projectID, region, instanceID string,
|
||||
) sqlserverflex.ApiGetInstanceRequestRequest
|
||||
GetDatabaseRequest(
|
||||
ctx context.Context,
|
||||
projectId string,
|
||||
projectID string,
|
||||
region string,
|
||||
instanceId string,
|
||||
instanceID string,
|
||||
databaseName string,
|
||||
) sqlserverflex.ApiGetDatabaseRequestRequest
|
||||
GetUserRequest(
|
||||
ctx context.Context,
|
||||
projectId string,
|
||||
projectID string,
|
||||
region string,
|
||||
instanceId string,
|
||||
userId int64,
|
||||
instanceID string,
|
||||
userID int64,
|
||||
) sqlserverflex.ApiGetUserRequestRequest
|
||||
|
||||
ListRolesRequest(
|
||||
ctx context.Context,
|
||||
projectId string,
|
||||
projectID string,
|
||||
region string,
|
||||
instanceId string,
|
||||
instanceID string,
|
||||
) sqlserverflex.ApiListRolesRequestRequest
|
||||
|
||||
ListUsersRequest(
|
||||
ctx context.Context,
|
||||
projectId string,
|
||||
projectID string,
|
||||
region string,
|
||||
instanceId string,
|
||||
instanceID string,
|
||||
) sqlserverflex.ApiListUsersRequestRequest
|
||||
}
|
||||
|
||||
|
|
@ -66,10 +66,10 @@ type APIClientInterface interface {
|
|||
type APIClientUserInterface interface {
|
||||
DeleteUserRequestExecute(
|
||||
ctx context.Context,
|
||||
projectId string,
|
||||
projectID string,
|
||||
region string,
|
||||
instanceId string,
|
||||
userId int64,
|
||||
instanceID string,
|
||||
userID int64,
|
||||
) error
|
||||
}
|
||||
|
||||
|
|
@ -77,11 +77,11 @@ type APIClientUserInterface interface {
|
|||
func CreateInstanceWaitHandler(
|
||||
ctx context.Context,
|
||||
a APIClientInterface,
|
||||
projectId, instanceId, region string,
|
||||
projectID, instanceID, region string,
|
||||
) *wait.AsyncActionHandler[sqlserverflex.GetInstanceResponse] {
|
||||
handler := wait.New(
|
||||
func() (waitFinished bool, response *sqlserverflex.GetInstanceResponse, err error) {
|
||||
s, err := a.GetInstanceRequest(ctx, projectId, region, instanceId).Execute()
|
||||
s, err := a.GetInstanceRequest(ctx, projectID, region, instanceID).Execute()
|
||||
if err != nil {
|
||||
var oapiErr *oapierror.GenericOpenAPIError
|
||||
ok := errors.As(err, &oapiErr)
|
||||
|
|
@ -95,7 +95,7 @@ func CreateInstanceWaitHandler(
|
|||
return false, nil, fmt.Errorf("api error: %w", err)
|
||||
}
|
||||
}
|
||||
if s == nil || s.Id != instanceId {
|
||||
if s == nil || s.Id != instanceID {
|
||||
return false, nil, nil
|
||||
}
|
||||
switch strings.ToLower(string(s.Status)) {
|
||||
|
|
@ -113,7 +113,7 @@ func CreateInstanceWaitHandler(
|
|||
|
||||
tflog.Info(ctx, "trying to get roles")
|
||||
time.Sleep(10 * time.Second)
|
||||
_, rolesErr := a.ListRolesRequest(ctx, projectId, region, instanceId).Execute()
|
||||
_, rolesErr := a.ListRolesRequest(ctx, projectID, region, instanceID).Execute()
|
||||
if rolesErr != nil {
|
||||
var oapiErr *oapierror.GenericOpenAPIError
|
||||
ok := errors.As(rolesErr, &oapiErr)
|
||||
|
|
@ -137,7 +137,7 @@ func CreateInstanceWaitHandler(
|
|||
|
||||
tflog.Info(ctx, "trying to get users")
|
||||
time.Sleep(10 * time.Second)
|
||||
_, usersErr := a.ListUsersRequest(ctx, projectId, region, instanceId).Execute()
|
||||
_, usersErr := a.ListUsersRequest(ctx, projectID, region, instanceID).Execute()
|
||||
if usersErr != nil {
|
||||
var oapiErr *oapierror.GenericOpenAPIError
|
||||
ok := errors.As(usersErr, &oapiErr)
|
||||
|
|
@ -162,13 +162,13 @@ func CreateInstanceWaitHandler(
|
|||
case strings.ToLower(InstanceStateUnknown):
|
||||
return true, nil, fmt.Errorf(
|
||||
"create failed for instance %s with status %s",
|
||||
instanceId,
|
||||
instanceID,
|
||||
InstanceStateUnknown,
|
||||
)
|
||||
case strings.ToLower(InstanceStateFailed):
|
||||
return true, nil, fmt.Errorf(
|
||||
"create failed for instance %s with status %s",
|
||||
instanceId,
|
||||
instanceID,
|
||||
InstanceStateFailed,
|
||||
)
|
||||
case strings.ToLower(InstanceStatePending), strings.ToLower(InstanceStateProcessing):
|
||||
|
|
@ -182,7 +182,7 @@ func CreateInstanceWaitHandler(
|
|||
default:
|
||||
tflog.Info(
|
||||
ctx, "Wait (create) received unknown status", map[string]interface{}{
|
||||
"instanceId": instanceId,
|
||||
"instanceId": instanceID,
|
||||
"status": s.Status,
|
||||
},
|
||||
)
|
||||
|
|
@ -197,22 +197,22 @@ func CreateInstanceWaitHandler(
|
|||
func UpdateInstanceWaitHandler(
|
||||
ctx context.Context,
|
||||
a APIClientInterface,
|
||||
projectId, instanceId, region string,
|
||||
projectID, instanceID, region string,
|
||||
) *wait.AsyncActionHandler[sqlserverflex.GetInstanceResponse] {
|
||||
handler := wait.New(
|
||||
func() (waitFinished bool, response *sqlserverflex.GetInstanceResponse, err error) {
|
||||
s, err := a.GetInstanceRequest(ctx, projectId, region, instanceId).Execute()
|
||||
s, err := a.GetInstanceRequest(ctx, projectID, region, instanceID).Execute()
|
||||
if err != nil {
|
||||
return false, nil, err
|
||||
}
|
||||
if s == nil || s.Id != instanceId {
|
||||
if s == nil || s.Id != instanceID {
|
||||
return false, nil, nil
|
||||
}
|
||||
switch strings.ToLower(string(s.Status)) {
|
||||
case strings.ToLower(InstanceStateSuccess):
|
||||
return true, s, nil
|
||||
case strings.ToLower(InstanceStateUnknown), strings.ToLower(InstanceStateFailed):
|
||||
return true, s, fmt.Errorf("update failed for instance with id %s", instanceId)
|
||||
return true, s, fmt.Errorf("update failed for instance with id %s", instanceID)
|
||||
case strings.ToLower(InstanceStatePending), strings.ToLower(InstanceStateProcessing):
|
||||
tflog.Info(
|
||||
ctx, "request is being handled", map[string]interface{}{
|
||||
|
|
@ -223,7 +223,7 @@ func UpdateInstanceWaitHandler(
|
|||
default:
|
||||
tflog.Info(
|
||||
ctx, "Wait (update) received unknown status", map[string]interface{}{
|
||||
"instanceId": instanceId,
|
||||
"instanceId": instanceID,
|
||||
"status": s.Status,
|
||||
},
|
||||
)
|
||||
|
|
@ -238,11 +238,11 @@ func UpdateInstanceWaitHandler(
|
|||
func DeleteInstanceWaitHandler(
|
||||
ctx context.Context,
|
||||
a APIClientInterface,
|
||||
projectId, instanceId, region string,
|
||||
projectID, instanceID, region string,
|
||||
) *wait.AsyncActionHandler[sqlserverflex.GetInstanceResponse] {
|
||||
handler := wait.New(
|
||||
func() (waitFinished bool, response *sqlserverflex.GetInstanceResponse, err error) {
|
||||
s, err := a.GetInstanceRequest(ctx, projectId, region, instanceId).Execute()
|
||||
s, err := a.GetInstanceRequest(ctx, projectID, region, instanceID).Execute()
|
||||
if err == nil {
|
||||
return false, s, nil
|
||||
}
|
||||
|
|
@ -265,11 +265,11 @@ func DeleteInstanceWaitHandler(
|
|||
func CreateDatabaseWaitHandler(
|
||||
ctx context.Context,
|
||||
a APIClientInterface,
|
||||
projectId, instanceId, region, databaseName string,
|
||||
projectID, instanceID, region, databaseName string,
|
||||
) *wait.AsyncActionHandler[sqlserverflex.GetDatabaseResponse] {
|
||||
handler := wait.New(
|
||||
func() (waitFinished bool, response *sqlserverflex.GetDatabaseResponse, err error) {
|
||||
s, err := a.GetDatabaseRequest(ctx, projectId, region, instanceId, databaseName).Execute()
|
||||
s, err := a.GetDatabaseRequest(ctx, projectID, region, instanceID, databaseName).Execute()
|
||||
if err != nil {
|
||||
var oapiErr *oapierror.GenericOpenAPIError
|
||||
ok := errors.As(err, &oapiErr)
|
||||
|
|
@ -297,12 +297,12 @@ func CreateDatabaseWaitHandler(
|
|||
func CreateUserWaitHandler(
|
||||
ctx context.Context,
|
||||
a APIClientInterface,
|
||||
projectId, instanceId, region string,
|
||||
userId int64,
|
||||
projectID, instanceID, region string,
|
||||
userID int64,
|
||||
) *wait.AsyncActionHandler[sqlserverflex.GetUserResponse] {
|
||||
handler := wait.New(
|
||||
func() (waitFinished bool, response *sqlserverflex.GetUserResponse, err error) {
|
||||
s, err := a.GetUserRequest(ctx, projectId, region, instanceId, userId).Execute()
|
||||
s, err := a.GetUserRequest(ctx, projectID, region, instanceID, userID).Execute()
|
||||
if err != nil {
|
||||
var oapiErr *oapierror.GenericOpenAPIError
|
||||
ok := errors.As(err, &oapiErr)
|
||||
|
|
@ -324,7 +324,7 @@ func CreateUserWaitHandler(
|
|||
func WaitForUserWaitHandler(
|
||||
ctx context.Context,
|
||||
a APIClientInterface,
|
||||
projectId, instanceId, region, userName string,
|
||||
projectID, instanceID, region, userName string,
|
||||
) *wait.AsyncActionHandler[sqlserverflex.ListUserResponse] {
|
||||
startTime := time.Now()
|
||||
timeOut := 2 * time.Minute
|
||||
|
|
@ -334,7 +334,7 @@ func WaitForUserWaitHandler(
|
|||
if time.Since(startTime) > timeOut {
|
||||
return false, nil, errors.New("ran into timeout")
|
||||
}
|
||||
s, err := a.ListUsersRequest(ctx, projectId, region, instanceId).Size(100).Execute()
|
||||
s, err := a.ListUsersRequest(ctx, projectID, region, instanceID).Size(100).Execute()
|
||||
if err != nil {
|
||||
var oapiErr *oapierror.GenericOpenAPIError
|
||||
ok := errors.As(err, &oapiErr)
|
||||
|
|
@ -376,12 +376,12 @@ func WaitForUserWaitHandler(
|
|||
func DeleteUserWaitHandler(
|
||||
ctx context.Context,
|
||||
a APIClientInterface,
|
||||
projectId, region, instanceId string,
|
||||
userId int64,
|
||||
projectID, region, instanceID string,
|
||||
userID int64,
|
||||
) *wait.AsyncActionHandler[struct{}] {
|
||||
handler := wait.New(
|
||||
func() (waitFinished bool, response *struct{}, err error) {
|
||||
_, err = a.GetUserRequest(ctx, projectId, region, instanceId, userId).Execute()
|
||||
_, err = a.GetUserRequest(ctx, projectID, region, instanceID, userID).Execute()
|
||||
if err == nil {
|
||||
return false, nil, nil
|
||||
}
|
||||
|
|
|
|||
838
tools/go.sum
Normal file
838
tools/go.sum
Normal file
|
|
@ -0,0 +1,838 @@
|
|||
4d63.com/gocheckcompilerdirectives v1.3.0/go.mod h1:ofsJ4zx2QAuIP/NO/NAh1ig6R1Fb18/GI7RVMwz7kAY=
|
||||
4d63.com/gochecknoglobals v0.2.2/go.mod h1:lLxwTQjL5eIesRbvnzIP3jZtG140FnTdz+AlMa+ogt0=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
|
||||
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
|
||||
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
|
||||
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
|
||||
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
|
||||
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
|
||||
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
|
||||
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
|
||||
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
|
||||
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
|
||||
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
|
||||
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
|
||||
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
|
||||
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
|
||||
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
|
||||
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
|
||||
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
|
||||
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
|
||||
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
|
||||
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
|
||||
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
|
||||
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
|
||||
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
codeberg.org/chavacava/garif v0.2.0/go.mod h1:P2BPbVbT4QcvLZrORc2T29szK3xEOlnl0GiPTJmEqBQ=
|
||||
codeberg.org/polyfloyd/go-errorlint v1.9.0/go.mod h1:GPRRu2LzVijNn4YkrZYJfatQIdS+TrcK8rL5Xs24qw8=
|
||||
dev.gaijin.team/go/exhaustruct/v4 v4.0.0/go.mod h1:aZ/k2o4Y05aMJtiux15x8iXaumE88YdiB0Ai4fXOzPI=
|
||||
dev.gaijin.team/go/golib v0.6.0/go.mod h1:uY1mShx8Z/aNHWDyAkZTkX+uCi5PdX7KsG1eDQa2AVE=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/4meepo/tagalign v1.4.3/go.mod h1:00WwRjiuSbrRJnSVeGWPLp2epS5Q/l4UEy0apLLS37c=
|
||||
github.com/Abirdcfly/dupword v0.1.7/go.mod h1:K0DkBeOebJ4VyOICFdppB23Q0YMOgVafM0zYW0n9lF4=
|
||||
github.com/AdminBenni/iota-mixing v1.0.0/go.mod h1:i4+tpAaB+qMVIV9OK3m4/DAynOd5bQFaOu+2AhtBCNY=
|
||||
github.com/AlwxSin/noinlineerr v1.0.5/go.mod h1:+QgkkoYrMH7RHvcdxdlI7vYYEdgeoFOVjU9sUhw/rQc=
|
||||
github.com/Antonboom/errname v1.1.1/go.mod h1:gjhe24xoxXp0ScLtHzjiXp0Exi1RFLKJb0bVBtWKCWQ=
|
||||
github.com/Antonboom/nilnil v1.1.1/go.mod h1:yCyAmSw3doopbOWhJlVci+HuyNRuHJKIv6V2oYQa8II=
|
||||
github.com/Antonboom/testifylint v1.6.4/go.mod h1:YO33FROXX2OoUfwjz8g+gUxQXio5i9qpVy7nXGbxDD4=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Djarvur/go-err113 v0.1.1/go.mod h1:IaWJdYFLg76t2ihfflPZnM1LIQszWOsFDh2hhhAVF6k=
|
||||
github.com/Kunde21/markdownfmt/v3 v3.1.0/go.mod h1:tPXN1RTyOzJwhfHoon9wUr4HGYmWgVxSQN6VBJDkrVc=
|
||||
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||
github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
|
||||
github.com/MirrexOne/unqueryvet v1.5.3/go.mod h1:fs9Zq6eh1LRIhsDIsxf9PONVUjYdFHdtkHIgZdJnyPU=
|
||||
github.com/OpenPeeDeeP/depguard/v2 v2.2.1/go.mod h1:q4DKzC4UcVaAvcfd41CZh0PWpGgzrVxUYBlgKNGquUo=
|
||||
github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
|
||||
github.com/alecthomas/chroma/v2 v2.23.1/go.mod h1:NqVhfBR0lte5Ouh3DcthuUCTUpDC9cxBOfyMbMQPs3o=
|
||||
github.com/alecthomas/go-check-sumtype v0.3.1/go.mod h1:A8TSiN3UPRw3laIgWEUOHHLPa6/r9MtoigdlP5h3K/E=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
|
||||
github.com/alexkohler/nakedret/v2 v2.0.6/go.mod h1:l3RKju/IzOMQHmsEvXwkqMDzHHvurNQfAgE1eVmT40Q=
|
||||
github.com/alexkohler/prealloc v1.0.2/go.mod h1:fT39Jge3bQrfA7nPMDngUfvUbQGQeJyGQnR+913SCig=
|
||||
github.com/alfatraining/structtag v1.0.0/go.mod h1:p3Xi5SwzTi+Ryj64DqjLWz7XurHxbGsq6y3ubePJPus=
|
||||
github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I=
|
||||
github.com/alingse/nilnesserr v0.2.0/go.mod h1:1xJPrXonEtX7wyTq8Dytns5P2hNzoWymVUIaKm4HNFg=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
|
||||
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/ashanbrown/forbidigo/v2 v2.3.0/go.mod h1:5p6VmsG5/1xx3E785W9fouMxIOkvY2rRV9nMdWadd6c=
|
||||
github.com/ashanbrown/makezero/v2 v2.1.0/go.mod h1:aEGT/9q3S8DHeE57C88z2a6xydvgx8J5hgXIGWgo0MY=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||
github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/bkielbasa/cyclop v1.2.3/go.mod h1:kHTwA9Q0uZqOADdupvcFJQtp/ksSnytRMe8ztxG8Fuo=
|
||||
github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k=
|
||||
github.com/bmatcuk/doublestar/v4 v4.9.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||
github.com/bombsimon/wsl/v4 v4.7.0/go.mod h1:uV/+6BkffuzSAVYD+yGyld1AChO7/EuLrCF/8xTiapg=
|
||||
github.com/bombsimon/wsl/v5 v5.6.0/go.mod h1:Uqt2EfrMj2NV8UGoN1f1Y3m0NpUVCsUdrNCdet+8LvU=
|
||||
github.com/breml/bidichk v0.3.3/go.mod h1:ISbsut8OnjB367j5NseXEGGgO/th206dVa427kR8YTE=
|
||||
github.com/breml/errchkjson v0.4.1/go.mod h1:a23OvR6Qvcl7DG/Z4o0el6BRAjKnaReoPQFciAl9U3s=
|
||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
|
||||
github.com/butuzov/ireturn v0.4.0/go.mod h1:ghI0FrCmap8pDWZwfPisFD1vEc56VKH4NpQUxDHta70=
|
||||
github.com/butuzov/mirror v1.3.0/go.mod h1:AEij0Z8YMALaq4yQj9CPPVYOyJQyiexpQEQgihajRfI=
|
||||
github.com/catenacyber/perfsprint v0.10.1/go.mod h1:DJTGsi/Zufpuus6XPGJyKOTMELe347o6akPvWG9Zcsc=
|
||||
github.com/ccojocar/zxcvbn-go v1.0.4/go.mod h1:3GxGX+rHmueTUMvm5ium7irpyjmm7ikxYFOSJB21Das=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/charithe/durationcheck v0.0.11/go.mod h1:x5iZaixRNl8ctbM+3B2RrPG5t856TxRyVQEnbIEM2X4=
|
||||
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
|
||||
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
|
||||
github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=
|
||||
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
|
||||
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/ckaznocha/intrange v0.3.1/go.mod h1:QVepyz1AkUoFQkpEqksSYpNpUo3c5W7nWh/s6SHIJJk=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/curioswitch/go-reassign v0.3.0/go.mod h1:nApPCCTtqLJN/s8HfItCcKV0jIPwluBOvZP+dsJGA88=
|
||||
github.com/daixiang0/gci v0.13.7/go.mod h1:812WVN6JLFY9S6Tv76twqmNqevN0pa3SX3nih0brVzQ=
|
||||
github.com/dave/dst v0.27.3/go.mod h1:jHh6EOibnHgcUW3WjKHisiooEkYwqpHLBSX1iOBhEyc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/denis-tingaikin/go-header v0.5.0/go.mod h1:mMenU5bWrok6Wl2UsZjy+1okegmwQ3UgWl4V1D8gjlY=
|
||||
github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/dprotaso/go-yit v0.0.0-20191028211022-135eb7262960/go.mod h1:9HQzr9D/0PGwMEbC3d5AB7oi67+h4TsQqItC1GVYG58=
|
||||
github.com/dprotaso/go-yit v0.0.0-20220510233725-9ba8df137936/go.mod h1:ttYvX5qlB+mlV1okblJqcSMtR4c52UKxDiX9GRBS8+Q=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/ettle/strcase v0.2.0/go.mod h1:DajmHElDSaX76ITe3/VHVyMin4LWSJN5Z909Wp+ED1A=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
|
||||
github.com/firefart/nonamedreturns v1.0.6/go.mod h1:R8NisJnSIpvPWheCq0mNRXJok6D8h7fagJTF8EMEwCo=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
|
||||
github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA=
|
||||
github.com/ghostiam/protogetter v0.3.20/go.mod h1:FjIu5Yfs6FT391m+Fjp3fbAYJ6rkL/J6ySpZBfnODuI=
|
||||
github.com/go-critic/go-critic v0.14.3/go.mod h1:xwntfW6SYAd7h1OqDzmN6hBX/JxsEKl5up/Y2bsxgVQ=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU=
|
||||
github.com/go-toolsmith/astcopy v1.1.0/go.mod h1:hXM6gan18VA1T/daUEHCFcYiW8Ai1tIwIzHY6srfEAw=
|
||||
github.com/go-toolsmith/astequal v1.0.3/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4=
|
||||
github.com/go-toolsmith/astequal v1.1.0/go.mod h1:sedf7VIdCL22LD8qIvv7Nn9MuWJruQA/ysswh64lffQ=
|
||||
github.com/go-toolsmith/astequal v1.2.0/go.mod h1:c8NZ3+kSFtFY/8lPso4v8LuJjdJiUFVnSuU3s0qrrDY=
|
||||
github.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlNMV634mhwuQ4=
|
||||
github.com/go-toolsmith/astp v1.1.0/go.mod h1:0T1xFGz9hicKs8Z5MfAqSUitoUYS30pDMsRVIDHs8CA=
|
||||
github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=
|
||||
github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ=
|
||||
github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig=
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/go-xmlfmt/xmlfmt v1.1.3/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
|
||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
github.com/godoc-lint/godoc-lint v0.11.2/go.mod h1:iVpGdL1JCikNH2gGeAn3Hh+AgN5Gx/I/cxV+91L41jo=
|
||||
github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
|
||||
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
|
||||
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
|
||||
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golangci/asciicheck v0.5.0/go.mod h1:5RMNAInbNFw2krqN6ibBxN/zfRFa9S6tA1nPdM0l8qQ=
|
||||
github.com/golangci/dupl v0.0.0-20250308024227-f665c8d69b32/go.mod h1:NUw9Zr2Sy7+HxzdjIULge71wI6yEg1lWQr7Evcu8K0E=
|
||||
github.com/golangci/go-printf-func-name v0.1.1/go.mod h1:Es64MpWEZbh0UBtTAICOZiB+miW53w/K9Or/4QogJss=
|
||||
github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d/go.mod h1:ivJ9QDg0XucIkmwhzCDsqcnxxlDStoTl89jDMIoNxKY=
|
||||
github.com/golangci/golangci-lint/v2 v2.10.1/go.mod h1:dBsrOk6zj0vDhlTv+IiJGqkDokR24IVTS7W3EVfPTQY=
|
||||
github.com/golangci/golines v0.15.0/go.mod h1:AZjXd23tbHMpowhtnGlj9KCNsysj72aeZVVHnVcZx10=
|
||||
github.com/golangci/misspell v0.8.0/go.mod h1:WZyyI2P3hxPY2UVHs3cS8YcllAeyfquQcKfdeE9AFVg=
|
||||
github.com/golangci/plugin-module-register v0.1.2/go.mod h1:1+QGTsKBvAIvPvoY/os+G5eoqxWn70HYDm2uvUyGuVw=
|
||||
github.com/golangci/revgrep v0.8.0/go.mod h1:U4R/s9dlXZsg8uJmaR1GrloUr14D7qDl8gi2iPXJH8k=
|
||||
github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e/go.mod h1:Vrn4B5oR9qRwM+f54koyeH3yzphlecwERs0el27Fr/s=
|
||||
github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e/go.mod h1:h+wZwLjUTJnm/P2rwlbJdRPZXOzaT36/FwnPnY2inzc=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/gordonklaus/ineffassign v0.2.0/go.mod h1:TIpymnagPSexySzs7F9FnO1XFTy8IT3a59vmZp5Y9Lw=
|
||||
github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc=
|
||||
github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM=
|
||||
github.com/gostaticanalysis/comment v1.5.0/go.mod h1:V6eb3gpCv9GNVqb6amXzEUX3jXLVK/AdA+IrAMSqvEc=
|
||||
github.com/gostaticanalysis/forcetypeassert v0.2.0/go.mod h1:M5iPavzE9pPqWyeiVXSFghQjljW1+l/Uke3PXHS6ILY=
|
||||
github.com/gostaticanalysis/nilerr v0.1.2/go.mod h1:A19UHhoY3y8ahoL7YKz6sdjDtduwTSI4CsymaC2htPA=
|
||||
github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M=
|
||||
github.com/hashicorp/cli v1.1.7/go.mod h1:e6Mfpga9OCT1vqzFuoGZiiF/KaG9CbUfO5s3ghU3YgU=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||
github.com/hashicorp/go-immutable-radix/v2 v2.1.0/go.mod h1:hgdqLXA4f6NIjRVisM1TJ9aOJVNRqKZj+xDGF6m7PBw=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
|
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/hashicorp/hc-install v0.9.2/go.mod h1:XUqBQNnuT4RsxoxiM9ZaUk0NX8hi2h+Lb6/c0OZnC/I=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/terraform-exec v0.24.0/go.mod h1:lluc/rDYfAhYdslLJQg3J0oDqo88oGQAdHR+wDqFvo4=
|
||||
github.com/hashicorp/terraform-json v0.27.2/go.mod h1:GzPLJ1PLdUG5xL6xn1OXWIjteQRT2CNT9o/6A9mi9hE=
|
||||
github.com/hashicorp/terraform-plugin-codegen-framework v0.4.1/go.mod h1:kpYM23L7NtcfaQdWAN0QFkV/lU0w16qJ2ddAPCI4zAg=
|
||||
github.com/hashicorp/terraform-plugin-codegen-openapi v0.3.0/go.mod h1:tT6wl80h7nsMBw+1yZRgJXi+Ys85PUai11weDqysvp4=
|
||||
github.com/hashicorp/terraform-plugin-codegen-spec v0.2.0/go.mod h1:fywrEKpordQypmAjz/HIfm2LuNVmyJ6KDe8XT9GdJxQ=
|
||||
github.com/hashicorp/terraform-plugin-docs v0.24.0/go.mod h1:YLg+7LEwVmRuJc0EuCw0SPLxuQXw5mW8iJ5ml/kvi+o=
|
||||
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jgautheron/goconst v1.8.2/go.mod h1:A0oxgBCHy55NQn6sYpO7UdnA9p+h7cPtoOZUmvNIako=
|
||||
github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c=
|
||||
github.com/jjti/go-spancheck v0.6.5/go.mod h1:aEogkeatBrbYsyW6y5TgDfihCulDYciL1B7rG2vSsrU=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/julz/importas v0.2.0/go.mod h1:pThlt589EnCYtMnmhmRYY/qn9lCf/frPOK+WMx3xiJY=
|
||||
github.com/karamaru-alpha/copyloopvar v1.2.2/go.mod h1:oY4rGZqZ879JkJMtX3RRkcXRkmUvH0x35ykgaKgsgJY=
|
||||
github.com/kisielk/errcheck v1.9.0/go.mod h1:kQxWMMVZgIkDq7U8xtG/n2juOjbLgZtedi0D+/VL/i8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kkHAIKE/contextcheck v1.1.6/go.mod h1:3dDbMRNBFaq8HFXWC1JyvDSPm43CmE6IuHam8Wr0rkg=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kulti/thelper v0.7.1/go.mod h1:NsMjfQEy6sd+9Kfw8kCP61W1I0nerGSYSFnGaxQkcbs=
|
||||
github.com/kunwardeep/paralleltest v1.0.15/go.mod h1:di4moFqtfz3ToSKxhNjhOZL+696QtJGCFe132CbBLGk=
|
||||
github.com/lasiar/canonicalheader v1.1.2/go.mod h1:qJCeLFS0G/QlLQ506T+Fk/fWMa2VmBUiEI2cuMK4djI=
|
||||
github.com/ldez/exptostd v0.4.5/go.mod h1:QRjHRMXJrCTIm9WxVNH6VW7oN7KrGSht69bIRwvdFsM=
|
||||
github.com/ldez/gomoddirectives v0.8.0/go.mod h1:jutzamvZR4XYJLr0d5Honycp4Gy6GEg2mS9+2YX3F1Q=
|
||||
github.com/ldez/grignotin v0.10.1/go.mod h1:UlDbXFCARrXbWGNGP3S5vsysNXAPhnSuBufpTEbwOas=
|
||||
github.com/ldez/structtags v0.6.1/go.mod h1:YDxVSgDy/MON6ariaxLF2X09bh19qL7MtGBN5MrvbdY=
|
||||
github.com/ldez/tagliatelle v0.7.2/go.mod h1:PtGgm163ZplJfZMZ2sf5nhUT170rSuPgBimoyYtdaSI=
|
||||
github.com/ldez/usetesting v0.5.0/go.mod h1:Spnb4Qppf8JTuRgblLrEWb7IE6rDmUpGvxY3iRrzvDQ=
|
||||
github.com/leonklingele/grouper v1.1.2/go.mod h1:6D0M/HVkhs2yRKRFZUoGjeDy7EZTfFBE9gl4kjmIGkA=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/macabu/inamedparam v0.2.0/go.mod h1:+Pee9/YfGe5LJ62pYXqB89lJ+0k5bsR8Wgz/C0Zlq3U=
|
||||
github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/manuelarte/embeddedstructfieldcheck v0.4.0/go.mod h1:z8dFSyXqp+fC6NLDSljRJeNQJJDWnY7RoWFzV3PC6UM=
|
||||
github.com/manuelarte/funcorder v0.5.0/go.mod h1:Yt3CiUQthSBMBxjShjdXMexmzpP8YGvGLjrxJNkO2hA=
|
||||
github.com/maratori/testableexamples v1.0.1/go.mod h1:XE2F/nQs7B9N08JgyRmdGjYVGqxWwClLPCGSQhXQSrQ=
|
||||
github.com/maratori/testpackage v1.1.2/go.mod h1:8F24GdVDFW5Ew43Et02jamrVMNXLUNaOynhDssITGfc=
|
||||
github.com/matoous/godox v1.1.0/go.mod h1:jgE/3fUXiTurkdHOLT5WEkThTSuE7yxHv5iWPa80afs=
|
||||
github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mgechev/revive v1.14.0/go.mod h1:MvnujelCZBZCaoDv5B3foPo6WWgULSSFxvfxp7GsPfo=
|
||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/moricho/tparallel v0.3.2/go.mod h1:OQ+K3b4Ln3l2TZveGCywybl68glfLEwFGqvnjok8b+U=
|
||||
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE=
|
||||
github.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs=
|
||||
github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c=
|
||||
github.com/nunnatsa/ginkgolinter v0.23.0/go.mod h1:9qN1+0akwXEccwV1CAcCDfcoBlWXHB+ML9884pL4SZ4=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.10.2/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
|
||||
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
|
||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
|
||||
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
|
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
|
||||
github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw=
|
||||
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
|
||||
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
|
||||
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
|
||||
github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
|
||||
github.com/pb33f/libopenapi v0.15.0/go.mod h1:m+4Pwri31UvcnZjuP8M7TlbR906DXJmMvYsbis234xg=
|
||||
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
|
||||
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
|
||||
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/quasilyte/go-ruleguard v0.4.5/go.mod h1:Vl05zJ538vcEEwu16V/Hdu7IYZWyKSwIy4c88Ro1kRE=
|
||||
github.com/quasilyte/go-ruleguard/dsl v0.3.23/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
|
||||
github.com/quasilyte/gogrep v0.5.0/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng=
|
||||
github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0=
|
||||
github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ=
|
||||
github.com/raeperd/recvcheck v0.2.0/go.mod h1:n04eYkwIR0JbgD73wT8wL4JjPC3wm0nFtzBnWNocnYU=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryancurrah/gomodguard v1.4.1/go.mod h1:qnMJwV1hX9m+YJseXEBhd2s90+1Xn6x9dLz11ualI1I=
|
||||
github.com/ryanrolds/sqlclosecheck v0.5.1/go.mod h1:2g3dUjoS6AL4huFdv6wn55WpLIDjY7ZgUR4J8HOO/XQ=
|
||||
github.com/sanposhiho/wastedassign/v2 v2.1.0/go.mod h1:+oSmSC+9bQ+VUAxA66nBb0Z7N8CK7mscKTDYC6aIek4=
|
||||
github.com/santhosh-tekuri/jsonschema/v6 v6.0.2/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
|
||||
github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ=
|
||||
github.com/sashamelentyev/usestdlibvars v1.29.0/go.mod h1:8PpnjHMk5VdeWlVb4wCdrB8PNbLqZ3wBZTZWkrpZZL8=
|
||||
github.com/securego/gosec/v2 v2.23.0/go.mod h1:qRHEgXLFuYUDkI2T7W7NJAmOkxVhkR0x9xyHOIcMNZ0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
|
||||
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||
github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
|
||||
github.com/sivchari/containedctx v1.0.3/go.mod h1:c1RDvCbnJLtH4lLcYD/GqwiBSSf4F5Qk0xld2rBqzJ4=
|
||||
github.com/sonatard/noctx v0.4.0/go.mod h1:64XdbzFb18XL4LporKXp8poqZtPKbCrqQ402CV+kJas=
|
||||
github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs=
|
||||
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48=
|
||||
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI=
|
||||
github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I=
|
||||
github.com/stbenjam/no-sprintf-host-port v0.3.1/go.mod h1:ODbZesTCHMVKthBHskvUUexdcNHAQRXk9NpSsL8p/HQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
|
||||
github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0=
|
||||
github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY=
|
||||
github.com/tetafro/godot v1.5.4/go.mod h1:eOkMrVQurDui411nBY2FA05EYH01r14LuWY/NrVDVcU=
|
||||
github.com/timakin/bodyclose v0.0.0-20241222091800-1db5c5ca4d67/go.mod h1:mkjARE7Yr8qU23YcGMSALbIxTQ9r9QBVahQOBRfU460=
|
||||
github.com/timonwong/loggercheck v0.11.0/go.mod h1:HEAWU8djynujaAVX7QI65Myb8qgfcZ1uKbdpg3ZzKl8=
|
||||
github.com/tomarrell/wrapcheck/v2 v2.12.0/go.mod h1:AQhQuZd0p7b6rfW+vUwHm5OMCGgp63moQ9Qr/0BpIWo=
|
||||
github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw=
|
||||
github.com/ultraware/funlen v0.2.0/go.mod h1:ZE0q4TsJ8T1SQcjmkhN/w+MceuatI6pBFSxxyteHIJA=
|
||||
github.com/ultraware/whitespace v0.2.0/go.mod h1:XcP1RLD81eV4BW8UhQlpaR+SDc2givTvyI8a586WjW8=
|
||||
github.com/uudashr/gocognit v1.2.0/go.mod h1:k/DdKPI6XBZO1q7HgoV2juESI2/Ofj9AcHPZhBBdrTU=
|
||||
github.com/uudashr/iface v1.4.1/go.mod h1:pbeBPlbuU2qkNDn0mmfrxP2X+wjPMIQAy+r1MBXSXtg=
|
||||
github.com/vmware-labs/yaml-jsonpath v0.3.2/go.mod h1:U6whw1z03QyqgWdgXxvVnQ90zN1BWz5V+51Ewf8k+rQ=
|
||||
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||
github.com/xen0n/gosmopolitan v1.3.0/go.mod h1:rckfr5T6o4lBtM1ga7mLGKZmLxswUoH1zxHgNXOsEt4=
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
|
||||
github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk=
|
||||
github.com/yeya24/promlinter v0.3.0/go.mod h1:cDfJQQYv9uYciW60QT0eeHlFodotkYZlL+YcPQN+mW4=
|
||||
github.com/ykadowak/zerologlint v0.1.5/go.mod h1:KaUskqF3e/v59oPmdq1U1DnKcuHokl2/K1U4pmIELKg=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yuin/goldmark v1.7.7/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
|
||||
github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0=
|
||||
github.com/zclconf/go-cty v1.17.0/go.mod h1:wqFzcImaLTI6A5HfsRwB0nj5n0MRZFwmey8YoFPPs3U=
|
||||
gitlab.com/bosi/decorder v0.4.2/go.mod h1:muuhHoaJkA9QLcYHq4Mj8FJUwDZ+EirSHRiaTcTf6T8=
|
||||
go-simpler.org/musttag v0.14.0/go.mod h1:uP8EymctQjJ4Z1kUnjX0u2l60WfUdQxCwSNKzE1JEOE=
|
||||
go-simpler.org/sloglint v0.11.1/go.mod h1:2PowwiCOK8mjiF+0KGifVOT8ZsCNiFzvfyJeJOIt8MQ=
|
||||
go.abhg.dev/goldmark/frontmatter v0.2.0/go.mod h1:XqrEkZuM57djk7zrlRUB02x8I5J0px76YjkOzhB4YlU=
|
||||
go.augendre.info/arangolint v0.4.0/go.mod h1:l+f/b4plABuFISuKnTGD4RioXiCCgghv2xqst/xOvAA=
|
||||
go.augendre.info/fatcontext v0.9.0/go.mod h1:L94brOAT1OOUNue6ph/2HnwxoNlds9aXDF2FcUntbNw=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
|
||||
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
|
||||
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8=
|
||||
golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
||||
golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
|
||||
golang.org/x/exp/typeparams v0.0.0-20260209203927-2842357ff358/go.mod h1:4Mzdyp/6jzw9auFDJ3OMF5qksa7UvPnzKqTVGcb04ms=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
|
||||
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
|
||||
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4/go.mod h1:g5NllXBEermZrmR51cJDQxmJUHUOfRAaNyWBM+R+548=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
|
||||
golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
|
||||
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
|
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU=
|
||||
golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU=
|
||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
|
||||
golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
|
||||
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
|
||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
|
||||
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
|
||||
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
|
||||
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
|
||||
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
|
||||
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
|
||||
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
|
||||
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
|
||||
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
|
||||
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
|
||||
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
|
||||
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
|
||||
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20191026110619-0b21df46bc1d/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.7.0/go.mod h1:pm29oPxeP3P82ISxZDgIYeOaf9ta6Pi0EWvCFoLG2vc=
|
||||
mvdan.cc/gofumpt v0.9.2/go.mod h1:iB7Hn+ai8lPvofHd9ZFGVg2GOr8sBUw1QUWjNbmIL/s=
|
||||
mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15/go.mod h1:4M5MMXl2kW6fivUT6yRGpLLPNfuGtU2Z0cPvFquGDYU=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
Loading…
Add table
Add a link
Reference in a new issue