diff --git a/.changes/.gitkeep b/.changes/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/.changes/.template.md b/.changes/.template.md new file mode 100644 index 0000000..acc2086 --- /dev/null +++ b/.changes/.template.md @@ -0,0 +1,6 @@ + +FEATURES: + +ENHANCEMENTS: + +BUG FIXES: diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index f8cc70e..75cc7cd 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -1,15 +1,16 @@ name: Go Tests on: [push, pull_request] jobs: - build-1_20: - name: Build 1.20 + build-1_22: + name: Build 1.22 runs-on: ubuntu-latest steps: - - name: Set up Go 1.20 + - name: Set up Go 1.22 uses: actions/setup-go@v5 with: - go-version: '1.20' + go-version: '1.22' check-latest: true + cache: false id: go - name: Disable cgo run: | @@ -21,15 +22,16 @@ jobs: - name: Build run: go build -v . - build-1_21: - name: Build 1.21 + build-1_23: + name: Build 1.23 runs-on: ubuntu-latest steps: - - name: Set up Go 1.21 + - name: Set up Go 1.23 uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version: '1.23' check-latest: true + cache: false id: go - name: Disable cgo run: | @@ -45,11 +47,12 @@ jobs: name: Test runs-on: ubuntu-latest steps: - - name: Set up Go 1.21 + - name: Set up Go 1.23 uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version: '1.23' check-latest: true + cache: false id: go - name: Disable cgo run: | diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index 4fb091a..5ef8bd9 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -5,10 +5,10 @@ jobs: name: golangci-lint runs-on: ubuntu-latest steps: - - name: Set up Go 1.21 + - name: Set up Go 1.23 uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version: '1.23' check-latest: true id: go - name: Disable cgo @@ -17,10 +17,11 @@ jobs: - name: Check out code uses: actions/checkout@v4 - name: golangci-lint - uses: golangci/golangci-lint-action@v4 + uses: golangci/golangci-lint-action@v6 with: - version: v1.54 + version: v1.61.0 args: -c .golangci.yml -v + skip-cache: true markdown-lint: name: markdown-lint @@ -38,11 +39,12 @@ jobs: name: terrafmt runs-on: ubuntu-latest steps: - - name: Set up Go 1.21 + - name: Set up Go 1.23 uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version: '1.23' check-latest: true + skip-cache: true id: go - name: Show version run: go version @@ -54,6 +56,7 @@ jobs: repository: katbyte/terrafmt ref: v0.5.2 path: terrafmt + skip-cache: true - name: Build terrafmt bin run: cd terrafmt && go install ./... && cd ${GITHUB_WORKSPACE} - name: Detect resource/data-source blocks without double quote on type and name (blocks not detected by terrafmt) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3784d32..8868381 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,20 +19,20 @@ jobs: name: Set up Go uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version: '1.23' - name: Import GPG key - uses: crazy-max/ghaction-import-gpg@v6.1.0 + uses: crazy-max/ghaction-import-gpg@v6.2.0 id: import_gpg with: gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} passphrase: ${{ secrets.PASSPHRASE }} - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v5.0.0 + uses: goreleaser/goreleaser-action@v6.0.0 with: version: latest - args: release --rm-dist + args: release --clean env: GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} # GitHub sets this automatically diff --git a/.golangci.yml b/.golangci.yml index 7ce9f6b..7b8accb 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,34 +1,36 @@ run: timeout: 5m + linters: enable-all: true disable: - # maligned # deprecated 1.38.0 but govet-fieldalignment not usuable - - interfacer # deprecated 1.38.0 - - scopelint # deprecated 1.39.0 - - golint # deprecated 1.41.0 - - exhaustivestruct # deprecated 1.46.0 - # ifshort # deprecated 1.48.0 but no replacement - - nosnakecase # deprecated 1.48.1 - - deadcode # deprecated 1.49.0 - - structcheck # deprecated 1.49.0 - - varcheck # deprecated 1.49.0 - - funlen + # deprecated + - execinquery # deprecated 1.58.0 + - gomnd # deprecated 1.58.0 + - exportloopref # deprecated 1.60.2 + # unwanted + - cyclop + - depguard - dupl - - wsl - - gomnd - - goerr113 - - nestif + - err113 - exhaustruct - - paralleltest - - gci - - cyclop - forcetypeassert - - tagliatelle + - funlen - gomoddirectives + - mnd + - nestif + - paralleltest + - tagliatelle - varnamelen - - depguard + - wsl + linters-settings: + gci: + custom-order: true + sections: + - standard + - localModule + - default govet: enable-all: true disable: @@ -39,4 +41,3 @@ linters-settings: gocyclo: # minimal code complexity to report, 30 by default min-complexity: 30 - \ No newline at end of file diff --git a/.goreleaser.yml b/.goreleaser.yml index 1d991a2..ac61f28 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,3 +1,4 @@ +version: 2 before: hooks: - go mod tidy @@ -40,4 +41,4 @@ signs: release: draft: true changelog: - skip: true + disable: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 807bcbc..eec01e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,32 @@ # changelog +## 0.14.0 (November 08, 2024) + +BREAKING CHANGES: + +* remove compatibility with API version 3.3 and 3.6 +* remove resource `wallix-bastion_ldapdomain` +* remove resource `wallix-bastion_ldapmapping` +* default provider api_version argument is now `v3.8` +* user statement is now mandatory + +FEATURES: + +* add compatibility with API version 3.12 + +ENHANCEMENTS: + +* **resource/wallix-bastion_application**: + * add `category`, `application_url`, `browser`, `browser_version` arguments to be able to add `jumphost` application (not tested) + * `paths` and `target` is now only required when `category` = `standard` +* **resource/wallix-bastion_connection_policy**: add `type` argument with default value as `protocol` value +* **resource/wallix-bastion_externalauth_saml**: add `claim_customization` block argument + +## 0.13.0 (March 08, 2024) + +* build(deps): bump github.com/cloudflare/circl from 1.3.3 to 1.3.7 by @dependabot in https://github.com/wallix/terraform-provider-wallix-bastion/pull/13 +* added http basic authentication by @moulip in https://github.com/wallix/terraform-provider-wallix-bastion/pull/15 + ## 0.12.2 (January 03, 2024) * Corrected and added documentation example diff --git a/README.md b/README.md index 282f61d..c6e1784 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ ### In addition to develop -- [Go](https://golang.org/doc/install) `v1.20` or `v1.21` +- [Go](https://golang.org/doc/install) `v1.22` or `v1.23` ### Special Thanks diff --git a/bastion/data_source_configoption.go b/bastion/data_source_configoption.go index 771b007..2cc638d 100644 --- a/bastion/data_source_configoption.go +++ b/bastion/data_source_configoption.go @@ -5,12 +5,12 @@ import ( "encoding/json" "fmt" "net/http" + "slices" + "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - balt "github.com/jeremmfr/go-utils/basicalter" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonConfigOptions struct { @@ -57,7 +57,7 @@ func dataSourceConfigoption() *schema.Resource { } func dataSourceConfigoptionVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -94,7 +94,7 @@ func readConfigoption( for _, v := range optionsList { params += v.(string) + "," } - _ = balt.CutPrefixInString(¶ms, ",") + params = strings.TrimSuffix(params, ",") } body, code, err := c.newRequest(ctx, "/configoptions/"+d.Get("config_id").(string)+params, http.MethodGet, nil) if err != nil { diff --git a/bastion/data_source_configoption_test.go b/bastion/data_source_configoption_test.go index bda6207..e9f241d 100644 --- a/bastion/data_source_configoption_test.go +++ b/bastion/data_source_configoption_test.go @@ -2,7 +2,7 @@ package bastion_test import ( "encoding/json" - "fmt" + "errors" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" @@ -30,7 +30,7 @@ func TestAccDataSourceConfigoption_basic(t *testing.T) { return err } if jsonData["name"].(string) != "one_time_password_ttl" { - return fmt.Errorf("can't find name=one_time_password_ttl in json") + return errors.New("can't find name=one_time_password_ttl in json") } return nil diff --git a/bastion/data_source_domain.go b/bastion/data_source_domain.go index b25311c..8f736c7 100644 --- a/bastion/data_source_domain.go +++ b/bastion/data_source_domain.go @@ -3,10 +3,10 @@ package bastion import ( "context" "fmt" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) func dataSourceDomain() *schema.Resource { @@ -54,7 +54,7 @@ func dataSourceDomain() *schema.Resource { } func dataSourceDomainVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } diff --git a/bastion/data_source_local_password_policy.go b/bastion/data_source_local_password_policy.go index 5cab8ec..ece50a3 100644 --- a/bastion/data_source_local_password_policy.go +++ b/bastion/data_source_local_password_policy.go @@ -5,10 +5,10 @@ import ( "encoding/json" "fmt" "net/http" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonLocalPasswordPolicy struct { @@ -97,7 +97,7 @@ func dataSourceLocalPasswordPolicy() *schema.Resource { } func dataSourceLocalPasswordPolicyVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } diff --git a/bastion/provider.go b/bastion/provider.go index 8a99c23..229ed4b 100644 --- a/bastion/provider.go +++ b/bastion/provider.go @@ -8,16 +8,14 @@ import ( ) const ( - VersionWallixAPI33 = "v3.3" - VersionWallixAPI36 = "v3.6" - VersionWallixAPI38 = "v3.8" + VersionWallixAPI38 = "v3.8" + VersionWallixAPI312 = "v3.12" ) func defaultVersionsValid() []string { return []string{ - VersionWallixAPI33, - VersionWallixAPI36, VersionWallixAPI38, + VersionWallixAPI312, } } @@ -30,6 +28,11 @@ func Provider() *schema.Provider { Required: true, DefaultFunc: schema.EnvDefaultFunc("WALLIX_BASTION_HOST", nil), }, + "user": { + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("WALLIX_BASTION_USER", nil), + }, "port": { Type: schema.TypeInt, Optional: true, @@ -40,11 +43,6 @@ func Provider() *schema.Provider { Optional: true, DefaultFunc: schema.EnvDefaultFunc("WALLIX_BASTION_TOKEN", nil), }, - "user": { - Type: schema.TypeString, - Optional: true, - DefaultFunc: schema.EnvDefaultFunc("WALLIX_BASTION_USER", nil), - }, "password": { Type: schema.TypeString, Optional: true, @@ -53,7 +51,7 @@ func Provider() *schema.Provider { "api_version": { Type: schema.TypeString, Optional: true, - DefaultFunc: schema.EnvDefaultFunc("WALLIX_BASTION_API_VERSION", VersionWallixAPI33), + DefaultFunc: schema.EnvDefaultFunc("WALLIX_BASTION_API_VERSION", VersionWallixAPI38), }, }, DataSourcesMap: map[string]*schema.Resource{ @@ -88,8 +86,6 @@ func Provider() *schema.Provider { "wallix-bastion_externalauth_radius": resourceExternalAuthRadius(), "wallix-bastion_externalauth_saml": resourceExternalAuthSaml(), "wallix-bastion_externalauth_tacacs": resourceExternalAuthTacacs(), - "wallix-bastion_ldapdomain": resourceLdapDomain(), - "wallix-bastion_ldapmapping": resourceLdapMapping(), "wallix-bastion_profile": resourceProfile(), "wallix-bastion_targetgroup": resourceTargetGroup(), "wallix-bastion_timeframe": resourceTimeframe(), diff --git a/bastion/provider_test.go b/bastion/provider_test.go index 763758e..54f2df2 100644 --- a/bastion/provider_test.go +++ b/bastion/provider_test.go @@ -5,9 +5,10 @@ import ( "os" "testing" + "github.com/wallix/terraform-provider-wallix-bastion/bastion" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - "github.com/wallix/terraform-provider-wallix-bastion/bastion" ) var ( diff --git a/bastion/resource_application.go b/bastion/resource_application.go index 5231951..484ece3 100644 --- a/bastion/resource_application.go +++ b/bastion/resource_application.go @@ -3,23 +3,30 @@ package bastion import ( "context" "encoding/json" + "errors" "fmt" "net/http" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - bchk "github.com/jeremmfr/go-utils/basiccheck" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "golang.org/x/mod/semver" ) type jsonApplication struct { ID string `json:"id,omitempty"` ApplicationName string `json:"application_name"` ConnectionPolicy string `json:"connection_policy"` + Category string `json:"category,omitempty"` + ApplicationURL *string `json:"application_url,omitempty"` + Browser *string `json:"browser,omitempty"` + BrowserVersion *string `json:"browser_version,omitempty"` Description string `json:"description"` Parameters string `json:"parameters"` - Target string `json:"target"` - GlobalDomains []string `json:"global_domains"` - Paths []jsonApplicationPath `json:"paths"` + Target *string `json:"target,omitempty"` + GlobalDomains *[]string `json:"global_domains,omitempty"` + Paths *[]jsonApplicationPath `json:"paths,omitempty"` LocalDomains *[]jsonApplicationLocalDomain `json:"local_domains,omitempty"` } @@ -47,9 +54,41 @@ func resourceApplication() *schema.Resource { Type: schema.TypeString, Required: true, }, + "category": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Default: "standard", + ValidateFunc: validation.StringInSlice([]string{"standard", "jumphost"}, false), + }, + "application_url": { + Type: schema.TypeString, + Optional: true, + }, + "browser": { + Type: schema.TypeString, + Optional: true, + }, + "browser_version": { + Type: schema.TypeString, + Optional: true, + }, + "description": { + Type: schema.TypeString, + Optional: true, + }, + "global_domains": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "parameters": { + Type: schema.TypeString, + Optional: true, + }, "paths": { Type: schema.TypeSet, - Required: true, + Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "target": { @@ -69,19 +108,6 @@ func resourceApplication() *schema.Resource { }, }, "target": { - Type: schema.TypeString, - Required: true, - }, - "description": { - Type: schema.TypeString, - Optional: true, - }, - "global_domains": { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "parameters": { Type: schema.TypeString, Optional: true, }, @@ -130,7 +156,7 @@ func resourceApplication() *schema.Resource { } func resourceApplicationVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -151,7 +177,7 @@ func resourceApplicationCreate( if ex { return diag.FromErr(fmt.Errorf("application_name %s already exists", d.Get("application_name").(string))) } - err = addApplication(ctx, d, m) + err = addApplication(ctx, d, m, c.bastionAPIVersion) if err != nil { return diag.FromErr(err) } @@ -195,7 +221,7 @@ func resourceApplicationUpdate( if err := resourceApplicationVersionCheck(c.bastionAPIVersion); err != nil { return diag.FromErr(err) } - if err := updateApplication(ctx, d, m); err != nil { + if err := updateApplication(ctx, d, m, c.bastionAPIVersion); err != nil { return diag.FromErr(err) } d.Partial(false) @@ -232,7 +258,7 @@ func resourceApplicationImport( return nil, err } if !ex { - return nil, fmt.Errorf("don't find application_name with id %s (id must be ", d.Id()) + return nil, fmt.Errorf("don't find application_name with id %s (id must be )", d.Id()) } cfg, err := readApplicationOptions(ctx, id, m) if err != nil { @@ -272,10 +298,13 @@ func searchResourceApplication( } func addApplication( - ctx context.Context, d *schema.ResourceData, m interface{}, + ctx context.Context, d *schema.ResourceData, m interface{}, apiVersion string, ) error { c := m.(*Client) - jsonData := prepareApplicationJSON(d) + jsonData, err := prepareApplicationJSON(d, true, apiVersion) + if err != nil { + return err + } body, code, err := c.newRequest(ctx, "/applications/", http.MethodPost, jsonData) if err != nil { return err @@ -288,10 +317,13 @@ func addApplication( } func updateApplication( - ctx context.Context, d *schema.ResourceData, m interface{}, + ctx context.Context, d *schema.ResourceData, m interface{}, apiVersion string, ) error { c := m.(*Client) - jsonData := prepareApplicationJSON(d) + jsonData, err := prepareApplicationJSON(d, false, apiVersion) + if err != nil { + return err + } body, code, err := c.newRequest(ctx, "/applications/"+d.Id()+"?force=true", http.MethodPut, jsonData) if err != nil { return err @@ -318,33 +350,92 @@ func deleteApplication( return nil } -func prepareApplicationJSON(d *schema.ResourceData) jsonApplication { +func prepareApplicationJSON( + d *schema.ResourceData, newResource bool, apiVersion string, +) ( + jsonApplication, error, +) { jsonData := jsonApplication{ ApplicationName: d.Get("application_name").(string), ConnectionPolicy: d.Get("connection_policy").(string), Description: d.Get("description").(string), Parameters: d.Get("parameters").(string), - Target: d.Get("target").(string), } + if newResource && + semver.Compare(apiVersion, VersionWallixAPI312) >= 0 { + jsonData.Category = d.Get("category").(string) + } + switch jsonData.Category { + case "", "standard": + if d.Get("application_url").(string) != "" { + return jsonData, errors.New("application_url cannot be configured when category = standard") + } + if d.Get("browser").(string) != "" { + return jsonData, errors.New("browser cannot be configured when category = standard") + } + if d.Get("browser_version").(string) != "" { + return jsonData, errors.New("browser_version cannot be configured when category = standard") + } - listPaths := d.Get("paths").(*schema.Set).List() - jsonData.Paths = make([]jsonApplicationPath, len(listPaths)) - for i, v := range listPaths { - paths := v.(map[string]interface{}) - jsonData.Paths[i] = jsonApplicationPath{ - Target: paths["target"].(string), - Program: paths["program"].(string), - WorkingDir: paths["working_dir"].(string), + target := d.Get("target").(string) + if target == "" { + return jsonData, errors.New("target must be specified when category = standard") } - } + jsonData.Target = &target + + listPaths := d.Get("paths").(*schema.Set).List() + if len(listPaths) == 0 { + return jsonData, errors.New("paths must be specified when category = standard") + } + jsonDataPaths := make([]jsonApplicationPath, len(listPaths)) + for i, v := range listPaths { + paths := v.(map[string]interface{}) + jsonDataPaths[i] = jsonApplicationPath{ + Target: paths["target"].(string), + Program: paths["program"].(string), + WorkingDir: paths["working_dir"].(string), + } + } + jsonData.Paths = &jsonDataPaths - listGlobalDomains := d.Get("global_domains").(*schema.Set).List() - jsonData.GlobalDomains = make([]string, len(listGlobalDomains)) - for i, v := range listGlobalDomains { - jsonData.GlobalDomains[i] = v.(string) + listGlobalDomains := d.Get("global_domains").(*schema.Set).List() + jsonDataGlobalDomains := make([]string, len(listGlobalDomains)) + for i, v := range listGlobalDomains { + jsonDataGlobalDomains[i] = v.(string) + } + jsonData.GlobalDomains = &jsonDataGlobalDomains + + case "jumphost": + if semver.Compare(apiVersion, VersionWallixAPI312) < 0 { + return jsonData, fmt.Errorf("category = jumphost not available with api version %s", apiVersion) + } + if d.Get("target").(string) != "" { + return jsonData, errors.New("target cannot be configured when category = jumphost") + } + if len(d.Get("paths").(*schema.Set).List()) > 0 { + return jsonData, errors.New("paths cannot be configured when category = jumphost") + } + if len(d.Get("global_domains").(*schema.Set).List()) > 0 { + return jsonData, errors.New("paths cannot be configured when category = jumphost") + } + + applicationURL := d.Get("application_url").(string) + if applicationURL == "" { + return jsonData, errors.New("application_url must be specified when category = jumphost") + } + jsonData.ApplicationURL = &applicationURL + + browser := d.Get("browser").(string) + if browser == "" { + return jsonData, errors.New("browser must be specified when category = jumphost") + } + jsonData.Browser = &browser + + browserVersion := d.Get("browser_version").(string) + jsonData.BrowserVersion = &browserVersion } - return jsonData + return jsonData, nil } func readApplicationOptions( @@ -372,26 +463,46 @@ func readApplicationOptions( return result, nil } -func fillApplication(d *schema.ResourceData, jsonData jsonApplication) { +func fillApplication(d *schema.ResourceData, jsonData jsonApplication) { //nolint:gocognit if tfErr := d.Set("application_name", jsonData.ApplicationName); tfErr != nil { panic(tfErr) } if tfErr := d.Set("connection_policy", jsonData.ConnectionPolicy); tfErr != nil { panic(tfErr) } - paths := make([]map[string]interface{}, len(jsonData.Paths)) - for i, v := range jsonData.Paths { - paths[i] = map[string]interface{}{ - "target": v.Target, - "program": v.Program, - "working_dir": v.WorkingDir, - } + category := jsonData.Category + if category == "" { + category = "standard" } - if tfErr := d.Set("paths", paths); tfErr != nil { + if tfErr := d.Set("category", category); tfErr != nil { panic(tfErr) } - if tfErr := d.Set("target", jsonData.Target); tfErr != nil { - panic(tfErr) + if jsonData.ApplicationURL != nil { + if tfErr := d.Set("application_url", *jsonData.ApplicationURL); tfErr != nil { + panic(tfErr) + } + } else { + if tfErr := d.Set("application_url", ""); tfErr != nil { + panic(tfErr) + } + } + if jsonData.Browser != nil { + if tfErr := d.Set("browser", *jsonData.Browser); tfErr != nil { + panic(tfErr) + } + } else { + if tfErr := d.Set("browser", ""); tfErr != nil { + panic(tfErr) + } + } + if jsonData.BrowserVersion != nil { + if tfErr := d.Set("browser_version", *jsonData.BrowserVersion); tfErr != nil { + panic(tfErr) + } + } else { + if tfErr := d.Set("browser_version", ""); tfErr != nil { + panic(tfErr) + } } if tfErr := d.Set("description", jsonData.Description); tfErr != nil { panic(tfErr) @@ -402,6 +513,29 @@ func fillApplication(d *schema.ResourceData, jsonData jsonApplication) { if tfErr := d.Set("parameters", jsonData.Parameters); tfErr != nil { panic(tfErr) } + paths := make([]map[string]interface{}, 0) + if jsonData.Paths != nil { + paths = make([]map[string]interface{}, len(*jsonData.Paths)) + for i, v := range *jsonData.Paths { + paths[i] = map[string]interface{}{ + "target": v.Target, + "program": v.Program, + "working_dir": v.WorkingDir, + } + } + } + if tfErr := d.Set("paths", paths); tfErr != nil { + panic(tfErr) + } + if jsonData.Target != nil { + if tfErr := d.Set("target", *jsonData.Target); tfErr != nil { + panic(tfErr) + } + } else { + if tfErr := d.Set("target", ""); tfErr != nil { + panic(tfErr) + } + } localDomains := make([]map[string]interface{}, len(*jsonData.LocalDomains)) for i, v := range *jsonData.LocalDomains { localDomains[i] = map[string]interface{}{ diff --git a/bastion/resource_application_localdomain.go b/bastion/resource_application_localdomain.go index 307addb..651aee4 100644 --- a/bastion/resource_application_localdomain.go +++ b/bastion/resource_application_localdomain.go @@ -3,14 +3,15 @@ package bastion import ( "context" "encoding/json" + "errors" "fmt" "net/http" + "slices" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonApplicationLocalDomain struct { @@ -79,7 +80,7 @@ func resourceApplicationLocalDomain() *schema.Resource { } func resourceApplicationLocalDomainVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -189,14 +190,14 @@ func resourceApplicationLocalDomainImport( } idSplit := strings.Split(d.Id(), "/") if len(idSplit) != 2 { - return nil, fmt.Errorf("id must be /") + return nil, errors.New("id must be /") } id, ex, err := searchResourceApplicationLocalDomain(ctx, idSplit[0], idSplit[1], m) if err != nil { return nil, err } if !ex { - return nil, fmt.Errorf("don't find domain_name with id %s (id must be /", d.Id()) + return nil, fmt.Errorf("don't find domain_name with id %s (id must be /)", d.Id()) } cfg, err := readApplicationLocalDomainOptions(ctx, idSplit[0], id, m) if err != nil { diff --git a/bastion/resource_application_localdomain_account.go b/bastion/resource_application_localdomain_account.go index 543271e..51389cb 100644 --- a/bastion/resource_application_localdomain_account.go +++ b/bastion/resource_application_localdomain_account.go @@ -3,13 +3,14 @@ package bastion import ( "context" "encoding/json" + "errors" "fmt" "net/http" + "slices" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonApplicationLocalDomainAccount struct { @@ -78,7 +79,7 @@ func resourceApplicationLocalDomainAccount() *schema.Resource { } func resourceApplicationLocalDomainAccountVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -199,7 +200,7 @@ func resourceApplicationLocalDomainAccountImport( } idSplit := strings.Split(d.Id(), "/") if len(idSplit) != 3 { - return nil, fmt.Errorf("id must be //") + return nil, errors.New("id must be //") } id, ex, err := searchResourceApplicationLocalDomainAccount(ctx, idSplit[0], idSplit[1], idSplit[2], m) if err != nil { @@ -207,7 +208,7 @@ func resourceApplicationLocalDomainAccountImport( } if !ex { return nil, fmt.Errorf("don't find account_name with id %s "+ - "(id must be //", d.Id()) + "(id must be //)", d.Id()) } cfg, err := readApplicationLocalDomainAccountOptions(ctx, idSplit[0], idSplit[1], id, m) if err != nil { diff --git a/bastion/resource_application_test.go b/bastion/resource_application_test.go index 402f431..6eee990 100644 --- a/bastion/resource_application_test.go +++ b/bastion/resource_application_test.go @@ -1,9 +1,13 @@ package bastion_test import ( + "os" "testing" + "github.com/wallix/terraform-provider-wallix-bastion/bastion" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "golang.org/x/mod/semver" ) func TestAccResourceApplication_basic(t *testing.T) { @@ -32,6 +36,36 @@ func TestAccResourceApplication_basic(t *testing.T) { }) } +func TestAccResourceApplication_jumphost(t *testing.T) { + if os.Getenv("TESTACC_JUMPHOST") != "" { + if v := os.Getenv("WALLIX_BASTION_API_VERSION"); semver.Compare(v, bastion.VersionWallixAPI312) >= 0 { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccResourceApplicationCreateJumphost(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet( + "wallix-bastion_application.testacc_Appli", + "id"), + ), + }, + { + Config: testAccResourceApplicationUpdateJumphost(), + }, + { + ResourceName: "wallix-bastion_application.testacc_Appli", + ImportState: true, + ImportStateId: "testacc_Appli", + }, + }, + PreventPostDestroyRefresh: true, + }) + } + } +} + // nolint: lll, nolintlint func testAccResourceApplicationCreate() string { return ` @@ -69,6 +103,20 @@ resource "wallix-bastion_application" "testacc_Appli" { ` } +// nolint: lll, nolintlint +func testAccResourceApplicationCreateJumphost() string { + return ` +resource "wallix-bastion_application" "testacc_Appli" { + application_name = "testacc_Appli_jumphost" + category = "jumphost" + connection_policy = "JumpHost" + browser = "Mozilla Firefox" + browser_version = "93.0" + application_url = "https://github.com/login" +} +` +} + // nolint: lll, nolintlint func testAccResourceApplicationUpdate() string { return ` @@ -111,3 +159,18 @@ resource "wallix-bastion_application" "testacc_Appli" { } ` } + +func testAccResourceApplicationUpdateJumphost() string { + return ` +resource "wallix-bastion_application" "testacc_Appli" { + application_name = "testacc_Appli_jumphost" + description = "testacc Appli jumphost" + category = "jumphost" + connection_policy = "JumpHost" + browser = "Google Chrome" + browser_version = "94.0.4606.81-1" + application_url = "https://github.com/login" + parameters = "app_parameters" +} +` +} diff --git a/bastion/resource_authdomain_ad.go b/bastion/resource_authdomain_ad.go index 4ec82a5..96d49e5 100644 --- a/bastion/resource_authdomain_ad.go +++ b/bastion/resource_authdomain_ad.go @@ -5,11 +5,11 @@ import ( "encoding/json" "fmt" "net/http" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonAuthDomainAD struct { @@ -120,7 +120,7 @@ func resourceAuthDomainAD() *schema.Resource { } func resourceAuthDomainADVersionCheck(version string) error { - if bchk.InSlice(version, []string{VersionWallixAPI38}) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -222,7 +222,7 @@ func resourceAuthDomainADImport( return nil, err } if !ex { - return nil, fmt.Errorf("don't find domain_name with id %s (id must be ", d.Id()) + return nil, fmt.Errorf("don't find domain_name with id %s (id must be )", d.Id()) } cfg, err := readAuthDomainADOptions(ctx, d.Id(), m) if err != nil { diff --git a/bastion/resource_authdomain_ad_test.go b/bastion/resource_authdomain_ad_test.go index cbf76be..a9b274f 100644 --- a/bastion/resource_authdomain_ad_test.go +++ b/bastion/resource_authdomain_ad_test.go @@ -1,47 +1,41 @@ package bastion_test import ( - "os" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/wallix/terraform-provider-wallix-bastion/bastion" ) func TestAccResourceAuthDomainAD_basic(t *testing.T) { - if v := os.Getenv("WALLIX_BASTION_API_VERSION"); v != "" && - v != bastion.VersionWallixAPI33 && - v != bastion.VersionWallixAPI36 { - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - Steps: []resource.TestStep{ - { - Config: testAccResourceAuthDomainADCreate(), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet( - "wallix-bastion_authdomain_ad.testacc_AuthDomainAD", - "id"), - ), - }, - { - Config: testAccResourceAuthDomainADUpdate(), - }, - { - ResourceName: "wallix-bastion_authdomain_ad.testacc_AuthDomainAD", - ImportState: true, - ImportStateId: "testacc_AuthDomainAD_u", - }, + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccResourceAuthDomainADCreate(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet( + "wallix-bastion_authdomain_ad.testacc_AuthDomainAD", + "id"), + ), }, - PreventPostDestroyRefresh: true, - }) - } + { + Config: testAccResourceAuthDomainADUpdate(), + }, + { + ResourceName: "wallix-bastion_authdomain_ad.testacc_AuthDomainAD", + ImportState: true, + ImportStateId: "testacc.AuthDomainAD-u", + }, + }, + PreventPostDestroyRefresh: true, + }) } func testAccResourceAuthDomainADCreate() string { return ` resource "wallix-bastion_authdomain_ad" "testacc_AuthDomainAD" { - domain_name = "testacc_AuthDomainAD" + domain_name = "testacc.AuthDomainAD" auth_domain_name = "test2.com" external_auths = [wallix-bastion_externalauth_ldap.testacc_AuthDomainAD.authentication_name] default_language = "fr" @@ -64,7 +58,7 @@ resource "wallix-bastion_externalauth_ldap" "testacc_AuthDomainAD" { func testAccResourceAuthDomainADUpdate() string { return ` resource "wallix-bastion_authdomain_ad" "testacc_AuthDomainAD" { - domain_name = "testacc_AuthDomainAD_u" + domain_name = "testacc.AuthDomainAD-u" auth_domain_name = "test2u.com" external_auths = [wallix-bastion_externalauth_ldap.testacc_AuthDomainAD.authentication_name] default_language = "en" diff --git a/bastion/resource_authdomain_azuread.go b/bastion/resource_authdomain_azuread.go index 064dd04..516da8d 100644 --- a/bastion/resource_authdomain_azuread.go +++ b/bastion/resource_authdomain_azuread.go @@ -5,11 +5,11 @@ import ( "encoding/json" "fmt" "net/http" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonAuthDomainAzureAD struct { @@ -115,7 +115,7 @@ func resourceAuthDomainAzureAD() *schema.Resource { } func resourceAuthDomainAzureADVersionCheck(version string) error { - if bchk.InSlice(version, []string{VersionWallixAPI38}) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -217,7 +217,7 @@ func resourceAuthDomainAzureADImport( return nil, err } if !ex { - return nil, fmt.Errorf("don't find domain_name with id %s (id must be ", d.Id()) + return nil, fmt.Errorf("don't find domain_name with id %s (id must be )", d.Id()) } cfg, err := readAuthDomainAzureADOptions(ctx, d.Id(), m) if err != nil { diff --git a/bastion/resource_authdomain_ldap.go b/bastion/resource_authdomain_ldap.go index a1b2b84..d2e2795 100644 --- a/bastion/resource_authdomain_ldap.go +++ b/bastion/resource_authdomain_ldap.go @@ -5,11 +5,11 @@ import ( "encoding/json" "fmt" "net/http" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonAuthDomainLdap struct { @@ -120,7 +120,7 @@ func resourceAuthDomainLdap() *schema.Resource { } func resourceAuthDomainLdapVersionCheck(version string) error { - if bchk.InSlice(version, []string{VersionWallixAPI38}) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -222,7 +222,7 @@ func resourceAuthDomainLdapImport( return nil, err } if !ex { - return nil, fmt.Errorf("don't find domain_name with id %s (id must be ", d.Id()) + return nil, fmt.Errorf("don't find domain_name with id %s (id must be )", d.Id()) } cfg, err := readAuthDomainLdapOptions(ctx, d.Id(), m) if err != nil { diff --git a/bastion/resource_authdomain_ldap_test.go b/bastion/resource_authdomain_ldap_test.go index cb671ee..998f376 100644 --- a/bastion/resource_authdomain_ldap_test.go +++ b/bastion/resource_authdomain_ldap_test.go @@ -1,47 +1,41 @@ package bastion_test import ( - "os" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/wallix/terraform-provider-wallix-bastion/bastion" ) func TestAccResourceAuthDomainLdap_basic(t *testing.T) { - if v := os.Getenv("WALLIX_BASTION_API_VERSION"); v != "" && - v != bastion.VersionWallixAPI33 && - v != bastion.VersionWallixAPI36 { - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - Steps: []resource.TestStep{ - { - Config: testAccResourceAuthDomainLdapCreate(), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet( - "wallix-bastion_authdomain_ldap.testacc_AuthDomainLDAP", - "id"), - ), - }, - { - Config: testAccResourceAuthDomainLdapUpdate(), - }, - { - ResourceName: "wallix-bastion_authdomain_ldap.testacc_AuthDomainLDAP", - ImportState: true, - ImportStateId: "testacc_AuthDomainLDAP_u", - }, + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccResourceAuthDomainLdapCreate(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet( + "wallix-bastion_authdomain_ldap.testacc_AuthDomainLDAP", + "id"), + ), }, - PreventPostDestroyRefresh: true, - }) - } + { + Config: testAccResourceAuthDomainLdapUpdate(), + }, + { + ResourceName: "wallix-bastion_authdomain_ldap.testacc_AuthDomainLDAP", + ImportState: true, + ImportStateId: "testacc.AuthDomainLDAP-u", + }, + }, + PreventPostDestroyRefresh: true, + }) } func testAccResourceAuthDomainLdapCreate() string { return ` resource "wallix-bastion_authdomain_ldap" "testacc_AuthDomainLDAP" { - domain_name = "testacc_AuthDomainLDAP" + domain_name = "testacc.AuthDomainLDAP" auth_domain_name = "test3.com" external_auths = [wallix-bastion_externalauth_ldap.testacc_AuthDomainLDAP.authentication_name] default_language = "fr" @@ -64,7 +58,7 @@ resource "wallix-bastion_externalauth_ldap" "testacc_AuthDomainLDAP" { func testAccResourceAuthDomainLdapUpdate() string { return ` resource "wallix-bastion_authdomain_ldap" "testacc_AuthDomainLDAP" { - domain_name = "testacc_AuthDomainLDAP_u" + domain_name = "testacc.AuthDomainLDAP-u" auth_domain_name = "test3u.com" external_auths = [wallix-bastion_externalauth_ldap.testacc_AuthDomainLDAP.authentication_name] default_language = "en" diff --git a/bastion/resource_authdomain_mapping.go b/bastion/resource_authdomain_mapping.go index 7cd1e31..c60a238 100644 --- a/bastion/resource_authdomain_mapping.go +++ b/bastion/resource_authdomain_mapping.go @@ -3,13 +3,14 @@ package bastion import ( "context" "encoding/json" + "errors" "fmt" "net/http" + "slices" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonAuthDomain struct { @@ -55,7 +56,7 @@ func resourceAuthDomainMapping() *schema.Resource { } func resourceAuthDomainMappingVersionCheck(version string) error { - if bchk.InSlice(version, []string{VersionWallixAPI38}) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -161,14 +162,14 @@ func resourceAuthDomainMappingImport( } idSplit := strings.Split(d.Id(), "/") if len(idSplit) != 2 { - return nil, fmt.Errorf("id must be /") + return nil, errors.New("id must be /") } id, ex, err := searchResourceAuthDomainMapping(ctx, idSplit[0], idSplit[1], m) if err != nil { return nil, err } if !ex { - return nil, fmt.Errorf("don't find auth domain mapping with id %s (id must be /", d.Id()) + return nil, fmt.Errorf("don't find auth domain mapping with id %s (id must be /)", d.Id()) } cfg, err := readAuthDomainMappingOptions(ctx, idSplit[0], id, m) if err != nil { diff --git a/bastion/resource_authdomain_mapping_test.go b/bastion/resource_authdomain_mapping_test.go index 10fc2cc..9aa35e8 100644 --- a/bastion/resource_authdomain_mapping_test.go +++ b/bastion/resource_authdomain_mapping_test.go @@ -2,61 +2,55 @@ package bastion_test import ( "fmt" - "os" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - "github.com/wallix/terraform-provider-wallix-bastion/bastion" ) func TestAccResourceAuthDomainMapping_basic(t *testing.T) { resourceName := "wallix-bastion_authdomain_mapping.testacc_AuthDomainMapping" - if v := os.Getenv("WALLIX_BASTION_API_VERSION"); v != "" && - v != bastion.VersionWallixAPI33 && - v != bastion.VersionWallixAPI36 { - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - Steps: []resource.TestStep{ - { - Config: testAccResourceAuthDomainMappingCreate(), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet(resourceName, - "id"), - resource.TestCheckResourceAttrSet(resourceName, - "domain"), - ), - }, - { - Config: testAccResourceAuthDomainMappingUpdate(), - }, - { - ResourceName: resourceName, - ImportState: true, - ImportStateIdFunc: func(s *terraform.State) (string, error) { - rs, ok := s.RootModule().Resources[resourceName] - if !ok { - return "", fmt.Errorf("Resource %s not found", resourceName) - } - devID := rs.Primary.Attributes["domain_id"] - if devID == "" { - return "", fmt.Errorf("Attribute %s not found:\n%+v", "domain_id", rs.Primary.Attributes) - } + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccResourceAuthDomainMappingCreate(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet(resourceName, + "id"), + resource.TestCheckResourceAttrSet(resourceName, + "domain"), + ), + }, + { + Config: testAccResourceAuthDomainMappingUpdate(), + }, + { + ResourceName: resourceName, + ImportState: true, + ImportStateIdFunc: func(s *terraform.State) (string, error) { + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return "", fmt.Errorf("Resource %s not found", resourceName) + } + devID := rs.Primary.Attributes["domain_id"] + if devID == "" { + return "", fmt.Errorf("Attribute %s not found:\n%+v", "domain_id", rs.Primary.Attributes) + } - return devID + "/testacc_AuthDomainMapping2", nil - }, + return devID + "/testacc_AuthDomainMapping2", nil }, }, - PreventPostDestroyRefresh: true, - }) - } + }, + PreventPostDestroyRefresh: true, + }) } func testAccResourceAuthDomainMappingCreate() string { return ` resource "wallix-bastion_authdomain_ldap" "testacc_AuthDomainMapping" { - domain_name = "testacc_AuthDomainMapping" + domain_name = "testacc.AuthDomainMapping" auth_domain_name = "test.com" external_auths = [wallix-bastion_externalauth_ldap.testacc_AuthDomainMapping.authentication_name] default_language = "fr" @@ -89,7 +83,7 @@ resource "wallix-bastion_authdomain_mapping" "testacc_AuthDomainMapping" { func testAccResourceAuthDomainMappingUpdate() string { return ` resource "wallix-bastion_authdomain_ldap" "testacc_AuthDomainMapping" { - domain_name = "testacc_AuthDomainMapping" + domain_name = "testacc.AuthDomainMapping" auth_domain_name = "test.com" external_auths = [wallix-bastion_externalauth_ldap.testacc_AuthDomainMapping.authentication_name] default_language = "fr" diff --git a/bastion/resource_authorization.go b/bastion/resource_authorization.go index 4468414..dbe6a70 100644 --- a/bastion/resource_authorization.go +++ b/bastion/resource_authorization.go @@ -5,10 +5,10 @@ import ( "encoding/json" "fmt" "net/http" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonAuthorization struct { @@ -144,7 +144,7 @@ func resourceAuthorization() *schema.Resource { } func resourceAuthorizationVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -246,7 +246,7 @@ func resourceAuthorizationImport( return nil, err } if !ex { - return nil, fmt.Errorf("don't find authorization_name with id %s (id must be ", d.Id()) + return nil, fmt.Errorf("don't find authorization_name with id %s (id must be )", d.Id()) } cfg, err := readAuthorizationOptions(ctx, id, m) if err != nil { diff --git a/bastion/resource_checkout_policy.go b/bastion/resource_checkout_policy.go index a00b348..679ffd6 100644 --- a/bastion/resource_checkout_policy.go +++ b/bastion/resource_checkout_policy.go @@ -5,10 +5,10 @@ import ( "encoding/json" "fmt" "net/http" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonCheckoutPolicy struct { @@ -70,7 +70,7 @@ func resourceCheckoutPolicy() *schema.Resource { } func resourceCheckoutPolicyVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -173,7 +173,7 @@ func resourceCheckoutPolicyImport( return nil, err } if !ex { - return nil, fmt.Errorf("don't find checkout_policy_name with id %s (id must be ", d.Id()) + return nil, fmt.Errorf("don't find checkout_policy_name with id %s (id must be )", d.Id()) } cfg, err := readCheckoutPolicyOptions(ctx, id, m) if err != nil { diff --git a/bastion/resource_cluster.go b/bastion/resource_cluster.go index 8870fd1..93ac424 100644 --- a/bastion/resource_cluster.go +++ b/bastion/resource_cluster.go @@ -5,10 +5,10 @@ import ( "encoding/json" "fmt" "net/http" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonCluster struct { @@ -61,7 +61,7 @@ func resourceCluster() *schema.Resource { } func resourceClusterVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -163,7 +163,7 @@ func resourceClusterImport( return nil, err } if !ex { - return nil, fmt.Errorf("don't find cluster_name with id %s (id must be ", d.Id()) + return nil, fmt.Errorf("don't find cluster_name with id %s (id must be )", d.Id()) } cfg, err := readClusterOptions(ctx, id, m) if err != nil { diff --git a/bastion/resource_connection_message.go b/bastion/resource_connection_message.go index fb9d6fa..89958e7 100644 --- a/bastion/resource_connection_message.go +++ b/bastion/resource_connection_message.go @@ -5,11 +5,11 @@ import ( "encoding/json" "fmt" "net/http" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonConnectionMessage struct { @@ -48,7 +48,7 @@ func resourceConnectionMessage() *schema.Resource { } func resourceConnectionMessageVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } diff --git a/bastion/resource_connection_policy.go b/bastion/resource_connection_policy.go index 7208fc9..94e364d 100644 --- a/bastion/resource_connection_policy.go +++ b/bastion/resource_connection_policy.go @@ -5,18 +5,20 @@ import ( "encoding/json" "fmt" "net/http" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" + "golang.org/x/mod/semver" ) type jsonConnectionPolicy struct { ID string `json:"id,omitempty"` ConnectionPolicyName string `json:"connection_policy_name"` Description string `json:"description"` - Protocol string `json:"protocol"` + Protocol string `json:"protocol,omitempty"` + Type string `json:"type,omitempty"` Options map[string]interface{} `json:"options"` AuthenticationMethods []string `json:"authentication_methods"` } @@ -43,6 +45,16 @@ func resourceConnectionPolicy() *schema.Resource { false, ), }, + "type": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice( + []string{"SSH", "RAWTCPIP", "RDP", "RDP-JUMPHOST", "RLOGIN", "TELNET", "VNC"}, + false, + ), + }, "description": { Type: schema.TypeString, Optional: true, @@ -62,7 +74,7 @@ func resourceConnectionPolicy() *schema.Resource { } func resourceConnectionPolicyVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -83,7 +95,7 @@ func resourceConnectionPolicyCreate( if ex { return diag.FromErr(fmt.Errorf("connection_policy_name %s already exists", d.Get("connection_policy_name").(string))) } - err = addConnectionPolicy(ctx, d, m) + err = addConnectionPolicy(ctx, d, m, c.bastionAPIVersion) if err != nil { return diag.FromErr(err) } @@ -128,7 +140,7 @@ func resourceConnectionPolicyUpdate( if err := resourceConnectionPolicyVersionCheck(c.bastionAPIVersion); err != nil { return diag.FromErr(err) } - if err := updateConnectionPolicy(ctx, d, m); err != nil { + if err := updateConnectionPolicy(ctx, d, m, c.bastionAPIVersion); err != nil { return diag.FromErr(err) } d.Partial(false) @@ -165,7 +177,7 @@ func resourceConnectionPolicyImport( return nil, err } if !ex { - return nil, fmt.Errorf("don't find connection_policy_name with id %s (id must be ", d.Id()) + return nil, fmt.Errorf("don't find connection_policy_name with id %s (id must be )", d.Id()) } cfg, err := readConnectionPolicyOptions(ctx, id, m) if err != nil { @@ -206,10 +218,10 @@ func searchResourceConnectionPolicy( } func addConnectionPolicy( - ctx context.Context, d *schema.ResourceData, m interface{}, + ctx context.Context, d *schema.ResourceData, m interface{}, apiVersion string, ) error { c := m.(*Client) - jsonData, err := prepareConnectionPolicyJSON(d) + jsonData, err := prepareConnectionPolicyJSON(d, true, apiVersion) if err != nil { return err } @@ -225,10 +237,10 @@ func addConnectionPolicy( } func updateConnectionPolicy( - ctx context.Context, d *schema.ResourceData, m interface{}, + ctx context.Context, d *schema.ResourceData, m interface{}, apiVersion string, ) error { c := m.(*Client) - jsonData, err := prepareConnectionPolicyJSON(d) + jsonData, err := prepareConnectionPolicyJSON(d, false, apiVersion) if err != nil { return err } @@ -258,17 +270,30 @@ func deleteConnectionPolicy( return nil } -func prepareConnectionPolicyJSON(d *schema.ResourceData) (jsonConnectionPolicy, error) { +func prepareConnectionPolicyJSON( + d *schema.ResourceData, newResource bool, apiVersion string, +) ( + jsonConnectionPolicy, error, +) { jsonData := jsonConnectionPolicy{ ConnectionPolicyName: d.Get("connection_policy_name").(string), Description: d.Get("description").(string), - Protocol: d.Get("protocol").(string), + } + if newResource { + jsonData.Protocol = d.Get("protocol").(string) + if semver.Compare(apiVersion, VersionWallixAPI312) >= 0 { + if v := d.Get("type").(string); v != "" { + jsonData.Type = v + } else { + jsonData.Type = jsonData.Protocol + } + } } listAuthenticationMethods := d.Get("authentication_methods").(*schema.Set).List() jsonData.AuthenticationMethods = make([]string, len(listAuthenticationMethods)) for i, v := range listAuthenticationMethods { - if !bchk.InSlice(v.(string), validAuthenticationMethods()) { + if !slices.Contains(validAuthenticationMethods(), v.(string)) { return jsonData, fmt.Errorf("authentication_methods must be in %v", validAuthenticationMethods()) } jsonData.AuthenticationMethods[i] = v.(string) @@ -331,6 +356,15 @@ func fillConnectionPolicy(d *schema.ResourceData, jsonData jsonConnectionPolicy) if tfErr := d.Set("protocol", jsonData.Protocol); tfErr != nil { panic(tfErr) } + if jsonData.Type != "" { + if tfErr := d.Set("type", jsonData.Type); tfErr != nil { + panic(tfErr) + } + } else { + if tfErr := d.Set("type", jsonData.Protocol); tfErr != nil { + panic(tfErr) + } + } if tfErr := d.Set("authentication_methods", jsonData.AuthenticationMethods); tfErr != nil { panic(tfErr) } diff --git a/bastion/resource_connection_policy_test.go b/bastion/resource_connection_policy_test.go index b036dd0..96fee5e 100644 --- a/bastion/resource_connection_policy_test.go +++ b/bastion/resource_connection_policy_test.go @@ -35,13 +35,6 @@ func TestAccResourceConnectionPolicy_basic(t *testing.T) { // nolint: lll, nolintlint func testAccResourceConnectionPolicyCreate() string { return ` -resource "wallix-bastion_connection_policy" "testacc_ConnectionPolicy" { - connection_policy_name = "testacc_ConnectionPolicy" - protocol = "RAWTCPIP" - options = jsonencode({ - general = {} - }) -} locals { optionsv8 = { algorithms = { @@ -168,6 +161,92 @@ locals { log_group_membership = false } } + optionsv12 = { + general = { + transformation_rule = "" + vault_transformation_rule = "" + } + authentication = { + show_issue_banner = false + } + session = { + inactivity_timeout = 0 + allow_multi_channels = false + force_shell_disconnection = false + server_keepalive_type = "none" + server_keepalive_interval = 0 + } + trace = { + log_all_kbd = false + log_group_membership = false + } + restriction = { + cmds_compatibility = "cisco" + } + algorithms = { + kex_algos = "diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group18-sha512" + cipher_algos = "chacha20-poly1305@openssh.com,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr" + integrity_algos = "hmac-sha2-256,hmac-sha2-512,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com" + compression_algos = "" + hostkey_algos = "ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-256,rsa-sha2-512" + allow_rsa_sha2_cert = true + dh_modulus_min_size = 3072 + } + server_pubkey = { + server_pubkey_store = true + server_pubkey_check = "1" + server_access_allowed_message = "0" + server_pubkey_create_message = "1" + server_pubkey_success_message = "0" + server_pubkey_failure_message = "1" + } + startup_scenario = { + enable = false + scenario = "" + show_output = true + timeout = 10 + ask_startup = false + } + tcp = { + enable_tcpkeepalive = false + tcpkeepalive_interval = 0 + tcpkeepalive_max_count = 0 + } + proxy = { + enable = false + proxy_type = "None" + host = "" + port = 0 + login = "" + password = "" + } + file_verification = { + enable_up = false + enable_down = false + block_invalid_file_up = false + block_invalid_file_down = false + max_file_size_rejected = 500 + abort_on_block = false + block_show_message = true + } + file_storage = { + store_file = "never" + } + } + optionsRAWTCPIP = { + nat_redirection = { + enable = false + host = "" + port = 0 + } + } + + options = { + "8" = local.optionsv8 + "9" = local.optionsv9 + "10" = local.optionsv9 + "12" = local.optionsv12 + } } data "wallix-bastion_version" "v" {} @@ -176,7 +255,12 @@ resource "wallix-bastion_connection_policy" "testacc_ConnectionPolicy2" { description = "testacc ConnectionPolicy2" protocol = "SSH" authentication_methods = ["PASSWORD_VAULT"] - options = split(".", data.wallix-bastion_version.v.wab_version)[0] == "8" ? jsonencode(local.optionsv8) : jsonencode(local.optionsv9) + options = jsonencode(local.options[split(".", data.wallix-bastion_version.v.wab_version)[0]]) +} +resource "wallix-bastion_connection_policy" "testacc_ConnectionPolicy" { + connection_policy_name = "testacc_ConnectionPolicy" + protocol = "RAWTCPIP" + options = jsonencode(local.optionsRAWTCPIP) } ` } @@ -310,6 +394,84 @@ locals { log_group_membership = false } } + optionsv12 = { + general = { + transformation_rule = "" + vault_transformation_rule = "" + } + authentication = { + show_issue_banner = false + } + session = { + inactivity_timeout = 0 + allow_multi_channels = false + force_shell_disconnection = false + server_keepalive_type = "none" + server_keepalive_interval = 0 + } + trace = { + log_all_kbd = false + log_group_membership = false + } + restriction = { + cmds_compatibility = "cisco" + } + algorithms = { + kex_algos = "diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,curve25519-sha256,curve25519-sha256@libssh.org,diffie-hellman-group18-sha512" + cipher_algos = "chacha20-poly1305@openssh.com,aes128-gcm@openssh.com,aes256-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr" + integrity_algos = "hmac-sha2-256,hmac-sha2-512,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com" + compression_algos = "" + hostkey_algos = "ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521,ssh-ed25519,rsa-sha2-256,rsa-sha2-512" + allow_rsa_sha2_cert = true + dh_modulus_min_size = 3072 + } + server_pubkey = { + server_pubkey_store = true + server_pubkey_check = "1" + server_access_allowed_message = "0" + server_pubkey_create_message = "1" + server_pubkey_success_message = "0" + server_pubkey_failure_message = "1" + } + startup_scenario = { + enable = false + scenario = "" + show_output = true + timeout = 10 + ask_startup = false + } + tcp = { + enable_tcpkeepalive = false + tcpkeepalive_interval = 0 + tcpkeepalive_max_count = 0 + } + proxy = { + enable = false + proxy_type = "None" + host = "" + port = 0 + login = "" + password = "" + } + file_verification = { + enable_up = false + enable_down = false + block_invalid_file_up = false + block_invalid_file_down = false + max_file_size_rejected = 500 + abort_on_block = false + block_show_message = true + } + file_storage = { + store_file = "never" + } + } + options = { + "8" = local.optionsv8 + "9" = local.optionsv9 + "10" = local.optionsv9 + "12" = local.optionsv12 + } } data "wallix-bastion_version" "v" {} @@ -318,7 +480,7 @@ resource "wallix-bastion_connection_policy" "testacc_ConnectionPolicy2" { description = "testacc ConnectionPolicy2" protocol = "SSH" authentication_methods = ["PASSWORD_VAULT", "PASSWORD_MAPPING"] - options = split(".", data.wallix-bastion_version.v.wab_version)[0] == "8" ? jsonencode(local.optionsv8) : jsonencode(local.optionsv9) + options = jsonencode(local.options[split(".", data.wallix-bastion_version.v.wab_version)[0]]) } ` } diff --git a/bastion/resource_device.go b/bastion/resource_device.go index 527e2e2..01d09b2 100644 --- a/bastion/resource_device.go +++ b/bastion/resource_device.go @@ -5,10 +5,10 @@ import ( "encoding/json" "fmt" "net/http" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonDevice struct { @@ -134,7 +134,7 @@ func resourceDevice() *schema.Resource { } func resourceDeviceVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -236,7 +236,7 @@ func resourceDeviceImport( return nil, err } if !ex { - return nil, fmt.Errorf("don't find device_name with id %s (id must be ", d.Id()) + return nil, fmt.Errorf("don't find device_name with id %s (id must be )", d.Id()) } cfg, err := readDeviceOptions(ctx, id, m) if err != nil { diff --git a/bastion/resource_device_localdomain.go b/bastion/resource_device_localdomain.go index 2c82f16..6759365 100644 --- a/bastion/resource_device_localdomain.go +++ b/bastion/resource_device_localdomain.go @@ -3,14 +3,15 @@ package bastion import ( "context" "encoding/json" + "errors" "fmt" "net/http" + "slices" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonDeviceLocalDomain struct { @@ -21,7 +22,7 @@ type jsonDeviceLocalDomain struct { CAPrivateKey string `json:"ca_private_key,omitempty"` CAPublicKey string `json:"ca_public_key,omitempty"` Description string `json:"description"` - Passphrase string `json:"passphrase"` + Passphrase string `json:"passphrase,omitempty"` PasswordChangePolicy string `json:"password_change_policy,omitempty"` PasswordChangePlugin string `json:"password_change_plugin,omitempty"` PasswordChangePluginParameters *map[string]interface{} `json:"password_change_plugin_parameters,omitempty"` @@ -97,7 +98,7 @@ func resourceDeviceLocalDomain() *schema.Resource { } func resourceDeviceLocalDomainVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -205,14 +206,14 @@ func resourceDeviceLocalDomainImport( } idSplit := strings.Split(d.Id(), "/") if len(idSplit) != 2 { - return nil, fmt.Errorf("id must be /") + return nil, errors.New("id must be /") } id, ex, err := searchResourceDeviceLocalDomain(ctx, idSplit[0], idSplit[1], m) if err != nil { return nil, err } if !ex { - return nil, fmt.Errorf("don't find domain_name with id %s (id must be /", d.Id()) + return nil, fmt.Errorf("don't find domain_name with id %s (id must be /)", d.Id()) } cfg, err := readDeviceLocalDomainOptions(ctx, idSplit[0], id, m) if err != nil { diff --git a/bastion/resource_device_localdomain_account.go b/bastion/resource_device_localdomain_account.go index 24c80bb..e8e19c0 100644 --- a/bastion/resource_device_localdomain_account.go +++ b/bastion/resource_device_localdomain_account.go @@ -3,13 +3,14 @@ package bastion import ( "context" "encoding/json" + "errors" "fmt" "net/http" + "slices" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonDeviceLocalDomainAccount struct { @@ -109,7 +110,7 @@ func resourceDeviceLocalDomainAccount() *schema.Resource { } func resourceDeviceLocalDomainAccountVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -228,7 +229,7 @@ func resourceDeviceLocalDomainAccountImport( } idSplit := strings.Split(d.Id(), "/") if len(idSplit) != 3 { - return nil, fmt.Errorf("id must be //") + return nil, errors.New("id must be //") } id, ex, err := searchResourceDeviceLocalDomainAccount(ctx, idSplit[0], idSplit[1], idSplit[2], m) if err != nil { @@ -236,7 +237,7 @@ func resourceDeviceLocalDomainAccountImport( } if !ex { return nil, fmt.Errorf("don't find account_name with id %s "+ - "(id must be //", d.Id()) + "(id must be //)", d.Id()) } cfg, err := readDeviceLocalDomainAccountOptions(ctx, idSplit[0], idSplit[1], id, m) if err != nil { diff --git a/bastion/resource_device_localdomain_account_credential.go b/bastion/resource_device_localdomain_account_credential.go index 1d0634a..c1bc76b 100644 --- a/bastion/resource_device_localdomain_account_credential.go +++ b/bastion/resource_device_localdomain_account_credential.go @@ -3,14 +3,15 @@ package bastion import ( "context" "encoding/json" + "errors" "fmt" "net/http" + "slices" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) func resourceDeviceLocalDomainAccountCredential() *schema.Resource { @@ -70,7 +71,7 @@ func resourceDeviceLocalDomainAccountCredential() *schema.Resource { } func resourceDeviceLocalDomainAccountCredentialVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -200,7 +201,7 @@ func resourceDeviceLocalDomainAccountCredentialImport( } idSplit := strings.Split(d.Id(), "/") if len(idSplit) != 4 { - return nil, fmt.Errorf("id must be ///") + return nil, errors.New("id must be ///") } id, ex, err := searchResourceDeviceLocalDomainAccountCredential(ctx, idSplit[0], idSplit[1], idSplit[2], idSplit[3], m) if err != nil { @@ -208,7 +209,7 @@ func resourceDeviceLocalDomainAccountCredentialImport( } if !ex { return nil, fmt.Errorf("don't find credential with id %s "+ - "(id must be ///", d.Id()) + "(id must be ///)", d.Id()) } cfg, err := readDeviceLocalDomainAccountCredentialOptions(ctx, idSplit[0], idSplit[1], idSplit[2], id, m) if err != nil { diff --git a/bastion/resource_device_service.go b/bastion/resource_device_service.go index 5ccd859..651754f 100644 --- a/bastion/resource_device_service.go +++ b/bastion/resource_device_service.go @@ -3,14 +3,15 @@ package bastion import ( "context" "encoding/json" + "errors" "fmt" "net/http" + "slices" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonDeviceService struct { @@ -77,7 +78,7 @@ func resourceDeviceService() *schema.Resource { } func resourceDeviceServiceVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -185,14 +186,14 @@ func resourceDeviceServiceImport( } idSplit := strings.Split(d.Id(), "/") if len(idSplit) != 2 { - return nil, fmt.Errorf("id must be /") + return nil, errors.New("id must be /") } id, ex, err := searchResourceDeviceService(ctx, idSplit[0], idSplit[1], m) if err != nil { return nil, err } if !ex { - return nil, fmt.Errorf("don't find service_name with id %s (id must be /", d.Id()) + return nil, fmt.Errorf("don't find service_name with id %s (id must be /)", d.Id()) } cfg, err := readDeviceServiceOptions(ctx, idSplit[0], id, m) if err != nil { @@ -346,12 +347,12 @@ func prepareDeviceServiceJSON( for i, v := range listSubProtocols { switch d.Get("protocol").(string) { case "SSH": - if !bchk.InSlice(v.(string), sshSubProtocolsValid()) { + if !slices.Contains(sshSubProtocolsValid(), v.(string)) { return jsonData, fmt.Errorf("subprotocols %s not valid for SSH service", v) } subProtocols[i] = v.(string) case "RDP": - if !bchk.InSlice(v.(string), rdpSubProtocolsValid()) { + if !slices.Contains(rdpSubProtocolsValid(), v.(string)) { return jsonData, fmt.Errorf("subprotocols %s not valid for RDP service", v) } subProtocols[i] = v.(string) diff --git a/bastion/resource_domain.go b/bastion/resource_domain.go index e9b1d05..1a37046 100644 --- a/bastion/resource_domain.go +++ b/bastion/resource_domain.go @@ -5,12 +5,12 @@ import ( "encoding/json" "fmt" "net/http" + "slices" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonDomain struct { @@ -22,7 +22,7 @@ type jsonDomain struct { CAPrivateKey string `json:"ca_private_key,omitempty"` CAPublicKey string `json:"ca_public_key,omitempty"` Description string `json:"description"` - Passphrase string `json:"passphrase"` + Passphrase string `json:"passphrase,omitempty"` PasswordChangePolicy string `json:"password_change_policy,omitempty"` PasswordChangePlugin string `json:"password_change_plugin,omitempty"` PasswordChangePluginParameters *map[string]interface{} `json:"password_change_plugin_parameters,omitempty"` @@ -115,7 +115,7 @@ func resourceDomain() *schema.Resource { } func resourceDomainVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -217,7 +217,7 @@ func resourceDomainImport( return nil, err } if !ex { - return nil, fmt.Errorf("don't find domain_name with id %s (id must be ", d.Id()) + return nil, fmt.Errorf("don't find domain_name with id %s (id must be )", d.Id()) } cfg, err := readDomainOptions(ctx, id, m) if err != nil { diff --git a/bastion/resource_domain_account.go b/bastion/resource_domain_account.go index 61130cc..5a2c826 100644 --- a/bastion/resource_domain_account.go +++ b/bastion/resource_domain_account.go @@ -3,13 +3,14 @@ package bastion import ( "context" "encoding/json" + "errors" "fmt" "net/http" + "slices" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonDomainAccount struct { @@ -105,7 +106,7 @@ func resourceDomainAccount() *schema.Resource { } func resourceDomainAccountVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -213,7 +214,7 @@ func resourceDomainAccountImport( } idSplit := strings.Split(d.Id(), "/") if len(idSplit) != 2 { - return nil, fmt.Errorf("id must be /") + return nil, errors.New("id must be /") } id, ex, err := searchResourceDomainAccount(ctx, idSplit[0], idSplit[1], m) if err != nil { @@ -221,7 +222,7 @@ func resourceDomainAccountImport( } if !ex { return nil, fmt.Errorf("don't find account_name with id %s "+ - "(id must be /", d.Id()) + "(id must be /)", d.Id()) } cfg, err := readDomainAccountOptions(ctx, idSplit[0], id, m) if err != nil { @@ -337,7 +338,7 @@ func prepareDomainAccountJSON(d *schema.ResourceData) (jsonDomainAccount, error) for i, v := range listResources { vSplt := strings.Split(v.(string), ":") if len(vSplt) != 2 { - return jsonData, fmt.Errorf("resource must have format device:service or application:APP") + return jsonData, errors.New("resource must have format device:service or application:APP") } resources[i] = v.(string) } diff --git a/bastion/resource_domain_account_credential.go b/bastion/resource_domain_account_credential.go index 5f8c771..af50148 100644 --- a/bastion/resource_domain_account_credential.go +++ b/bastion/resource_domain_account_credential.go @@ -3,14 +3,15 @@ package bastion import ( "context" "encoding/json" + "errors" "fmt" "net/http" + "slices" "strings" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) func resourceDomainAccountCredential() *schema.Resource { @@ -65,7 +66,7 @@ func resourceDomainAccountCredential() *schema.Resource { } func resourceDomainAccountCredentialVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -185,7 +186,7 @@ func resourceDomainAccountCredentialImport( } idSplit := strings.Split(d.Id(), "/") if len(idSplit) != 3 { - return nil, fmt.Errorf("id must be //") + return nil, errors.New("id must be //") } id, ex, err := searchResourceDomainAccountCredential(ctx, idSplit[0], idSplit[1], idSplit[2], m) if err != nil { @@ -193,7 +194,7 @@ func resourceDomainAccountCredentialImport( } if !ex { return nil, fmt.Errorf("don't find credential with id %s "+ - "(id must be //", d.Id()) + "(id must be //)", d.Id()) } cfg, err := readDomainAccountCredentialOptions(ctx, idSplit[0], idSplit[1], id, m) if err != nil { diff --git a/bastion/resource_externalauth_kerberos.go b/bastion/resource_externalauth_kerberos.go index f121a44..8715a9b 100644 --- a/bastion/resource_externalauth_kerberos.go +++ b/bastion/resource_externalauth_kerberos.go @@ -5,11 +5,11 @@ import ( "encoding/json" "fmt" "net/http" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonExternalAuthKerberos struct { @@ -79,7 +79,7 @@ func resourceExternalAuthKerberos() *schema.Resource { } func resourceExternalAuthKerberosVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -181,7 +181,7 @@ func resourceExternalAuthKerberosImport( return nil, err } if !ex { - return nil, fmt.Errorf("don't find authentication_name with id %s (id must be ", d.Id()) + return nil, fmt.Errorf("don't find authentication_name with id %s (id must be )", d.Id()) } cfg, err := readExternalAuthKerberosOptions(ctx, id, m) if err != nil { diff --git a/bastion/resource_externalauth_ldap.go b/bastion/resource_externalauth_ldap.go index 67d8dc2..880fd06 100644 --- a/bastion/resource_externalauth_ldap.go +++ b/bastion/resource_externalauth_ldap.go @@ -5,11 +5,11 @@ import ( "encoding/json" "fmt" "net/http" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonExternalAuthLdap struct { @@ -138,7 +138,7 @@ func resourceExternalAuthLdap() *schema.Resource { } func resourceExternalAuthLdapVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -248,7 +248,7 @@ func resourceExternalAuthLdapImport( return nil, err } if !ex { - return nil, fmt.Errorf("don't find authentication_name with id %s (id must be ", d.Id()) + return nil, fmt.Errorf("don't find authentication_name with id %s (id must be )", d.Id()) } cfg, err := readExternalAuthLdapOptions(ctx, id, m) if err != nil { diff --git a/bastion/resource_externalauth_radius.go b/bastion/resource_externalauth_radius.go index 3b379f4..c8a3f89 100644 --- a/bastion/resource_externalauth_radius.go +++ b/bastion/resource_externalauth_radius.go @@ -5,11 +5,11 @@ import ( "encoding/json" "fmt" "net/http" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonExternalAuthRadius struct { @@ -69,7 +69,7 @@ func resourceExternalAuthRadius() *schema.Resource { } func resourceExternalAuthRadiusVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -171,7 +171,7 @@ func resourceExternalAuthRadiusImport( return nil, err } if !ex { - return nil, fmt.Errorf("don't find authentication_name with id %s (id must be ", d.Id()) + return nil, fmt.Errorf("don't find authentication_name with id %s (id must be )", d.Id()) } cfg, err := readExternalAuthRadiusOptions(ctx, id, m) if err != nil { diff --git a/bastion/resource_externalauth_saml.go b/bastion/resource_externalauth_saml.go index 552b382..7038e9b 100644 --- a/bastion/resource_externalauth_saml.go +++ b/bastion/resource_externalauth_saml.go @@ -5,30 +5,39 @@ import ( "encoding/json" "fmt" "net/http" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonExternalAuthSaml struct { - Timeout float64 `json:"timeout"` - ID string `json:"id,omitempty"` - AuthenticationName string `json:"authentication_name"` - Certificate string `json:"certificate"` - Description string `json:"description"` - IDPEntityID string `json:"idp_entity_id,omitempty"` - IDPMetadata string `json:"idp_metadata"` - Passphrase string `json:"passphrase,omitempty"` - PrivateKey string `json:"private_key"` - SamlRequestMethod string `json:"saml_request_method,omitempty"` - SamlRequestURL string `json:"saml_request_url,omitempty"` - SPAssertionConsumerService string `json:"sp_assertion_consumer_service,omitempty"` - SPEntityID string `json:"sp_entity_id,omitempty"` - SPMetadata string `json:"sp_metadata,omitempty"` - SPSingleLogoutService string `json:"sp_single_logout_service,omitempty"` - Type string `json:"type"` + Timeout float64 `json:"timeout"` + ID string `json:"id,omitempty"` + AuthenticationName string `json:"authentication_name"` + Certificate string `json:"certificate"` + Description string `json:"description"` + IDPEntityID string `json:"idp_entity_id,omitempty"` + IDPMetadata string `json:"idp_metadata"` + Passphrase string `json:"passphrase,omitempty"` + PrivateKey string `json:"private_key"` + SamlRequestMethod string `json:"saml_request_method,omitempty"` + SamlRequestURL string `json:"saml_request_url,omitempty"` + SPAssertionConsumerService string `json:"sp_assertion_consumer_service,omitempty"` + SPEntityID string `json:"sp_entity_id,omitempty"` + SPMetadata string `json:"sp_metadata,omitempty"` + SPSingleLogoutService string `json:"sp_single_logout_service,omitempty"` + Type string `json:"type"` + ClaimCustomization *jsonExternalAuthSamlClaimCustomization `json:"claim_customization,omitempty"` +} + +type jsonExternalAuthSamlClaimCustomization struct { + Username string `json:"username"` + Displayname string `json:"displayname"` + Email string `json:"email"` + Language string `json:"language"` + Group string `json:"group"` } func resourceExternalAuthSaml() *schema.Resource { @@ -59,6 +68,35 @@ func resourceExternalAuthSaml() *schema.Resource { Optional: true, Sensitive: true, }, + "claim_customization": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "username": { + Type: schema.TypeString, + Required: true, + }, + "displayname": { + Type: schema.TypeString, + Optional: true, + }, + "email": { + Type: schema.TypeString, + Optional: true, + }, + "language": { + Type: schema.TypeString, + Optional: true, + }, + "group": { + Type: schema.TypeString, + Optional: true, + }, + }, + }, + }, "description": { Type: schema.TypeString, Optional: true, @@ -107,7 +145,7 @@ func resourceExternalAuthSaml() *schema.Resource { } func resourceExternalAuthSamlVersionCheck(version string) error { - if bchk.InSlice(version, []string{VersionWallixAPI38}) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -209,7 +247,7 @@ func resourceExternalAuthSamlImport( return nil, err } if !ex { - return nil, fmt.Errorf("don't find authentication_name with id %s (id must be ", d.Id()) + return nil, fmt.Errorf("don't find authentication_name with id %s (id must be )", d.Id()) } cfg, err := readExternalAuthSamlOptions(ctx, id, m) if err != nil { @@ -296,7 +334,7 @@ func deleteExternalAuthSaml( } func prepareExternalAuthSamlJSON(d *schema.ResourceData) jsonExternalAuthSaml { - return jsonExternalAuthSaml{ + jsonData := jsonExternalAuthSaml{ AuthenticationName: d.Get("authentication_name").(string), Type: "SAML", IDPMetadata: d.Get("idp_metadata").(string), @@ -306,6 +344,21 @@ func prepareExternalAuthSamlJSON(d *schema.ResourceData) jsonExternalAuthSaml { Passphrase: d.Get("passphrase").(string), PrivateKey: d.Get("private_key").(string), } + for _, v := range d.Get("claim_customization").([]interface{}) { + if v == nil { + continue + } + m := v.(map[string]interface{}) + jsonData.ClaimCustomization = &jsonExternalAuthSamlClaimCustomization{ + Username: m["username"].(string), + Displayname: m["displayname"].(string), + Email: m["email"].(string), + Language: m["language"].(string), + Group: m["group"].(string), + } + } + + return jsonData } func readExternalAuthSamlOptions( diff --git a/bastion/resource_externalauth_saml_test.go b/bastion/resource_externalauth_saml_test.go index 0761484..7a12e32 100644 --- a/bastion/resource_externalauth_saml_test.go +++ b/bastion/resource_externalauth_saml_test.go @@ -5,14 +5,69 @@ import ( "os" "testing" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" "github.com/wallix/terraform-provider-wallix-bastion/bastion" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" ) +func TestAccResourceExternalAuthSaml_basic38(t *testing.T) { + if v := os.Getenv("WALLIX_BASTION_API_VERSION"); v == bastion.VersionWallixAPI38 { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + ExternalProviders: map[string]resource.ExternalProvider{ + "tls": { + Source: "hashicorp/tls", + VersionConstraint: "~> 4.0", + }, + }, + Steps: []resource.TestStep{ + { + Config: testAccResourceExternalAuthSaml38Create(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet( + "wallix-bastion_externalauth_saml.testacc_ExternalAuthSaml", + "id"), + resource.TestCheckResourceAttrSet( + "wallix-bastion_externalauth_saml.testacc_ExternalAuthSaml", + "idp_entity_id"), + resource.TestCheckResourceAttrSet( + "wallix-bastion_externalauth_saml.testacc_ExternalAuthSaml", + "saml_request_url"), + resource.TestCheckResourceAttrSet( + "wallix-bastion_externalauth_saml.testacc_ExternalAuthSaml", + "saml_request_method"), + resource.TestCheckResourceAttrSet( + "wallix-bastion_externalauth_saml.testacc_ExternalAuthSaml", + "sp_metadata"), + resource.TestCheckResourceAttrSet( + "wallix-bastion_externalauth_saml.testacc_ExternalAuthSaml", + "sp_entity_id"), + resource.TestCheckResourceAttrSet( + "wallix-bastion_externalauth_saml.testacc_ExternalAuthSaml", + "sp_assertion_consumer_service"), + resource.TestCheckResourceAttrSet( + "wallix-bastion_externalauth_saml.testacc_ExternalAuthSaml", + "sp_single_logout_service"), + ), + }, + { + Config: testAccResourceExternalAuthSaml38Update(), + }, + { + ResourceName: "wallix-bastion_externalauth_saml.testacc_ExternalAuthSaml", + ImportState: true, + ImportStateId: "testacc_ExternalAuthSaml", + }, + }, + PreventPostDestroyRefresh: true, + }) + } +} + func TestAccResourceExternalAuthSaml_basic(t *testing.T) { if v := os.Getenv("WALLIX_BASTION_API_VERSION"); v != "" && - v != bastion.VersionWallixAPI33 && - v != bastion.VersionWallixAPI36 { + v != bastion.VersionWallixAPI38 { resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, @@ -92,6 +147,18 @@ const ( ` ) +func testAccResourceExternalAuthSaml38Create() string { + return fmt.Sprintf(` +resource "wallix-bastion_externalauth_saml" "testacc_ExternalAuthSaml" { + authentication_name = "testacc_ExternalAuthSaml" + idp_metadata = <", d.Id()) + return nil, fmt.Errorf("don't find authentication_name with id %s (id must be )", d.Id()) } cfg, err := readExternalAuthTacacsOptions(ctx, id, m) if err != nil { diff --git a/bastion/resource_ldapdomain.go b/bastion/resource_ldapdomain.go deleted file mode 100644 index a9e0318..0000000 --- a/bastion/resource_ldapdomain.go +++ /dev/null @@ -1,411 +0,0 @@ -package bastion - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - - govers "github.com/hashicorp/go-version" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" -) - -type jsonLdapDomain struct { - CheckX509SanEmail bool `json:"check_x509_san_email"` - IsDefault bool `json:"is_default"` - DomainName string `json:"domain_name,omitempty"` - DefaultLanguage string `json:"default_language"` - DefaultEmailDomain string `json:"default_email_domain"` - Description string `json:"description"` - DisplayNameAttribute string `json:"display_name_attribute"` - EmailAttribute string `json:"email_attribute"` - LdapDomainName string `json:"ldap_domain_name"` - LanguageAttribute string `json:"language_attribute"` - GroupAttribute string `json:"group_attribute"` - SanDomainName string `json:"san_domain_name"` - X509Condition string `json:"x509_condition"` - X509SearchFilter string `json:"x509_search_filter"` - ExternalLdaps []string `json:"external_ldaps"` - SecondaryAuth []string `json:"secondary_auth"` -} - -func resourceLdapDomain() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceLdapDomainCreate, - ReadContext: resourceLdapDomainRead, - UpdateContext: resourceLdapDomainUpdate, - DeleteContext: resourceLdapDomainDelete, - Importer: &schema.ResourceImporter{ - State: resourceLdapDomainImport, - }, - Schema: map[string]*schema.Schema{ - "domain_name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "ldap_domain_name": { - Type: schema.TypeString, - Required: true, - }, - "external_ldaps": { - Type: schema.TypeList, - Required: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "default_language": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringInSlice([]string{"de", "en", "es", "fr", "ru"}, false), - }, - "default_email_domain": { - Type: schema.TypeString, - Required: true, - }, - "secondary_auth": { - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "description": { - Type: schema.TypeString, - Optional: true, - }, - "check_x509_san_email": { - Type: schema.TypeBool, - Optional: true, - }, - "display_name_attribute": { - Type: schema.TypeString, - Optional: true, - }, - "email_attribute": { - Type: schema.TypeString, - Optional: true, - }, - "group_attribute": { - Type: schema.TypeString, - Optional: true, - }, - "is_default": { - Type: schema.TypeBool, - Optional: true, - }, - "language_attribute": { - Type: schema.TypeString, - Optional: true, - }, - "san_domain_name": { - Type: schema.TypeString, - Optional: true, - }, - "x509_condition": { - Type: schema.TypeString, - Optional: true, - }, - "x509_search_filter": { - Type: schema.TypeString, - Optional: true, - }, - }, - } -} - -func resourceLdapDomainVersionCheck(version string) error { - if bchk.InSlice(version, []string{VersionWallixAPI33, VersionWallixAPI36}) { - return nil - } - if vers, err := govers.NewVersion(version); err == nil { - versionResourceRename, _ := govers.NewVersion(VersionWallixAPI38) - if vers.GreaterThanOrEqual(versionResourceRename) { - return fmt.Errorf( - "resource wallix-bastion_ldapdomain not available with api version %s\n"+ - " use wallix-bastion_authdomain_ldap instead", - version) - } - } - - return fmt.Errorf("resource wallix-bastion_ldapdomain not available with api version %s", version) -} - -func resourceLdapDomainCreate( - ctx context.Context, d *schema.ResourceData, m interface{}, -) diag.Diagnostics { - c := m.(*Client) - if err := resourceLdapDomainVersionCheck(c.bastionAPIVersion); err != nil { - return diag.FromErr(err) - } - ex, err := checkResourceLdapDomainExists(ctx, d.Get("domain_name").(string), m) - if err != nil { - return diag.FromErr(err) - } - if ex { - return diag.FromErr(fmt.Errorf("domain_name %s already exists", d.Get("domain_name").(string))) - } - err = addLdapDomain(ctx, d, m) - if err != nil { - return diag.FromErr(err) - } - d.SetId(d.Get("domain_name").(string)) - - return resourceLdapDomainRead(ctx, d, m) -} - -func resourceLdapDomainRead( - ctx context.Context, d *schema.ResourceData, m interface{}, -) diag.Diagnostics { - c := m.(*Client) - if err := resourceLdapDomainVersionCheck(c.bastionAPIVersion); err != nil { - return diag.FromErr(err) - } - cfg, err := readLdapDomainOptions(ctx, d.Id(), m) - if err != nil { - return diag.FromErr(err) - } - if cfg.DomainName == "" { - d.SetId("") - } else { - fillLdapDomain(d, cfg) - } - - return nil -} - -func resourceLdapDomainUpdate( - ctx context.Context, d *schema.ResourceData, m interface{}, -) diag.Diagnostics { - d.Partial(true) - c := m.(*Client) - if err := resourceLdapDomainVersionCheck(c.bastionAPIVersion); err != nil { - return diag.FromErr(err) - } - if err := updateLdapDomain(ctx, d, m); err != nil { - return diag.FromErr(err) - } - d.Partial(false) - - return resourceLdapDomainRead(ctx, d, m) -} - -func resourceLdapDomainDelete( - ctx context.Context, d *schema.ResourceData, m interface{}, -) diag.Diagnostics { - c := m.(*Client) - if err := resourceLdapDomainVersionCheck(c.bastionAPIVersion); err != nil { - return diag.FromErr(err) - } - if err := deleteLdapDomain(ctx, d, m); err != nil { - return diag.FromErr(err) - } - - return nil -} - -func resourceLdapDomainImport( - d *schema.ResourceData, m interface{}, -) ( - []*schema.ResourceData, error, -) { - ctx := context.Background() - c := m.(*Client) - if err := resourceLdapDomainVersionCheck(c.bastionAPIVersion); err != nil { - return nil, err - } - ex, err := checkResourceLdapDomainExists(ctx, d.Id(), m) - if err != nil { - return nil, err - } - if !ex { - return nil, fmt.Errorf("don't find domain_name with id %s (id must be ", d.Id()) - } - cfg, err := readLdapDomainOptions(ctx, d.Id(), m) - if err != nil { - return nil, err - } - fillLdapDomain(d, cfg) - result := make([]*schema.ResourceData, 1) - result[0] = d - - return result, nil -} - -func checkResourceLdapDomainExists( - ctx context.Context, domainName string, m interface{}, -) ( - bool, error, -) { - c := m.(*Client) - body, code, err := c.newRequest(ctx, "/ldapdomains/"+domainName, http.MethodGet, nil) - if err != nil { - return false, err - } - if code == http.StatusNotFound { - return false, nil - } - if code != http.StatusOK { - return false, fmt.Errorf("api doesn't return OK: %d with body:\n%s", code, body) - } - - return true, nil -} - -func addLdapDomain( - ctx context.Context, d *schema.ResourceData, m interface{}, -) error { - c := m.(*Client) - jsonData := prepareLdapDomainJSON(d, true) - body, code, err := c.newRequest(ctx, "/ldapdomains/", http.MethodPost, jsonData) - if err != nil { - return err - } - if code != http.StatusOK && code != http.StatusNoContent { - return fmt.Errorf("api doesn't return OK or NoContent: %d with body:\n%s", code, body) - } - - return nil -} - -func updateLdapDomain( - ctx context.Context, d *schema.ResourceData, m interface{}, -) error { - c := m.(*Client) - jsonData := prepareLdapDomainJSON(d, false) - body, code, err := c.newRequest(ctx, "/ldapdomains/"+d.Id()+"?force=true", http.MethodPut, jsonData) - if err != nil { - return err - } - if code != http.StatusOK && code != http.StatusNoContent { - return fmt.Errorf("api doesn't return OK or NoContent: %d with body:\n%s", code, body) - } - - return nil -} - -func deleteLdapDomain( - ctx context.Context, d *schema.ResourceData, m interface{}, -) error { - c := m.(*Client) - body, code, err := c.newRequest(ctx, "/ldapdomains/"+d.Id(), http.MethodDelete, nil) - if err != nil { - return err - } - if code != http.StatusOK && code != http.StatusNoContent { - return fmt.Errorf("api doesn't return OK or NoContent: %d with body:\n%s", code, body) - } - - return nil -} - -func prepareLdapDomainJSON(d *schema.ResourceData, newResource bool) jsonLdapDomain { - jsonData := jsonLdapDomain{ - LdapDomainName: d.Get("ldap_domain_name").(string), - DefaultLanguage: d.Get("default_language").(string), - DefaultEmailDomain: d.Get("default_email_domain").(string), - Description: d.Get("description").(string), - CheckX509SanEmail: d.Get("check_x509_san_email").(bool), - DisplayNameAttribute: d.Get("display_name_attribute").(string), - EmailAttribute: d.Get("email_attribute").(string), - GroupAttribute: d.Get("group_attribute").(string), - IsDefault: d.Get("is_default").(bool), - LanguageAttribute: d.Get("language_attribute").(string), - SanDomainName: d.Get("san_domain_name").(string), - X509Condition: d.Get("x509_condition").(string), - X509SearchFilter: d.Get("x509_search_filter").(string), - } - if newResource { - jsonData.DomainName = d.Get("domain_name").(string) - } - - listExternalLdaps := d.Get("external_ldaps").([]interface{}) - jsonData.ExternalLdaps = make([]string, len(listExternalLdaps)) - for i, v := range listExternalLdaps { - jsonData.ExternalLdaps[i] = v.(string) - } - - listSecondaryAuth := d.Get("secondary_auth").([]interface{}) - jsonData.SecondaryAuth = make([]string, len(listSecondaryAuth)) - for i, v := range listSecondaryAuth { - jsonData.SecondaryAuth[i] = v.(string) - } - - return jsonData -} - -func readLdapDomainOptions( - ctx context.Context, domainName string, m interface{}, -) ( - jsonLdapDomain, error, -) { - c := m.(*Client) - var result jsonLdapDomain - body, code, err := c.newRequest(ctx, "/ldapdomains/"+domainName, http.MethodGet, nil) - if err != nil { - return result, err - } - if code == http.StatusNotFound { - return result, nil - } - if code != http.StatusOK { - return result, fmt.Errorf("api doesn't return OK: %d with body:\n%s", code, body) - } - err = json.Unmarshal([]byte(body), &result) - if err != nil { - return result, fmt.Errorf("unmarshaling json: %w", err) - } - - return result, nil -} - -func fillLdapDomain(d *schema.ResourceData, jsonData jsonLdapDomain) { - if tfErr := d.Set("domain_name", jsonData.DomainName); tfErr != nil { - panic(tfErr) - } - if tfErr := d.Set("ldap_domain_name", jsonData.LdapDomainName); tfErr != nil { - panic(tfErr) - } - if tfErr := d.Set("external_ldaps", jsonData.ExternalLdaps); tfErr != nil { - panic(tfErr) - } - if tfErr := d.Set("default_language", jsonData.DefaultLanguage); tfErr != nil { - panic(tfErr) - } - if tfErr := d.Set("default_email_domain", jsonData.DefaultEmailDomain); tfErr != nil { - panic(tfErr) - } - if tfErr := d.Set("description", jsonData.Description); tfErr != nil { - panic(tfErr) - } - if tfErr := d.Set("check_x509_san_email", jsonData.CheckX509SanEmail); tfErr != nil { - panic(tfErr) - } - if tfErr := d.Set("group_attribute", jsonData.GroupAttribute); tfErr != nil { - panic(tfErr) - } - if tfErr := d.Set("display_name_attribute", jsonData.DisplayNameAttribute); tfErr != nil { - panic(tfErr) - } - if tfErr := d.Set("email_attribute", jsonData.EmailAttribute); tfErr != nil { - panic(tfErr) - } - if tfErr := d.Set("is_default", jsonData.IsDefault); tfErr != nil { - panic(tfErr) - } - if tfErr := d.Set("language_attribute", jsonData.LanguageAttribute); tfErr != nil { - panic(tfErr) - } - if tfErr := d.Set("san_domain_name", jsonData.SanDomainName); tfErr != nil { - panic(tfErr) - } - if tfErr := d.Set("secondary_auth", jsonData.SecondaryAuth); tfErr != nil { - panic(tfErr) - } - if tfErr := d.Set("x509_condition", jsonData.X509Condition); tfErr != nil { - panic(tfErr) - } - if tfErr := d.Set("x509_search_filter", jsonData.X509SearchFilter); tfErr != nil { - panic(tfErr) - } -} diff --git a/bastion/resource_ldapdomain_test.go b/bastion/resource_ldapdomain_test.go deleted file mode 100644 index a89621c..0000000 --- a/bastion/resource_ldapdomain_test.go +++ /dev/null @@ -1,88 +0,0 @@ -package bastion_test - -import ( - "os" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/wallix/terraform-provider-wallix-bastion/bastion" -) - -func TestAccResourceLDAPDomain_basic(t *testing.T) { - if v := os.Getenv("WALLIX_BASTION_API_VERSION"); v == "" || - v == bastion.VersionWallixAPI33 || - v == bastion.VersionWallixAPI36 { - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - Steps: []resource.TestStep{ - { - Config: testAccResourceLDAPDomainCreate(), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet( - "wallix-bastion_ldapdomain.testacc_LDAPDomain", - "id"), - ), - }, - { - Config: testAccResourceLDAPDomainUpdate(), - }, - { - ResourceName: "wallix-bastion_ldapdomain.testacc_LDAPDomain", - ImportState: true, - ImportStateId: "testacc_LDAPDomain", - }, - }, - PreventPostDestroyRefresh: true, - }) - } -} - -func testAccResourceLDAPDomainCreate() string { - return ` -resource "wallix-bastion_ldapdomain" "testacc_LDAPDomain" { - domain_name = "testacc_LDAPDomain" - ldap_domain_name = "test.com" - external_ldaps = [wallix-bastion_externalauth_ldap.testacc_LDAPDomain.authentication_name] - default_language = "fr" - default_email_domain = "test.com" -} -resource "wallix-bastion_externalauth_ldap" "testacc_LDAPDomain" { - authentication_name = "testacc_LDAPDomain" - cn_attribute = "sAMAccountName" - host = "server1" - ldap_base = "OU=FR,DC=test,DC=com" - login_attribute = "sAMAccountName" - port = 636 - timeout = 10 - is_ssl = true - is_anonymous_access = true -} -` -} - -func testAccResourceLDAPDomainUpdate() string { - return ` -resource "wallix-bastion_ldapdomain" "testacc_LDAPDomain" { - domain_name = "testacc_LDAPDomain" - ldap_domain_name = "test.com" - external_ldaps = [wallix-bastion_externalauth_ldap.testacc_LDAPDomain.authentication_name] - default_language = "fr" - default_email_domain = "test.com" - description = "testacc LDAPDomain" - display_name_attribute = "displayName" - language_attribute = "preferredLanguage" -} -resource "wallix-bastion_externalauth_ldap" "testacc_LDAPDomain" { - authentication_name = "testacc_LDAPDomain" - cn_attribute = "sAMAccountName" - host = "server1" - ldap_base = "OU=FR,DC=test,DC=com" - login_attribute = "sAMAccountName" - port = 636 - timeout = 10 - is_ssl = true - is_anonymous_access = true -} -` -} diff --git a/bastion/resource_ldapmapping.go b/bastion/resource_ldapmapping.go deleted file mode 100644 index 17a9084..0000000 --- a/bastion/resource_ldapmapping.go +++ /dev/null @@ -1,238 +0,0 @@ -package bastion - -import ( - "context" - "encoding/json" - "fmt" - "net/http" - "net/url" - "strings" - - govers "github.com/hashicorp/go-version" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - bchk "github.com/jeremmfr/go-utils/basiccheck" -) - -type jsonLdapMapping struct { - Domain string `json:"domain"` - UserGroup string `json:"user_group"` - LdapGroup string `json:"ldap_group"` -} - -func resourceLdapMapping() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceLdapMappingCreate, - ReadContext: resourceLdapMappingRead, - DeleteContext: resourceLdapMappingDelete, - Importer: &schema.ResourceImporter{ - State: resourceLdapMappingImport, - }, - Schema: map[string]*schema.Schema{ - "domain": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "user_group": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - "ldap_group": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - }, - } -} - -func resourceLdapMappingVersionCheck(version string) error { - if bchk.InSlice(version, []string{VersionWallixAPI33, VersionWallixAPI36}) { - return nil - } - if vers, err := govers.NewVersion(version); err == nil { - versionResourceRename, _ := govers.NewVersion(VersionWallixAPI38) - if vers.GreaterThanOrEqual(versionResourceRename) { - return fmt.Errorf( - "resource wallix-bastion_ldapmapping not available with api version %s\n"+ - " use wallix-bastion_authdomain_mapping instead", - version) - } - } - - return fmt.Errorf("resource wallix-bastion_ldapmapping not available with api version %s", version) -} - -func resourceLdapMappingCreate( - ctx context.Context, d *schema.ResourceData, m interface{}, -) diag.Diagnostics { - c := m.(*Client) - if err := resourceLdapMappingVersionCheck(c.bastionAPIVersion); err != nil { - return diag.FromErr(err) - } - ex, err := checkResourceLdapMappingExists(ctx, - d.Get("domain").(string), d.Get("user_group").(string), d.Get("ldap_group").(string), m) - if err != nil { - return diag.FromErr(err) - } - if ex { - return diag.FromErr(fmt.Errorf("ldapmapping %s/%s/%s already exists", - d.Get("domain").(string), d.Get("user_group").(string), d.Get("ldap_group").(string))) - } - err = addLdapMapping(ctx, d, m) - if err != nil { - return diag.FromErr(err) - } - d.SetId(d.Get("domain").(string) + "/" + d.Get("user_group").(string) + "/" + d.Get("ldap_group").(string)) - - return nil -} - -func resourceLdapMappingRead( - ctx context.Context, d *schema.ResourceData, m interface{}, -) diag.Diagnostics { - c := m.(*Client) - if err := resourceLdapMappingVersionCheck(c.bastionAPIVersion); err != nil { - return diag.FromErr(err) - } - ex, err := checkResourceLdapMappingExists(ctx, - d.Get("domain").(string), d.Get("user_group").(string), d.Get("ldap_group").(string), m) - if err != nil { - return diag.FromErr(err) - } - if !ex { - d.SetId("") - } - - return nil -} - -func resourceLdapMappingDelete( - ctx context.Context, d *schema.ResourceData, m interface{}, -) diag.Diagnostics { - c := m.(*Client) - if err := resourceLdapMappingVersionCheck(c.bastionAPIVersion); err != nil { - return diag.FromErr(err) - } - if err := deleteLdapMapping(ctx, d, m); err != nil { - return diag.FromErr(err) - } - - return nil -} - -func resourceLdapMappingImport( - d *schema.ResourceData, m interface{}, -) ( - []*schema.ResourceData, error, -) { - ctx := context.Background() - c := m.(*Client) - if err := resourceLdapMappingVersionCheck(c.bastionAPIVersion); err != nil { - return nil, err - } - idSplit := strings.Split(d.Id(), "/") - if len(idSplit) != 3 { - return nil, fmt.Errorf("id must be //") - } - ex, err := checkResourceLdapMappingExists(ctx, idSplit[0], idSplit[1], idSplit[2], m) - if err != nil { - return nil, err - } - if !ex { - return nil, fmt.Errorf("don't find ldapmapping with id %s (id must be //", d.Id()) - } - cfg := jsonLdapMapping{ - Domain: idSplit[0], - UserGroup: idSplit[1], - LdapGroup: idSplit[2], - } - fillLdapMapping(d, cfg) - result := make([]*schema.ResourceData, 1) - result[0] = d - - return result, nil -} - -func checkResourceLdapMappingExists( - ctx context.Context, domain, userGroup, ldapGroup string, m interface{}, -) ( - bool, error, -) { - c := m.(*Client) - body, code, err := c.newRequest(ctx, - "/ldapmappings/?q=domain="+domain+url.QueryEscape("&&")+"user_group="+userGroup, http.MethodGet, nil) - if err != nil { - return false, err - } - if code != http.StatusOK { - return false, fmt.Errorf("api doesn't return OK: %d with body:\n%s", code, body) - } - var results []jsonLdapMapping - err = json.Unmarshal([]byte(body), &results) - if err != nil { - return false, fmt.Errorf("unmarshaling json: %w", err) - } - if len(results) == 1 && results[0].LdapGroup == ldapGroup { - return true, nil - } - - return false, nil -} - -func addLdapMapping( - ctx context.Context, d *schema.ResourceData, m interface{}, -) error { - c := m.(*Client) - jsonData := prepareLdapMappingJSON(d) - body, code, err := c.newRequest(ctx, "/ldapmappings/", http.MethodPost, jsonData) - if err != nil { - return err - } - if code != http.StatusOK && code != http.StatusNoContent { - return fmt.Errorf("api doesn't return OK or NoContent: %d with body:\n%s", code, body) - } - - return nil -} - -func deleteLdapMapping( - ctx context.Context, d *schema.ResourceData, m interface{}, -) error { - c := m.(*Client) - idSplit := strings.Split(d.Id(), "/") - if len(idSplit) != 3 { - return fmt.Errorf("id must be //") - } - body, code, err := c.newRequest(ctx, "/ldapmappings/"+idSplit[0]+"/"+idSplit[1]+"/"+idSplit[2], http.MethodDelete, nil) - if err != nil { - return err - } - if code != http.StatusOK && code != http.StatusNoContent { - return fmt.Errorf("api doesn't return OK or NoContent: %d with body:\n%s", code, body) - } - - return nil -} - -func prepareLdapMappingJSON(d *schema.ResourceData) jsonLdapMapping { - return jsonLdapMapping{ - Domain: d.Get("domain").(string), - UserGroup: d.Get("user_group").(string), - LdapGroup: d.Get("ldap_group").(string), - } -} - -func fillLdapMapping(d *schema.ResourceData, jsonData jsonLdapMapping) { - if tfErr := d.Set("domain", jsonData.Domain); tfErr != nil { - panic(tfErr) - } - if tfErr := d.Set("user_group", jsonData.UserGroup); tfErr != nil { - panic(tfErr) - } - if tfErr := d.Set("ldap_group", jsonData.LdapGroup); tfErr != nil { - panic(tfErr) - } -} diff --git a/bastion/resource_ldapmapping_test.go b/bastion/resource_ldapmapping_test.go deleted file mode 100644 index cfaea5f..0000000 --- a/bastion/resource_ldapmapping_test.go +++ /dev/null @@ -1,69 +0,0 @@ -package bastion_test - -import ( - "os" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/wallix/terraform-provider-wallix-bastion/bastion" -) - -func TestAccResourceLDAPMapping_basic(t *testing.T) { - if v := os.Getenv("WALLIX_BASTION_API_VERSION"); v == "" || - v == bastion.VersionWallixAPI33 || - v == bastion.VersionWallixAPI36 { - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - Steps: []resource.TestStep{ - { - Config: testAccResourceLDAPMappingCreate(), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet( - "wallix-bastion_ldapmapping.testacc_LDAPMapping", - "id"), - ), - }, - { - ResourceName: "wallix-bastion_ldapmapping.testacc_LDAPMapping", - ImportState: true, - ImportStateId: "testacc_LDAPMapping/testacc_LDAPMapping/CN=testacc,OU=FR,DC=test,DC=com", - }, - }, - PreventPostDestroyRefresh: true, - }) - } -} - -func testAccResourceLDAPMappingCreate() string { - return ` -resource "wallix-bastion_ldapdomain" "testacc_LDAPMapping" { - domain_name = "testacc_LDAPMapping" - ldap_domain_name = "test.com" - external_ldaps = [wallix-bastion_externalauth_ldap.testacc_LDAPMapping.authentication_name] - default_language = "fr" - default_email_domain = "test.com" -} -resource "wallix-bastion_externalauth_ldap" "testacc_LDAPMapping" { - authentication_name = "testacc_LDAPMapping" - cn_attribute = "sAMAccountName" - host = "server1" - ldap_base = "OU=FR,DC=test,DC=com" - login_attribute = "sAMAccountName" - port = 636 - timeout = 10 - is_ssl = true - is_anonymous_access = true -} -resource "wallix-bastion_usergroup" "testacc_LDAPMapping" { - group_name = "testacc_LDAPMapping" - timeframes = ["allthetime"] - profile = "user" -} -resource "wallix-bastion_ldapmapping" "testacc_LDAPMapping" { - domain = wallix-bastion_ldapdomain.testacc_LDAPMapping.domain_name - user_group = wallix-bastion_usergroup.testacc_LDAPMapping.group_name - ldap_group = "CN=testacc,OU=FR,DC=test,DC=com" -} -` -} diff --git a/bastion/resource_profile.go b/bastion/resource_profile.go index 932efbf..63e2c4f 100644 --- a/bastion/resource_profile.go +++ b/bastion/resource_profile.go @@ -5,11 +5,11 @@ import ( "encoding/json" "fmt" "net/http" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonProfile struct { @@ -59,10 +59,6 @@ type jsonProfile struct { } `json:"user_groups_limitation"` } -type profileFeatures struct { - withDashboards bool -} - func resourceProfile() *schema.Resource { return &schema.Resource{ CreateContext: resourceProfileCreate, @@ -274,11 +270,8 @@ func resourceProfile() *schema.Resource { } } -func resourceProfileVersionCheck(version string, features profileFeatures) error { - if features.withDashboards && version == VersionWallixAPI33 { - return fmt.Errorf("can't use dashboards with api version %s", version) - } - if bchk.InSlice(version, defaultVersionsValid()) { +func resourceProfileVersionCheck(version string) error { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -289,11 +282,7 @@ func resourceProfileCreate( ctx context.Context, d *schema.ResourceData, m interface{}, ) diag.Diagnostics { c := m.(*Client) - var features profileFeatures - if len(d.Get("dashboards").(*schema.Set).List()) > 0 { - features.withDashboards = true - } - if err := resourceProfileVersionCheck(c.bastionAPIVersion, features); err != nil { + if err := resourceProfileVersionCheck(c.bastionAPIVersion); err != nil { return diag.FromErr(err) } _, ex, err := searchResourceProfile(ctx, d.Get("profile_name").(string), m) @@ -303,7 +292,7 @@ func resourceProfileCreate( if ex { return diag.FromErr(fmt.Errorf("profile_name %s already exists", d.Get("profile_name").(string))) } - err = addProfile(ctx, d, m, features) + err = addProfile(ctx, d, m) if err != nil { return diag.FromErr(err) } @@ -323,7 +312,7 @@ func resourceProfileRead( ctx context.Context, d *schema.ResourceData, m interface{}, ) diag.Diagnostics { c := m.(*Client) - if err := resourceProfileVersionCheck(c.bastionAPIVersion, profileFeatures{}); err != nil { + if err := resourceProfileVersionCheck(c.bastionAPIVersion); err != nil { return diag.FromErr(err) } cfg, err := readProfileOptions(ctx, d.Id(), m) @@ -344,14 +333,10 @@ func resourceProfileUpdate( ) diag.Diagnostics { d.Partial(true) c := m.(*Client) - var features profileFeatures - if len(d.Get("dashboards").(*schema.Set).List()) > 0 { - features.withDashboards = true - } - if err := resourceProfileVersionCheck(c.bastionAPIVersion, features); err != nil { + if err := resourceProfileVersionCheck(c.bastionAPIVersion); err != nil { return diag.FromErr(err) } - if err := updateProfile(ctx, d, m, features); err != nil { + if err := updateProfile(ctx, d, m); err != nil { return diag.FromErr(err) } d.Partial(false) @@ -363,7 +348,7 @@ func resourceProfileDelete( ctx context.Context, d *schema.ResourceData, m interface{}, ) diag.Diagnostics { c := m.(*Client) - if err := resourceProfileVersionCheck(c.bastionAPIVersion, profileFeatures{}); err != nil { + if err := resourceProfileVersionCheck(c.bastionAPIVersion); err != nil { return diag.FromErr(err) } if err := deleteProfile(ctx, d, m); err != nil { @@ -380,7 +365,7 @@ func resourceProfileImport( ) { ctx := context.Background() c := m.(*Client) - if err := resourceProfileVersionCheck(c.bastionAPIVersion, profileFeatures{}); err != nil { + if err := resourceProfileVersionCheck(c.bastionAPIVersion); err != nil { return nil, err } id, ex, err := searchResourceProfile(ctx, d.Id(), m) @@ -388,7 +373,7 @@ func resourceProfileImport( return nil, err } if !ex { - return nil, fmt.Errorf("don't find profile_name with id %s (id must be ", d.Id()) + return nil, fmt.Errorf("don't find profile_name with id %s (id must be )", d.Id()) } cfg, err := readProfileOptions(ctx, id, m) if err != nil { @@ -431,10 +416,10 @@ func searchResourceProfile( } func addProfile( - ctx context.Context, d *schema.ResourceData, m interface{}, features profileFeatures, + ctx context.Context, d *schema.ResourceData, m interface{}, ) error { c := m.(*Client) - jsonData := prepareProfileJSON(d, true, features) + jsonData := prepareProfileJSON(d, true) body, code, err := c.newRequest(ctx, "/profiles/", http.MethodPost, jsonData) if err != nil { return err @@ -447,10 +432,10 @@ func addProfile( } func updateProfile( - ctx context.Context, d *schema.ResourceData, m interface{}, features profileFeatures, + ctx context.Context, d *schema.ResourceData, m interface{}, ) error { c := m.(*Client) - jsonData := prepareProfileJSON(d, false, features) + jsonData := prepareProfileJSON(d, false) body, code, err := c.newRequest(ctx, "/profiles/"+d.Id()+"?force=true", http.MethodPut, jsonData) if err != nil { return err @@ -478,7 +463,7 @@ func deleteProfile( } func prepareProfileJSON( //nolint: gocognit,gocyclo - d *schema.ResourceData, newResource bool, features profileFeatures, + d *schema.ResourceData, newResource bool, ) jsonProfile { jsonData := jsonProfile{ Description: d.Get("description").(string), @@ -579,8 +564,8 @@ func prepareProfileJSON( //nolint: gocognit,gocyclo } } - if features.withDashboards { - listDashboards := d.Get("dashboards").(*schema.Set).List() + listDashboards := d.Get("dashboards").(*schema.Set).List() + if len(listDashboards) > 0 { dashboards := make([]string, len(listDashboards)) for i, v := range listDashboards { dashboards[i] = v.(string) diff --git a/bastion/resource_profile_test.go b/bastion/resource_profile_test.go index fc9bf9c..0749de9 100644 --- a/bastion/resource_profile_test.go +++ b/bastion/resource_profile_test.go @@ -1,51 +1,40 @@ package bastion_test import ( - "os" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/wallix/terraform-provider-wallix-bastion/bastion" ) func TestAccResourceProfile_basic(t *testing.T) { resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - Steps: testAccResourceProfileSteps(), + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccResourceProfileCreate(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet( + "wallix-bastion_profile.testacc_Profile", + "id"), + ), + }, + { + Config: testAccResourceProfileUpdate(), + }, + { + ResourceName: "wallix-bastion_profile.testacc_Profile", + ImportState: true, + ImportStateId: "testacc_Profile", + }, + { + Config: testAccResourceProfileUpdate2(), + }, + }, PreventPostDestroyRefresh: true, }) } -func testAccResourceProfileSteps() []resource.TestStep { - steps := []resource.TestStep{ - { - Config: testAccResourceProfileCreate(), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrSet( - "wallix-bastion_profile.testacc_Profile", - "id"), - ), - }, - { - Config: testAccResourceProfileUpdate(), - }, - { - ResourceName: "wallix-bastion_profile.testacc_Profile", - ImportState: true, - ImportStateId: "testacc_Profile", - }, - } - if v := os.Getenv("WALLIX_BASTION_API_VERSION"); v != "" && - v != bastion.VersionWallixAPI33 { - steps = append(steps, resource.TestStep{ - Config: testAccResourceProfileUpdate2(), - }) - } - - return steps -} - func testAccResourceProfileCreate() string { return ` resource "wallix-bastion_profile" "testacc_Profile" { diff --git a/bastion/resource_targetgroup.go b/bastion/resource_targetgroup.go index 35c17ff..d760f61 100644 --- a/bastion/resource_targetgroup.go +++ b/bastion/resource_targetgroup.go @@ -3,13 +3,14 @@ package bastion import ( "context" "encoding/json" + "errors" "fmt" "net/http" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) const ( @@ -270,7 +271,7 @@ func resourceTargetGroup() *schema.Resource { } func resourceTargetGroupVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -372,7 +373,7 @@ func resourceTargetGroupImport( return nil, err } if !ex { - return nil, fmt.Errorf("don't find group_name with id %s (id must be ", d.Id()) + return nil, fmt.Errorf("don't find group_name with id %s (id must be )", d.Id()) } cfg, err := readTargetGroupOptions(ctx, id, m) if err != nil { @@ -481,17 +482,17 @@ func prepareTargetGroupJSON(d *schema.ResourceData) (jsonTargetGroup, error) { / case passwordRetrievalAccounts["domain_type"].(string) == domainTypeGlobal: if passwordRetrievalAccounts["device"].(string) != "" || passwordRetrievalAccounts["application"].(string) != "" { - return jsonData, fmt.Errorf("bad password_retrieval_accounts: " + + return jsonData, errors.New("bad password_retrieval_accounts: " + "device and application need to be null with domain_type=global") } case passwordRetrievalAccounts["domain_type"].(string) == domainTypeLocal: if passwordRetrievalAccounts["device"].(string) == "" && passwordRetrievalAccounts["application"].(string) == "" { - return jsonData, fmt.Errorf("bad password_retrieval_accounts: " + + return jsonData, errors.New("bad password_retrieval_accounts: " + "device or application need to be set with domain_type=local") } case passwordRetrievalAccounts["device"].(string) != "" && passwordRetrievalAccounts["application"].(string) != "": - return jsonData, fmt.Errorf("bad password_retrieval_accounts: " + + return jsonData, errors.New("bad password_retrieval_accounts: " + "device and application mutually exclusive") } jsonData.PasswordRetrieval.Accounts[i] = jsonTargerGroupPasswordRetrievalAccount{ @@ -521,13 +522,13 @@ func prepareTargetGroupJSON(d *schema.ResourceData) (jsonTargetGroup, error) { / switch { case (sessionAccounts["device"].(string) == "" || sessionAccounts["service"].(string) == "") && sessionAccounts["application"].(string) == "": - return jsonData, fmt.Errorf("bad session_accounts: " + + return jsonData, errors.New("bad session_accounts: " + "device/service or application need to be set") case sessionAccounts["device"].(string) != "" && sessionAccounts["application"].(string) != "": - return jsonData, fmt.Errorf("bad session_accounts: " + + return jsonData, errors.New("bad session_accounts: " + "device and application mutually exclusive") case sessionAccounts["service"].(string) != "" && sessionAccounts["application"].(string) != "": - return jsonData, fmt.Errorf("bad session_accounts: " + + return jsonData, errors.New("bad session_accounts: " + "service and application mutually exclusive") case sessionAccounts["device"].(string) != "" && sessionAccounts["service"].(string) == "": return jsonData, fmt.Errorf("bad session_accounts: "+ @@ -552,10 +553,10 @@ func prepareTargetGroupJSON(d *schema.ResourceData) (jsonTargetGroup, error) { / sessionAccountMappings := v.(map[string]interface{}) switch { case sessionAccountMappings["device"].(string) != "" && sessionAccountMappings["application"].(string) != "": - return jsonData, fmt.Errorf("bad session_account_mappings: " + + return jsonData, errors.New("bad session_account_mappings: " + "device and application mutually exclusive") case sessionAccountMappings["service"].(string) != "" && sessionAccountMappings["application"].(string) != "": - return jsonData, fmt.Errorf("bad session_account_mappings: " + + return jsonData, errors.New("bad session_account_mappings: " + "service and application mutually exclusive") case sessionAccountMappings["device"].(string) != "" && sessionAccountMappings["service"].(string) == "": return jsonData, fmt.Errorf("bad session_account_mappings: "+ @@ -577,10 +578,10 @@ func prepareTargetGroupJSON(d *schema.ResourceData) (jsonTargetGroup, error) { / sessionInteractiveLogins := v.(map[string]interface{}) switch { case sessionInteractiveLogins["device"].(string) != "" && sessionInteractiveLogins["application"].(string) != "": - return jsonData, fmt.Errorf("bad session_interactive_logins: " + + return jsonData, errors.New("bad session_interactive_logins: " + "device and application mutually exclusive") case sessionInteractiveLogins["service"].(string) != "" && sessionInteractiveLogins["application"].(string) != "": - return jsonData, fmt.Errorf("bad session_interactive_logins: " + + return jsonData, errors.New("bad session_interactive_logins: " + "service and application mutually exclusive") case sessionInteractiveLogins["device"].(string) != "" && sessionInteractiveLogins["service"].(string) == "": return jsonData, fmt.Errorf("bad session_interactive_logins: "+ @@ -604,17 +605,17 @@ func prepareTargetGroupJSON(d *schema.ResourceData) (jsonTargetGroup, error) { / case sessionScenarioAccounts["domain_type"].(string) == domainTypeGlobal: if sessionScenarioAccounts["device"].(string) != "" || sessionScenarioAccounts["application"].(string) != "" { - return jsonData, fmt.Errorf("bad session_scenario_accounts: " + + return jsonData, errors.New("bad session_scenario_accounts: " + "device and application need to be null with domain_type=global") } case sessionScenarioAccounts["domain_type"].(string) == domainTypeLocal: if sessionScenarioAccounts["device"].(string) == "" && sessionScenarioAccounts["application"].(string) == "" { - return jsonData, fmt.Errorf("bad session_scenario_accounts: " + + return jsonData, errors.New("bad session_scenario_accounts: " + "device or application need to be set with domain_type=local") } case sessionScenarioAccounts["device"].(string) != "" && sessionScenarioAccounts["application"].(string) != "": - return jsonData, fmt.Errorf("bad session_scenario_accounts: " + + return jsonData, errors.New("bad session_scenario_accounts: " + "device and application mutually exclusive") } jsonData.Session.ScenarioAccounts[i] = jsonTargetGroupSessionScenarioAccount{ diff --git a/bastion/resource_timeframe.go b/bastion/resource_timeframe.go index 070d37a..08514fc 100644 --- a/bastion/resource_timeframe.go +++ b/bastion/resource_timeframe.go @@ -6,11 +6,11 @@ import ( "fmt" "net/http" "regexp" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonTimeframe struct { @@ -92,7 +92,7 @@ func resourceTimeframe() *schema.Resource { } func resourceTimeframeVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -194,7 +194,7 @@ func resourceTimeframeImport( return nil, err } if !ex { - return nil, fmt.Errorf("don't find timeframe_name with id %s (id must be ", d.Id()) + return nil, fmt.Errorf("don't find timeframe_name with id %s (id must be )", d.Id()) } cfg, err := readTimeframeOptions(ctx, d.Id(), m) if err != nil { @@ -301,7 +301,7 @@ func prepareTimeframeJSON(d *schema.ResourceData) (jsonTimeframe, error) { listWeekDays := period["week_days"].(*schema.Set).List() jsonPeriod.WeekDays = make([]string, len(listWeekDays)) for ii, d := range listWeekDays { - if !bchk.InSlice(d.(string), []string{ + if !slices.Contains([]string{ "monday", "tuesday", "wednesday", @@ -309,7 +309,7 @@ func prepareTimeframeJSON(d *schema.ResourceData) (jsonTimeframe, error) { "friday", "saturday", "sunday", - }) { + }, d.(string)) { return jsonData, fmt.Errorf("`%s` isn't a valid week_day", d.(string)) } jsonPeriod.WeekDays[ii] = d.(string) diff --git a/bastion/resource_user.go b/bastion/resource_user.go index 90dcd1b..44b2be7 100644 --- a/bastion/resource_user.go +++ b/bastion/resource_user.go @@ -5,11 +5,11 @@ import ( "encoding/json" "fmt" "net/http" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonUser struct { @@ -107,7 +107,7 @@ func resourceUser() *schema.Resource { } func resourceUserVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -202,7 +202,7 @@ func resourceUserImport( return nil, err } if !ex { - return nil, fmt.Errorf("don't find user_name with id %s (id must be ", d.Id()) + return nil, fmt.Errorf("don't find user_name with id %s (id must be )", d.Id()) } cfg, err := readUserOptions(ctx, d.Id(), m) if err != nil { diff --git a/bastion/resource_usergroup.go b/bastion/resource_usergroup.go index be3b1a3..4409b69 100644 --- a/bastion/resource_usergroup.go +++ b/bastion/resource_usergroup.go @@ -5,11 +5,11 @@ import ( "encoding/json" "fmt" "net/http" + "slices" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - bchk "github.com/jeremmfr/go-utils/basiccheck" ) type jsonUserGroup struct { @@ -94,7 +94,7 @@ func resourceUserGroup() *schema.Resource { } func resourceUserGroupVersionCheck(version string) error { - if bchk.InSlice(version, defaultVersionsValid()) { + if slices.Contains(defaultVersionsValid(), version) { return nil } @@ -196,7 +196,7 @@ func resourceUserGroupImport( return nil, err } if !ex { - return nil, fmt.Errorf("don't find group_name with id %s (id must be ", d.Id()) + return nil, fmt.Errorf("don't find group_name with id %s (id must be )", d.Id()) } cfg, err := readUserGroupOptions(ctx, id, m) if err != nil { diff --git a/docs/index.md b/docs/index.md index 12ec003..139c19d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -4,32 +4,38 @@ The following arguments are supported in the `provider` block: -- **ip** (Required) - This is the target for bastion API connection (ip or dns name). +- **ip** (Required) + This is the target for bastion API connection (ip or dns name). It can also be sourced from the `WALLIX_BASTION_HOST` environment variable. -- **token** (Optional) - This is the token to authenticate on bastion API. - It can also be sourced from the `WALLIX_BASTION_TOKEN` environment variable. +- **user** (Required) + This is the username used to authenticate on bastion API. + It can also be sourced from the `WALLIX_BASTION_USER` environment variable. -- **port** (Optional) - This is the tcp port for https connection on bastion API. - It can also be sourced from the `WALLIX_BASTION_PORT` environment variable. - Defaults to `443`. +- **token** (Optional) + This is the token to authenticate on bastion API. + It can also be sourced from the `WALLIX_BASTION_TOKEN` environment variable. -- **user** (Optional) - This is the username used to authenticate on bastion API. - It can also be sourced from the `WALLIX_BASTION_USER` environment variable. +- **port** (Optional) + This is the tcp port for https connection on bastion API. + It can also be sourced from the `WALLIX_BASTION_PORT` environment variable. + Defaults to `443`. - **password** (Optional) This is the password used to authenticate against Bastion API. It can also be sourced from the `WALLIX_BASTION_PASSWORD`environment variable. -- **api_version** (Optional) - This is the version of api used to call api. - It can also be sourced from the `WALLIX_BASTION_API_VERSION` environment variable. - Defaults to `v3.3`. +- **api_version** (Optional) + This is the version of api used to call api. + It can also be sourced from the `WALLIX_BASTION_API_VERSION` environment variable. + Accepted Value `v3.8` or `v3.12` + Defaults to `v3.8`. - You have to specify either the API key **OR** the user/password couple. The latter is the recommanded authentication method. Create a dedicated account in the Bastion with the needed permissions according to which resources you plan to use. + +## Note regarding API v3.3 and v3.6 + +From version v0.14.0 were the support for old APIs. +If you need to use those versions please use v0.13.0 of this provider and think on upgrading your Bastion. diff --git a/docs/resources/application.md b/docs/resources/application.md index e6f396c..79aa00a 100644 --- a/docs/resources/application.md +++ b/docs/resources/application.md @@ -26,22 +26,38 @@ The following arguments are supported: The application name. - **connection_policy** (Required, String) The connection policy name. -- **paths** (Required, Set of Block) - Need to be specified multiple times for each target in cluster or once if target is a device's session. +- **category** (Optional, String) + The application category. + Default to `standard`. + Need to be `standard` or `jumphost`. +- **application_url** (Optional, String) + The application url. + `category` need to be `jumphost`. +- **browser** (Optional, String) + The application browser. + `category` need to be `jumphost`. +- **browser_version** (Optional, String) + The browser version. + `category` need to be `jumphost`. +- **description** - (Optional, String) + The application description. +- **global_domains** (Optional, List of String) + The global domains names. + `category` need to be `standard`. +- **parameters** (Optional, String) + The application parameters. +- **paths** (Optional, Set of Block) + Need to be specified when `category` = `standard`, + multiple times for each target in cluster or once if target is a device's session. - **target** (Required, String) The application target. - **program** (Required, String) The application path. - **working_dir** (Required, String) The application working directory. -- **target** (Required, String) - The application target/cluster name. -- **description** - (Optional, String) - The application description. -- **global_domains** (Optional, List of String) - The global domains names. -- **parameters** (Optional, String) - The application parameters. +- **target** (Optional, String) + The application target/cluster name. + Need to be specified when `category` = `standard` ## Attribute Reference diff --git a/docs/resources/connection_policy.md b/docs/resources/connection_policy.md index 5e178b3..c92cfe9 100644 --- a/docs/resources/connection_policy.md +++ b/docs/resources/connection_policy.md @@ -24,6 +24,10 @@ The following arguments are supported: - **protocol** (Required, String) The connection policy protocol. Need to be `SSH`, `RAWTCPIP`, `RDP`, `RLOGIN`, `TELNET` or `VNC`. +- **type** (Optional, String) + The connection policy type. + Default to value of `protocol`. + Need to be `SSH`, `RAWTCPIP`, `RDP`, `RDP-JUMPHOST`, `RLOGIN`, `TELNET` or `VNC`. - **description** (Optional, String) The connection policy description. - **authentication_methods** (Optional, Set of String) diff --git a/docs/resources/externalauth_saml.md b/docs/resources/externalauth_saml.md index 475e903..dd47291 100644 --- a/docs/resources/externalauth_saml.md +++ b/docs/resources/externalauth_saml.md @@ -25,6 +25,18 @@ The following arguments are supported: SAML request timeout. - **certificate** (Optional, String, Sensitive, **Value can't refresh**) The certificate of the Service Provider. +- **claim_customization** (Optional, Block) + A claim customization to bind the IDP attribute names with the SP ones. + - **username** (Required, String) + IDP attribute that correspond to username. + - **displayname** (Optional, String) + DP attribute that correspond to displayname. + - **email** (Optional, String) + DP attribute that correspond to email. + - **language** (Optional, String) + DP attribute that correspond to language. + - **group** (Optional, String) + DP attribute that correspond to group. - **description** (Optional, String) Description of the authentication. - **passphrase** (Optional, String, Sensitive, **Value can't refresh**) diff --git a/docs/resources/ldapdomain.md b/docs/resources/ldapdomain.md deleted file mode 100644 index e6ba46f..0000000 --- a/docs/resources/ldapdomain.md +++ /dev/null @@ -1,69 +0,0 @@ -# wallix-bastion_ldapdomain Resource - -Provides a ldapdomain resource. - --> **Note:** Since version `v3.8` of the API, use the `wallix-bastion_authdomain_ldap` resource instead - -## Example Usage - -```hcl -# Configure a LDAP domain -resource "wallix-bastion_ldapdomain" "example_com" { - domain_name = "example.com" - ldap_domain_name = "example.com" - external_ldaps = "server1" - default_language = "fr" - default_email_domain = "example.com" -} -``` - -## Argument Reference - -The following arguments are supported: - -- **domain_name** (Required, String, Forces new resource) - The domain name. -- **ldap_domain_name** (Required, String) - The LDAP domain name. -- **external_ldaps** (Required, List of String) - The LDAP external authentications. -- **default_language** (Required, String) - The default language. - Need to be `de`, `en`, `es`, `fr` or `ru`. -- **default_email_domain** (Required, String) - The default email domain. -- **secondary_auth** (Optional, List of String) - The secondary authentications methods for the LDAP domain. -- **description** (Optional, String) - The domain description. -- **check_x509_san_email** (Optional, Boolean) - Match the X509v3 SAN email. -- **display_name_attribute** (Optional, String) - The display name attribute. -- **email_attribute** (Optional, String) - The email attribute. -- **group_attribute** (Optional, String) - The group attribute. -- **is_default** (Optional, Boolean) - The domain is used by default. -- **language_attribute** (Optional, String) - The language attribute. -- **san_domain_name** (Optional, String) - The domain name to match SAN email (only for AD server). -- **x509_condition** (Optional, String) - Condition to match a LDAP domain with the X509 certificate variables (only for LDAP server). -- **x509_search_filter** (Optional, String) - LDAP search filter for X509 authentication (only for LDAP server). - -## Attribute Reference - -- **id** (String) - ID of resource = `domain_name` - -## Import - -Ldapdomain can be imported using an id made up of ``, e.g. - -```shell -terraform import wallix-bastion_ldapdomain.example_com example.com -``` diff --git a/docs/resources/ldapmapping.md b/docs/resources/ldapmapping.md deleted file mode 100644 index 7887394..0000000 --- a/docs/resources/ldapmapping.md +++ /dev/null @@ -1,38 +0,0 @@ -# wallix-bastion_ldapmapping Resource - -Provides a ldapmapping resource. - -## Example Usage - -```hcl -# Configure a ldapmapping -resource "wallix-bastion_ldapmapping" "test" { - domain = "domain.local" - user_group = "group1" - ldap_group = "CN=Test,OU=Group,DC=domain,DC=local" -} -``` - -## Argument Reference - -The following arguments are supported: - -- **domain** (Required, String, Forces new resource) - The name of the domain for which the mapping is defined. -- **user_group** (Required, String, Forces new resource) - The name of the Bastion users group. -- **ldap_group** (Required, String, Forces new resource) - The name (distinguished name - DN) of the LDAP group, `*` means fallback mapping. - -## Attribute Reference - -- **id** (String) - An identifier for the resource with format `//` - -## Import - -ldapmapping can be imported using an id made up of `//`, e.g. - -```shell -terraform import wallix-bastion_ldapmapping.test 'domain.local/group1/CN=test,OU=example,DC=com' -``` diff --git a/go.mod b/go.mod index 3845e61..24629b4 100644 --- a/go.mod +++ b/go.mod @@ -1,41 +1,42 @@ module github.com/wallix/terraform-provider-wallix-bastion -go 1.20 +go 1.22.0 require ( github.com/hashicorp/go-cleanhttp v0.5.2 - github.com/hashicorp/go-version v1.6.0 - github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0 - github.com/jeremmfr/go-utils v0.10.0 + github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 + golang.org/x/mod v0.21.0 ) require ( - github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 // indirect + github.com/ProtonMail/go-crypto v1.1.0-alpha.2 // indirect github.com/agext/levenshtein v1.2.2 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/cloudflare/circl v1.3.7 // indirect - github.com/fatih/color v1.13.0 // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/fatih/color v1.16.0 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 // indirect - github.com/hashicorp/go-hclog v1.5.0 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-plugin v1.5.1 // indirect + github.com/hashicorp/go-plugin v1.6.2 // indirect + github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect - github.com/hashicorp/hc-install v0.6.0 // indirect - github.com/hashicorp/hcl/v2 v2.18.0 // indirect + github.com/hashicorp/go-version v1.7.0 // indirect + github.com/hashicorp/hc-install v0.9.0 // indirect + github.com/hashicorp/hcl/v2 v2.22.0 // indirect github.com/hashicorp/logutils v1.0.0 // indirect - github.com/hashicorp/terraform-exec v0.19.0 // indirect - github.com/hashicorp/terraform-json v0.17.1 // indirect - github.com/hashicorp/terraform-plugin-go v0.19.0 // indirect + github.com/hashicorp/terraform-exec v0.21.0 // indirect + github.com/hashicorp/terraform-json v0.23.0 // indirect + github.com/hashicorp/terraform-plugin-go v0.25.0 // indirect github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect - github.com/hashicorp/terraform-registry-address v0.2.2 // indirect + github.com/hashicorp/terraform-registry-address v0.2.3 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect - github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect - github.com/mattn/go-colorable v0.1.12 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect + github.com/hashicorp/yamux v0.1.1 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.0 // indirect @@ -43,18 +44,19 @@ require ( github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/oklog/run v1.0.0 // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect - github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect + github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/zclconf/go-cty v1.14.0 // indirect - golang.org/x/crypto v0.17.0 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.15.0 // indirect - golang.org/x/text v0.14.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect - google.golang.org/grpc v1.57.1 // indirect - google.golang.org/protobuf v1.31.0 // indirect + github.com/zclconf/go-cty v1.15.0 // indirect + golang.org/x/crypto v0.28.0 // indirect + golang.org/x/net v0.28.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.26.0 // indirect + golang.org/x/text v0.19.0 // indirect + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect + google.golang.org/appengine v1.6.8 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/grpc v1.67.1 // indirect + google.golang.org/protobuf v1.35.1 // indirect ) -replace github.com/hashicorp/terraform-plugin-sdk/v2 => github.com/jeremmfr/terraform-plugin-sdk/v2 v2.29.1-0.20230913082525-7f46c82c0820 +replace github.com/hashicorp/terraform-plugin-sdk/v2 => github.com/jeremmfr/terraform-plugin-sdk/v2 v2.35.1-0.20241104080352-55b65701df12 diff --git a/go.sum b/go.sum index 6caf877..845fc88 100644 --- a/go.sum +++ b/go.sum @@ -1,38 +1,47 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 h1:KLq8BE0KwCL+mmXnjLWEAOYO+2l2AE4YMmqG1ZpZHBs= -github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= -github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg= +github.com/ProtonMail/go-crypto v1.1.0-alpha.2/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE= github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= -github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= +github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= -github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= -github.com/go-git/go-git/v5 v5.8.1 h1:Zo79E4p7TRk0xoRgMq0RShiTHGKcKI4+DI6BfJc/Q+A= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= +github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/protobuf v1.1.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.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU= @@ -42,56 +51,61 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= -github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= -github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-plugin v1.5.1 h1:oGm7cWBaYIp3lJpx1RUEfLWophprE2EV/KUeqBYo+6k= -github.com/hashicorp/go-plugin v1.5.1/go.mod h1:w1sAEES3g3PuV/RzUrgow20W2uErMly84hhD3um1WL4= +github.com/hashicorp/go-plugin v1.6.2 h1:zdGAEd0V1lCaU0u+MxWQhtSDQmahpkwOun8U8EiRVog= +github.com/hashicorp/go-plugin v1.6.2/go.mod h1:CkgLQ5CZqNmdL9U9JzM532t8ZiYQ35+pj3b1FD37R0Q= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +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 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= -github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hc-install v0.6.0 h1:fDHnU7JNFNSQebVKYhHZ0va1bC6SrPQ8fpebsvNr2w4= -github.com/hashicorp/hc-install v0.6.0/go.mod h1:10I912u3nntx9Umo1VAeYPUUuehk0aRQJYpMwbX5wQA= -github.com/hashicorp/hcl/v2 v2.18.0 h1:wYnG7Lt31t2zYkcquwgKo6MWXzRUDIeIVU5naZwHLl8= -github.com/hashicorp/hcl/v2 v2.18.0/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= +github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= +github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/hc-install v0.9.0 h1:2dIk8LcvANwtv3QZLckxcjyF5w8KVtiMxu6G6eLhghE= +github.com/hashicorp/hc-install v0.9.0/go.mod h1:+6vOP+mf3tuGgMApVYtmsnDoKWMDcFXeTxCACYZ8SFg= +github.com/hashicorp/hcl/v2 v2.22.0 h1:hkZ3nCtqeJsDhPRFz5EA9iwcG1hNWGePOTw6oyul12M= +github.com/hashicorp/hcl/v2 v2.22.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/terraform-exec v0.19.0 h1:FpqZ6n50Tk95mItTSS9BjeOVUb4eg81SpgVtZNNtFSM= -github.com/hashicorp/terraform-exec v0.19.0/go.mod h1:tbxUpe3JKruE9Cuf65mycSIT8KiNPZ0FkuTE3H4urQg= -github.com/hashicorp/terraform-json v0.17.1 h1:eMfvh/uWggKmY7Pmb3T85u86E2EQg6EQHgyRwf3RkyA= -github.com/hashicorp/terraform-json v0.17.1/go.mod h1:Huy6zt6euxaY9knPAFKjUITn8QxUFIe9VuSzb4zn/0o= -github.com/hashicorp/terraform-plugin-go v0.19.0 h1:BuZx/6Cp+lkmiG0cOBk6Zps0Cb2tmqQpDM3iAtnhDQU= -github.com/hashicorp/terraform-plugin-go v0.19.0/go.mod h1:EhRSkEPNoylLQntYsk5KrDHTZJh9HQoumZXbOGOXmec= +github.com/hashicorp/terraform-exec v0.21.0 h1:uNkLAe95ey5Uux6KJdua6+cv8asgILFVWkd/RG0D2XQ= +github.com/hashicorp/terraform-exec v0.21.0/go.mod h1:1PPeMYou+KDUSSeRE9szMZ/oHf4fYUmB923Wzbq1ICg= +github.com/hashicorp/terraform-json v0.23.0 h1:sniCkExU4iKtTADReHzACkk8fnpQXrdD2xoR+lppBkI= +github.com/hashicorp/terraform-json v0.23.0/go.mod h1:MHdXbBAbSg0GvzuWazEGKAn/cyNfIB7mN6y7KJN6y2c= +github.com/hashicorp/terraform-plugin-go v0.25.0 h1:oi13cx7xXA6QciMcpcFi/rwA974rdTxjqEhXJjbAyks= +github.com/hashicorp/terraform-plugin-go v0.25.0/go.mod h1:+SYagMYadJP86Kvn+TGeV+ofr/R3g4/If0O5sO96MVw= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= -github.com/hashicorp/terraform-registry-address v0.2.2 h1:lPQBg403El8PPicg/qONZJDC6YlgCVbWDtNmmZKtBno= -github.com/hashicorp/terraform-registry-address v0.2.2/go.mod h1:LtwNbCihUoUZ3RYriyS2wF/lGPB6gF9ICLRtuDk7hSo= +github.com/hashicorp/terraform-registry-address v0.2.3 h1:2TAiKJ1A3MAkZlH1YI/aTVcLZRu7JseiXNRHbOAyoTI= +github.com/hashicorp/terraform-registry-address v0.2.3/go.mod h1:lFHA76T8jfQteVfT7caREqguFrW3c4MFSPhZB7HHgUM= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= -github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= -github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= +github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= +github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= -github.com/jeremmfr/go-utils v0.10.0 h1:gEgZzLkzzHqRS0slHv3NCEeVemBYWWF7C4M3W1EatlY= -github.com/jeremmfr/go-utils v0.10.0/go.mod h1:Lkn95iSzCRviFhn2/0XmqzWGmxI+kkoqKAZqip7VUmM= -github.com/jeremmfr/terraform-plugin-sdk/v2 v2.29.1-0.20230913082525-7f46c82c0820 h1:NfBGagrPGV0InEMFvcqwIuYgeBzU//NwvEPSiTGSxZM= -github.com/jeremmfr/terraform-plugin-sdk/v2 v2.29.1-0.20230913082525-7f46c82c0820/go.mod h1:qH/34G25Ugdj5FcM95cSoXzUgIbgfhVLXCcEcYaMwq8= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jeremmfr/terraform-plugin-sdk/v2 v2.35.1-0.20241104080352-55b65701df12 h1:9kr38pXYu83ByiliYIMgTabUrroIPlIYqkH/X+9YvgI= +github.com/jeremmfr/terraform-plugin-sdk/v2 v2.35.1-0.20241104080352-55b65701df12/go.mod h1:B0Al8NyYVr8Mp/KLwssKXG1RqnTk7FySqSn4fRuLNgw= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= +github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= 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 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= @@ -105,49 +119,49 @@ github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= +github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= -github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zclconf/go-cty v1.14.0 h1:/Xrd39K7DXbHzlisFP9c4pHao4yyf+/Ug9LEz+Y/yhc= -github.com/zclconf/go-cty v1.14.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ= +github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= +github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= +github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= -golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= +golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= 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 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/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-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 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.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/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-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.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -158,48 +172,41 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/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.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= -golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/text v0.3.0/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.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.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= -google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 h1:0nDDozoAU19Qb2HwhXadU8OcsiO/09cnTqhUtq2MEOM= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg= -google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= 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.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=