From febf66ab428d7c4737dadd16e0f93a38d948d661 Mon Sep 17 00:00:00 2001 From: Alberto Donato Date: Fri, 23 Oct 2026 09:16:34 +0200 Subject: [PATCH] refactor: split API package into shared and platform-specific parts ### what Move the GraphQL client and wrappers to `internal/api/platform`, and keep in `internal/api` the HTTP transports, error types (`APIError`, `NotFound`, `Conflict`) and the `MaskSecrets` helper for masking secrets in logs. ### why Allow adding other API clients (e.g. for the IaC API) sharing authentication, logging and error handling with the platform one. ### testing `just lint`, `just test-unit` and `just test` (replay mode) pass. No functional changes. ### docs Updated dev docs for the new layout, also fixing references to code that no longer exists or has moved. --- CLAUDE.md | 5 +- dev-docs/architecture.md | 54 ++--- dev-docs/contributing.md | 12 +- dev-docs/development.md | 15 +- internal/api/client.go | 229 ------------------ internal/api/error.go | 45 +--- internal/api/error_test.go | 29 +-- internal/api/mask.go | 31 +++ internal/api/mask_test.go | 34 +++ internal/api/{ => platform}/account.go | 10 +- .../api/{ => platform}/account_discovery.go | 10 +- internal/api/{ => platform}/account_group.go | 6 +- .../{ => platform}/account_group_mapping.go | 6 +- .../{ => platform}/anthropic_integration.go | 10 +- internal/api/{ => platform}/api.go | 4 +- internal/api/{ => platform}/binding.go | 10 +- internal/api/platform/client.go | 93 +++++++ internal/api/{ => platform}/client_test.go | 52 +--- internal/api/{ => platform}/common.go | 2 +- .../{ => platform}/configuration_profile.go | 32 +-- .../api/{ => platform}/datadog_integration.go | 8 +- internal/api/{ => platform}/enums.go | 2 +- internal/api/platform/error.go | 35 +++ internal/api/platform/error_test.go | 36 +++ internal/api/{ => platform}/filter.go | 2 +- .../api/{ => platform}/gcp_integration.go | 8 +- .../{ => platform}/notification_template.go | 6 +- internal/api/{ => platform}/policy.go | 6 +- .../api/{ => platform}/policy_collection.go | 6 +- .../policy_collection_mapping.go | 6 +- internal/api/{ => platform}/report_group.go | 8 +- internal/api/{ => platform}/repository.go | 10 +- internal/api/{ => platform}/role.go | 6 +- .../api/{ => platform}/role_assignment.go | 14 +- internal/api/{ => platform}/saml_provider.go | 10 +- internal/api/{ => platform}/sso_group.go | 14 +- internal/api/{ => platform}/system.go | 2 +- internal/api/{ => platform}/types.go | 2 +- internal/api/{ => platform}/user.go | 6 +- internal/api/{ => platform}/user_group.go | 12 +- internal/api/transport.go | 133 ++++++++++ internal/api/transport_test.go | 61 +++++ internal/datasources/datasource.go | 4 +- internal/models/account.go | 6 +- internal/models/account_discovery_aws.go | 4 +- internal/models/account_discovery_azure.go | 4 +- internal/models/account_discovery_gcp.go | 4 +- internal/models/account_group.go | 4 +- internal/models/account_group_mapping.go | 4 +- internal/models/account_test.go | 14 +- internal/models/anthropic_integration.go | 4 +- internal/models/binding.go | 8 +- .../configuration_profile_account_owners.go | 6 +- .../models/configuration_profile_email.go | 6 +- internal/models/configuration_profile_jira.go | 8 +- .../models/configuration_profile_msteams.go | 18 +- .../configuration_profile_resource_owner.go | 4 +- .../configuration_profile_servicenow.go | 4 +- .../models/configuration_profile_slack.go | 8 +- .../models/configuration_profile_symphony.go | 4 +- internal/models/datadog_integration.go | 4 +- internal/models/gcp_integration.go | 32 +-- internal/models/gcp_integration_surface.go | 4 +- .../models/msteams_integration_surface.go | 4 +- internal/models/notification_template.go | 4 +- internal/models/platform.go | 6 +- internal/models/policy.go | 4 +- internal/models/policy_collection.go | 4 +- internal/models/policy_collection_mapping.go | 4 +- internal/models/report_group.go | 28 +-- internal/models/repository.go | 4 +- internal/models/role.go | 4 +- internal/models/role_assignment.go | 6 +- internal/models/saml_provider.go | 4 +- internal/models/sso_group.go | 4 +- internal/models/status.go | 6 +- internal/models/status_test.go | 8 +- internal/models/user.go | 4 +- internal/models/user_group.go | 4 +- internal/provider/provider.go | 4 +- internal/providerdata/providerdata.go | 8 +- internal/resources/account.go | 10 +- internal/resources/account_discovery_aws.go | 6 +- internal/resources/account_discovery_azure.go | 6 +- internal/resources/account_discovery_gcp.go | 14 +- internal/resources/account_group.go | 10 +- internal/resources/anthropic_integration.go | 5 +- internal/resources/binding.go | 36 +-- .../configuration_profile_account_owners.go | 20 +- .../resources/configuration_profile_email.go | 16 +- .../resources/configuration_profile_jira.go | 14 +- .../configuration_profile_msteams.go | 20 +- .../configuration_profile_resource_owner.go | 16 +- .../configuration_profile_servicenow.go | 8 +- .../resources/configuration_profile_slack.go | 26 +- .../configuration_profile_symphony.go | 8 +- internal/resources/datadog_integration.go | 6 +- internal/resources/gcp_integration.go | 44 ++-- internal/resources/notification_template.go | 6 +- internal/resources/policy_collection.go | 20 +- .../resources/policy_collection_mapping.go | 6 +- internal/resources/report_group.go | 62 ++--- internal/resources/repository.go | 12 +- internal/resources/resource.go | 4 +- internal/resources/saml_provider.go | 6 +- internal/resources/sso_group.go | 6 +- internal/resources/user.go | 6 +- internal/resources/user_group.go | 6 +- internal/schemavalidate/cloud_provider.go | 6 +- 109 files changed, 944 insertions(+), 807 deletions(-) delete mode 100644 internal/api/client.go create mode 100644 internal/api/mask.go create mode 100644 internal/api/mask_test.go rename internal/api/{ => platform}/account.go (94%) rename internal/api/{ => platform}/account_discovery.go (96%) rename internal/api/{ => platform}/account_group.go (95%) rename internal/api/{ => platform}/account_group_mapping.go (95%) rename internal/api/{ => platform}/anthropic_integration.go (92%) rename internal/api/{ => platform}/api.go (96%) rename internal/api/{ => platform}/binding.go (96%) create mode 100644 internal/api/platform/client.go rename internal/api/{ => platform}/client_test.go (70%) rename internal/api/{ => platform}/common.go (99%) rename internal/api/{ => platform}/configuration_profile.go (95%) rename internal/api/{ => platform}/datadog_integration.go (92%) rename internal/api/{ => platform}/enums.go (98%) create mode 100644 internal/api/platform/error.go create mode 100644 internal/api/platform/error_test.go rename internal/api/{ => platform}/filter.go (99%) rename internal/api/{ => platform}/gcp_integration.go (97%) rename internal/api/{ => platform}/notification_template.go (92%) rename internal/api/{ => platform}/policy.go (91%) rename internal/api/{ => platform}/policy_collection.go (96%) rename internal/api/{ => platform}/policy_collection_mapping.go (95%) rename internal/api/{ => platform}/report_group.go (97%) rename internal/api/{ => platform}/repository.go (96%) rename internal/api/{ => platform}/role.go (86%) rename internal/api/{ => platform}/role_assignment.go (93%) rename internal/api/{ => platform}/saml_provider.go (93%) rename internal/api/{ => platform}/sso_group.go (88%) rename internal/api/{ => platform}/system.go (99%) rename internal/api/{ => platform}/types.go (98%) rename internal/api/{ => platform}/user.go (95%) rename internal/api/{ => platform}/user_group.go (91%) create mode 100644 internal/api/transport.go create mode 100644 internal/api/transport_test.go diff --git a/CLAUDE.md b/CLAUDE.md index d3bc5019..d2c19e8d 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -20,8 +20,9 @@ Built with Terraform Plugin Framework the provider uses GraphQL to communicate w All commands use the `just` task runner: - `just build` - Build the provider binary -- `just format` / `just lint` - Format and lint code +- `just lint` - Format and lint code - `just test` - Run acceptance tests (replay mode, no API needed) +- `just test-unit` - Run unit tests only - `just test-live` - Run tests against live API - `just test-record ` - Record new API responses - `just docs` - Generate provider documentation @@ -37,7 +38,7 @@ All commands use the `just` task runner: ### Adding Resources 1. Create model (`internal/models/`) -2. Create API methods (`internal/api/`) +2. Create API methods (`internal/api/platform/`) 3. Create resource (`internal/resources/`), register in `resources.go` 4. Add examples and tests 5. Run `just docs` diff --git a/dev-docs/architecture.md b/dev-docs/architecture.md index 71931be9..1d8a69dc 100644 --- a/dev-docs/architecture.md +++ b/dev-docs/architecture.md @@ -7,13 +7,13 @@ ├── main.go # Provider entry point ├── internal/ │ ├── provider/ # Provider configuration and registration -│ ├── api/ # GraphQL API client and wrappers +│ ├── api/ # Shared HTTP transports and errors for API clients +│ │ └── platform/ # Platform GraphQL API client and wrappers │ ├── resources/ # Terraform resource implementations │ ├── datasources/ # Terraform data source implementations │ ├── models/ # Data model definitions │ ├── acceptance_tests/ # Acceptance tests with HTTP recording │ ├── errors/ # Error handling utilities (legacy) -│ ├── modelupdate/ # Helper functions for model updates │ ├── planmodifiers/ # Custom Terraform plan modifiers │ ├── providerdata/ # Provider data management │ ├── schemavalidate/ # Custom schema validators @@ -21,22 +21,21 @@ │ └── typehelpers/ # Type conversion and manipulation helpers ├── examples/ # Example Terraform configurations ├── docs/ # Auto-generated documentation -├── templates/ # Documentation templates └── tools/ # Build and documentation tools ``` ## API Integration -- **GraphQL Client**: Uses `github.com/hasura/go-graphql-client` for GraphQL communication -- **API Wrapper**: `internal/api/api.go` provides a typed `API` struct with methods for each resource type +- **Shared API code** (`internal/api/`): Functionality common to all API clients + - HTTP transport layers for authentication (`AuthTransport`) and logging (`LogTransport`), combined by `NewTransport()` + - Error types: `APIError`, `NotFound` and `Conflict` (resources remove objects from state on `api.NotFound`) + - `MaskSecrets()` returns a context which masks the given secrets in request/response logs. Call it before API requests that send secrets +- **GraphQL Client**: The platform client (`internal/api/platform/`) uses `github.com/hasura/go-graphql-client` for GraphQL communication +- **API Wrapper**: `internal/api/platform/api.go` provides a typed `API` struct with methods for each resource type - **Modular API Files**: Each resource type has its own API file -- **HTTP Transport**: Custom transport layers for authentication (`authTransport`) and logging (`logTransport`) -- **Enums**: Strongly typed enums in `internal/api/enums.go`. -- **Pagination**: Generic helpers in `internal/api/pagination.go` for GraphQL connection pattern pagination - - `FindInPaginatedQuery[T, R]()` - Searches through paginated results for a specific item - - `CollectAllPages[T]()` - Collects all items from all pages -- **Filtering**: Filter API in `internal/api/filter.go` for constructing GraphQL filter queries - - `FilterElementInput` and `FilterValueInput` types for building filter expressions +- **Enums**: Strongly typed enums in `internal/api/platform/enums.go`. +- **Filtering**: Filter API in `internal/api/platform/filter.go` for constructing GraphQL filter queries + - `filterElementInput` and `filterValueInput` types for building filter expressions - `newExactMatchFilter()` helper for creating exact-match filters with "equals" operator ## Resource Architecture @@ -55,7 +54,7 @@ Resources follow the Terraform Plugin Framework patterns: - `Delete()` - Delete resource - `ImportState()` - Import existing resource -3. **Resource Registration**: All resources are registered in `internal/resources/resources.go` in the `RESOURCES` slice +3. **Resource Registration**: All resources are registered in the `Resources` variable in `internal/resources/resources.go`, via `newFactory()`. Resources in the `Unreleased` list are only enabled when `STACKLET_UNRELEASED_FEATURES` is set 4. **Model Separation**: Models are defined in `internal/models/` separate from resource logic @@ -67,6 +66,7 @@ Resources follow the Terraform Plugin Framework patterns: - `RequiresReplaceIfFieldsChanged()` - Forces recreation when specific nested object fields change - `RequiresReplaceIfUnset()` - Forces recreation when object transitions from non-null to null - `RequiresReplaceIfNullStringChange()` - Forces recreation when string toggles between null and non-null + - `TrimWhiteSpace()` - Strips leading/trailing whitespace from planned strings, for APIs that normalize it - `DefaultObject()` - Sets default object values to match API defaults ## Data Source Architecture @@ -77,7 +77,7 @@ Data sources follow similar patterns to resources: - `datasource.DataSource` - Basic data source interface - `datasource.DataSourceWithConfigure` - For provider configuration -2. **Data Source Registration**: All registered in `internal/datasources/datasources.go` in the `DATASOURCES` slice +2. **Data Source Registration**: All registered in the `DataSources` variable in `internal/datasources/datasources.go`, with the same `Released`/`Unreleased` split as resources 3. **Shared Models**: Often share model definitions with their corresponding resources @@ -91,18 +91,21 @@ Models in `internal/models/` define Terraform schema structure with `tfsdk` stru ## Type Helpers and Validators -**Type Helpers** (`internal/typehelpers/`): All return `(result, diag.Diagnostics)` for proper error propagation: +**Type Helpers** (`internal/typehelpers/`): Helpers that can fail return `(result, diag.Diagnostics)` for proper error propagation: - `JSONString()` - Normalizes JSON strings for consistent comparison - `ObjectValue()` / `ObjectList()` - Converts values/slices to Terraform objects/lists - `FilteredObject()` / `UpdatedObject()` - Extracts/updates object attributes - `ObjectStringIdentifier()` / `ListItemsIdentifiers()` - Extracts identifiers - `ListSortedEntries()` - Sorts list entries by identifier order +- `StringsList()` / `GraphQLIDValue()` - Simple conversions (no diagnostics) +- `PreserveIfNull()` / `PreserveIfEmptyJSON()` - Keep the original value when the API returns null or `{}` for it, avoiding perpetual diffs **Usage Pattern**: Call helper, append diagnostics with `diags.Append(d...)`, check `diags.HasError()` for early returns when needed. **Schema Validators** (`internal/schemavalidate/`): - `OneOfCloudProviders()` - Validates cloud provider values -- `unique_string_attribute.go` - Ensures string uniqueness in lists +- `UniqueStringAttribute()` - Ensures string uniqueness in lists +- `UUID()` - Validates UUID strings **Schema Defaults** (`internal/schemadefault/`): - `EmptyListDefault()` / `EmptyMapDefault()` - Provide empty defaults for optional attributes @@ -113,14 +116,10 @@ Models in `internal/models/` define Terraform schema structure with `tfsdk` stru - **Legacy package** - Being phased out in favor of direct `diag.Diagnostics` usage - New code should use `diag.Diagnostics` directly and the `typehelpers` package functions which all return diagnostics -**Model Update** (`internal/modelupdate/`): -- Helper functions for updating Terraform models from API results -- Centralizes common update patterns - **Provider Data** (`internal/providerdata/`): -- `ProviderData` struct holds API client for resources/data sources -- `GetResourceProviderData()` - Retrieves provider data in resources -- `GetDataSourceProviderData()` - Retrieves provider data in data sources +- `providerData` struct holds API clients for resources/data sources, built by `New()` +- `GetForResource()` - Retrieves provider data in resources +- `GetForDataSource()` - Retrieves provider data in data sources ## Architectural Patterns @@ -130,7 +129,7 @@ All functions that can fail return `diag.Diagnostics` (plural). Pattern: initial ### Type Conversion Pattern -Use `internal/typehelpers` for all type conversions: `JSONString()`, `ObjectValue()`, `ObjectList()`, `ObjectStringIdentifier()`, `ListItemsIdentifiers()`, `ListSortedEntries()`. All return `(result, diag.Diagnostics)`. +Use `internal/typehelpers` for type conversions: `JSONString()`, `ObjectValue()`, `ObjectList()`, `ObjectStringIdentifier()`, `ListItemsIdentifiers()`, `ListSortedEntries()`. These return `(result, diag.Diagnostics)`. ### Model Update Pattern @@ -142,11 +141,11 @@ Models implement `Update(ctx, obj) diag.Diagnostics`. Resource models extend dat - One resource/data source per file - File names match resource type (e.g., `account.go` for `stacklet_account`) - Models in separate `models/` package -- API methods in separate `api/` package +- API methods in the `api/platform/` package ### Naming Conventions -- Resource constructors: `NewXxxResource()` -- Data source constructors: `NewXxxDataSource()` +- Resource types: `xxxResource`, registered with `newFactory(&xxxResource{})` +- Data source types: `xxxDataSource`, registered with `newFactory(&xxxDataSource{})` - API types: Input types use `XxxInput` suffix - Models: Separate types for resources vs data sources when needed @@ -163,6 +162,7 @@ Models implement `Update(ctx, obj) diag.Diagnostics`. Resource models extend dat - `RequiresReplaceIfNullStringChange()` - For string fields that toggle between null and non-null - `RequiresReplaceIfFieldsChanged()` - For objects where specific nested fields require replacement - `RequiresReplaceIfUnset()` - For objects that cannot transition from configured to null + - `TrimWhiteSpace()` - For strings where surrounding whitespace is not significant - `DefaultObject()` - Sets default objects matching API defaults ### Write-Only Fields diff --git a/dev-docs/contributing.md b/dev-docs/contributing.md index 50282327..285f805a 100644 --- a/dev-docs/contributing.md +++ b/dev-docs/contributing.md @@ -3,21 +3,21 @@ ## Adding a New Resource 1. Create model in `internal/models/` -2. Create API methods in `internal/api/` +2. Create API methods in `internal/api/platform/` 3. Create resource in `internal/resources/` -4. Register in `internal/resources/resources.go` in the `RESOURCES` slice +4. Register in the `Resources` variable in `internal/resources/resources.go` 5. Add examples in `examples/resources/` -6. Add acceptance test in `acceptance_tests/` +6. Add acceptance test in `internal/acceptance_tests/` 7. Generate docs: `just docs` ## Adding a New Data Source 1. Create or reuse model in `internal/models/` -2. Create or reuse API methods in `internal/api/` +2. Create or reuse API methods in `internal/api/platform/` 3. Create data source in `internal/datasources/` -4. Register in `internal/datasources/datasources.go` in the `DATASOURCES` slice +4. Register in the `DataSources` variable in `internal/datasources/datasources.go` 5. Add examples in `examples/data-sources/` -6. Add acceptance test in `acceptance_tests/` +6. Add acceptance test in `internal/acceptance_tests/` 7. Generate docs: `just docs` **Note**: Data sources often reuse models and API methods from corresponding resources. diff --git a/dev-docs/development.md b/dev-docs/development.md index 919dfd67..90f28ab0 100644 --- a/dev-docs/development.md +++ b/dev-docs/development.md @@ -24,8 +24,9 @@ Run `./terraform-provider-stacklet -debug` and use `TF_REATTACH_PROVIDERS` envir All development commands use the `just` task runner: - `just build` - Build the provider binary -- `just format` / `just lint` - Format and lint code (Go, Terraform, docs, copyright) +- `just lint` - Format and lint code (Go, Terraform, docs, copyright) - `just test` - Run acceptance tests (replay mode, no API needed) +- `just test-unit` - Run unit tests only - `just test-live` - Run tests against live API - `just test-record ` - Record new API responses for a test - `just docs` - Generate provider documentation @@ -35,7 +36,7 @@ Testing individual tests: `just test -run TestAccAccountResource` ## Testing Strategy -**HTTP Recording**: Tests use recorded HTTP interactions (`acceptance_tests/recordings/`) for fast, deterministic runs without live API. Three modes via `TF_ACC_MODE`: `replay` (default), `record`, `live`. See `acceptance_tests/recorded_transport.go`. +**HTTP Recording**: Tests use recorded HTTP interactions (`internal/acceptance_tests/recordings/`) for fast, deterministic runs without live API. Three modes via `TF_ACC_MODE`: `replay` (default), `record`, `live`. See `internal/acceptance_tests/recorded_transport.go`. **Test Helpers**: - `importStateIDFuncFromAttrs()` - Creates import IDs from resource attributes @@ -43,7 +44,7 @@ Testing individual tests: `just test -run TestAccAccountResource` - `ConfigPlanChecks` with `plancheck.ExpectResourceAction()` - Validates plan actions - Template rendering for test configurations -**Unit Tests**: Use testify test suites for shared setup (e.g., `internal/provider/provider_test.go`). Run with: `go test ./internal/provider/` +**Unit Tests**: Table-driven tests with testify assertions (e.g., `internal/provider/provider_test.go`). Run with: `just test-unit` ## Authentication @@ -62,16 +63,16 @@ Additional tools are defined in `tools/go.mod`. ## Documentation - **Auto-generated**: Documentation in `docs/` is generated from code -- **Templates**: Use `templates/` for customizing documentation - **Examples**: All examples in `examples/` must be valid Terraform - **Import examples**: Each resource has `import.sh` example ## CI/CD ### Continuous Integration (`.github/workflows/ci.yaml`) -- Runs on push to `main` and all PRs -- All GitHub Actions use SHA pinning for security -- Separate jobs for: Go linting, Terraform linting, documentation validation, copyright headers, and acceptance tests (replay mode) +- Runs on push to `main` and PRs targeting `main` +- All GitHub Actions and reusable workflows use SHA pinning for security +- `Lint` job runs `just lint` (all pre-commit hooks: Go linting, Terraform formatting and examples validation, documentation validation, copyright headers, spelling) +- `Tests` job runs `just test` (acceptance tests in replay mode) ### Release Workflow (`.github/workflows/release.yaml`) - **Public Registry**: Triggered by version tags (`v*.*.*`), builds with GoReleaser, signs with GPG, publishes to Terraform Registry diff --git a/internal/api/client.go b/internal/api/client.go deleted file mode 100644 index 7c6ac8e4..00000000 --- a/internal/api/client.go +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright Stacklet, Inc. 2025, 2026 - -package api - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io" - "net/http" - "os" - "strings" - - "github.com/hashicorp/go-hclog" - "github.com/hashicorp/terraform-plugin-log/tflog" - "github.com/hasura/go-graphql-client" -) - -// ClientConfig is the configuration for the API client. -type ClientConfig struct { - Endpoint string - APIKey string - Version string - PageSize int -} - -// client is the wrapper for the GraphQL client. -type client struct { - c *graphql.Client - pageSize int -} - -// Query makes a GraphQL query call. -func (c *client) Query(ctx context.Context, q any, variables map[string]any) error { - err := c.c.Query(ctx, q, variables) - if err != nil { - return newAPIError(err) - } - return nil -} - -// Mutate makes a GraphQL mutation call. -func (c *client) Mutate(ctx context.Context, m any, variables map[string]any) error { - err := c.c.Mutate(ctx, m, variables) - if err != nil { - return newAPIError(err) - } - return nil -} - -// maskSecrets returns a context whose logs show the given secrets only as a -// mask. Request bodies carry them JSON-encoded, so that form is masked too. -func maskSecrets(ctx context.Context, secrets ...*string) context.Context { - var masked []string - for _, s := range secrets { - if s == nil || *s == "" { - continue - } - masked = append(masked, *s) - if encoded, err := json.Marshal(*s); err == nil { - if e := string(encoded[1 : len(encoded)-1]); e != *s { - masked = append(masked, e) - } - } - } - if len(masked) == 0 { - return ctx - } - return tflog.MaskLogStrings(ctx, masked...) -} - -// newClient returns a configured graphql Client. -func newClient(config ClientConfig) *client { - tfLog := hclog.LevelFromString(os.Getenv("TF_LOG")) - logBody := tfLog == hclog.Debug || tfLog == hclog.Trace - - httpClient := &http.Client{ - Transport: &errorTransport{ - Base: &authTransport{ - APIKey: config.APIKey, - Version: config.Version, - Base: &logTransport{ - Base: http.DefaultTransport, - LogBody: logBody, - }, - }, - }, - } - return &client{ - c: graphql.NewClient(config.Endpoint, httpClient), - pageSize: config.PageSize, - } -} - -// authTransport is an http.Transport that adds authorization header. -type authTransport struct { - APIKey string - Version string - Base http.RoundTripper -} - -func (t *authTransport) RoundTrip(req *http.Request) (*http.Response, error) { - if t.APIKey == "" { - return nil, fmt.Errorf("no API key provided") - } - req.Header.Set("Authorization", "Bearer "+t.APIKey) - req.Header.Set("User-Agent", "terraform-provider-stacklet/"+t.Version) - return t.Base.RoundTrip(req) -} - -// logTransport is an http.Transport that logs requests/responses through the -// request's context, so the logs apply whatever masking the caller set up. -type logTransport struct { - Base http.RoundTripper - LogBody bool -} - -func (t *logTransport) RoundTrip(req *http.Request) (*http.Response, error) { - var reqBody, respBody string - var err error - - // Decode the request before performing it since it will otherwise consume the body - if t.LogBody { - reqBody, err = decodeRequestBody(req) - if err != nil { - return nil, err - } - } - - tflog.Debug( - req.Context(), - "Performing GraphQL request", - map[string]any{ - "req_method": req.Method, - "req_url": req.URL.String(), - "req_body": reqBody, - }, - ) - - resp, reqErr := t.Base.RoundTrip(req) - - if resp != nil { - if t.LogBody { - respBody, err = decodeResponseBody(resp) - if err != nil { - return nil, err - } - } - - tflog.Debug( - req.Context(), - "Got GraphQL response", - map[string]any{ - "req_method": req.Method, - "req_url": req.URL.String(), - "resp_status": resp.Status, - "resp_status_code": resp.StatusCode, - "req_body": reqBody, - "resp_body": respBody, - }, - ) - } - - return resp, reqErr -} - -// errorTransport is an http.Transport that converts 400 responses with a -// GraphQL-style error payload into Go errors, so callers see the actual -// error messages rather than a generic "400 Bad Request". -type errorTransport struct { - Base http.RoundTripper -} - -func (t *errorTransport) RoundTrip(req *http.Request) (*http.Response, error) { - resp, err := t.Base.RoundTrip(req) - if err != nil || resp == nil || resp.StatusCode != http.StatusBadRequest { - return resp, err - } - - content, err := decodeResponseBody(resp) - if err != nil { - return nil, err - } - - var payload struct { - Errors []struct { - Message string `json:"message"` - } `json:"errors"` - } - if json.Unmarshal([]byte(content), &payload) == nil && len(payload.Errors) > 0 { - msgs := make([]string, len(payload.Errors)) - for i, e := range payload.Errors { - msgs[i] = e.Message - } - return nil, apiError{Kind: "API Error", Detail: strings.Join(msgs, "\n")} - } - - return resp, nil -} - -func decodeRequestBody(req *http.Request) (string, error) { - if req.Body == nil || req.Body == http.NoBody { - return "", nil - } - - content, err := io.ReadAll(req.Body) - if err != nil { - return "", err - } - req.Body = io.NopCloser(bytes.NewReader(content)) - - return string(content), nil -} - -func decodeResponseBody(resp *http.Response) (string, error) { - if resp.Body == nil || resp.Body == http.NoBody { - return "", nil - } - defer resp.Body.Close() - - content, err := io.ReadAll(resp.Body) - if err != nil { - return "", err - } - resp.Body = io.NopCloser(bytes.NewReader(content)) - - return string(content), nil -} diff --git a/internal/api/error.go b/internal/api/error.go index b2f6ab11..6e70b90d 100644 --- a/internal/api/error.go +++ b/internal/api/error.go @@ -3,36 +3,33 @@ package api import ( - "context" "errors" "net/url" - - "github.com/hashicorp/terraform-plugin-log/tflog" ) -// apiError represent an error interacting with the API. -type apiError struct { +// APIError represent an error interacting with the API. +type APIError struct { Kind string Detail string } -// Error returns the error summary message. -func (e apiError) Summary() string { +// Summary returns the error summary message. +func (e APIError) Summary() string { return e.Kind } // Error returns the error message. -func (e apiError) Error() string { +func (e APIError) Error() string { return e.Detail } -// newAPIError returns an apiError from an error. -func newAPIError(err error) apiError { +// NewAPIError returns an APIError from an error. +func NewAPIError(err error) APIError { var urlErr *url.Error if errors.As(err, &urlErr) { - return newAPIError(urlErr.Err) + return NewAPIError(urlErr.Err) } - return apiError{Kind: "API Error", Detail: err.Error()} + return APIError{Kind: "API Error", Detail: err.Error()} } // NotFound represents an error raised when an API resource is not found. @@ -65,27 +62,3 @@ func (e Conflict) Summary() string { func (e Conflict) Error() string { return e.Message } - -// fromProblems returns an error from a list of API problems. -func fromProblems(ctx context.Context, problems []problem) error { - if len(problems) == 0 { - return nil - } - for _, problem := range problems[1:] { - info := map[string]any{"kind": problem.Kind, "message": problem.Message} - tflog.Error(ctx, "discarding additional error", info) - } - switch problems[0].Kind { - case "NotFound": - return NotFound{problems[0].Message} - case "Conflict": - return Conflict{problems[0].Message} - } - return apiError{Kind: problems[0].Kind, Detail: problems[0].Message} -} - -// problem contains the details for an API query error. -type problem struct { - Kind string `graphql:"__typename"` - Message string -} diff --git a/internal/api/error_test.go b/internal/api/error_test.go index 3b6deb86..daa56f4b 100644 --- a/internal/api/error_test.go +++ b/internal/api/error_test.go @@ -3,7 +3,6 @@ package api import ( - "context" "errors" "net/url" "testing" @@ -17,39 +16,15 @@ func TestNewAPIError_URLError(t *testing.T) { // the clean inner message. inner := errors.New("field not found; invalid type") urlErr := &url.Error{Op: "Post", URL: "https://api.example.com/graphql", Err: inner} - err := newAPIError(urlErr) + err := NewAPIError(urlErr) assert.Equal(t, "API Error", err.Summary()) assert.Equal(t, "field not found; invalid type", err.Error()) } func TestNewAPIError_PlainError(t *testing.T) { - err := newAPIError(errors.New("something went wrong")) + err := NewAPIError(errors.New("something went wrong")) assert.Equal(t, "API Error", err.Summary()) assert.Equal(t, "something went wrong", err.Error()) } - -func TestFromProblems(t *testing.T) { - ctx := context.Background() - tests := []struct { - name string - problems []problem - want error - }{ - {"none", nil, nil}, - {"not found", []problem{{Kind: "NotFound", Message: "gone"}}, NotFound{"gone"}}, - {"conflict", []problem{{Kind: "Conflict", Message: "try again"}}, Conflict{"try again"}}, - {"other", []problem{{Kind: "InvalidInput", Message: "bad key"}}, apiError{Kind: "InvalidInput", Detail: "bad key"}}, - { - "first of several", - []problem{{Kind: "InvalidInput", Message: "first"}, {Kind: "NotFound", Message: "second"}}, - apiError{Kind: "InvalidInput", Detail: "first"}, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.want, fromProblems(ctx, tt.problems)) - }) - } -} diff --git a/internal/api/mask.go b/internal/api/mask.go new file mode 100644 index 00000000..4b5b8d10 --- /dev/null +++ b/internal/api/mask.go @@ -0,0 +1,31 @@ +// Copyright Stacklet, Inc. 2025, 2026 + +package api + +import ( + "context" + "encoding/json" + + "github.com/hashicorp/terraform-plugin-log/tflog" +) + +// MaskSecrets returns a context whose logs show the given secrets only as a +// mask. Request bodies carry them JSON-encoded, so that form is masked too. +func MaskSecrets(ctx context.Context, secrets ...*string) context.Context { + var masked []string + for _, s := range secrets { + if s == nil || *s == "" { + continue + } + masked = append(masked, *s) + if encoded, err := json.Marshal(*s); err == nil { + if e := string(encoded[1 : len(encoded)-1]); e != *s { + masked = append(masked, e) + } + } + } + if len(masked) == 0 { + return ctx + } + return tflog.MaskLogStrings(ctx, masked...) +} diff --git a/internal/api/mask_test.go b/internal/api/mask_test.go new file mode 100644 index 00000000..b9977024 --- /dev/null +++ b/internal/api/mask_test.go @@ -0,0 +1,34 @@ +// Copyright Stacklet, Inc. 2025, 2026 + +package api + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-log/tflog" + "github.com/hashicorp/terraform-plugin-log/tflogtest" + "github.com/stretchr/testify/assert" +) + +func TestMaskSecrets(t *testing.T) { + plain := "plain-secret" + escaped := "escaped\"secret" + empty := "" + encoded, _ := json.Marshal(map[string]string{"key": escaped}) + + var output bytes.Buffer + ctx := tflogtest.RootLogger(context.Background(), &output) + ctx = MaskSecrets(ctx, &plain, &escaped, &empty, nil) + tflog.Debug(ctx, "message", map[string]any{"plain": plain, "body": string(encoded)}) + + entries, err := tflogtest.MultilineJSONDecode(&output) + assert.NoError(t, err) + assert.Len(t, entries, 1) + assert.Equal(t, "***", entries[0]["plain"]) + assert.Equal(t, `{"key":"***"}`, entries[0]["body"]) + assert.NotContains(t, fmt.Sprint(entries[0]), "secret") +} diff --git a/internal/api/account.go b/internal/api/platform/account.go similarity index 94% rename from internal/api/account.go rename to internal/api/platform/account.go index 3a2d2786..c5cad6d8 100644 --- a/internal/api/account.go +++ b/internal/api/platform/account.go @@ -1,11 +1,13 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) // Account is the data returned by reading account data. @@ -73,7 +75,7 @@ func (a accountAPI) Read(ctx context.Context, cloudProvider string, key string) } if query.Account.ID == "" || !query.Account.Active { - return nil, NotFound{"Account not found"} + return nil, api.NotFound{Message: "Account not found"} } return &query.Account, nil @@ -86,7 +88,7 @@ func (a accountAPI) Create(ctx context.Context, i AccountCreateInput) (*Account, Account Account } `graphql:"addAccount(input: $input)"` } - ctx = maskSecrets(ctx, i.SecurityContext) + ctx = api.MaskSecrets(ctx, i.SecurityContext) input := map[string]any{"input": i} if err := a.c.Mutate(ctx, &mutation, input); err != nil { return nil, err @@ -102,7 +104,7 @@ func (a accountAPI) Update(ctx context.Context, i AccountUpdateInput) (*Account, Account Account } `graphql:"updateAccount(input: $input)"` } - ctx = maskSecrets(ctx, i.SecurityContext) + ctx = api.MaskSecrets(ctx, i.SecurityContext) input := map[string]any{"input": i} if err := a.c.Mutate(ctx, &mutation, input); err != nil { return nil, err diff --git a/internal/api/account_discovery.go b/internal/api/platform/account_discovery.go similarity index 96% rename from internal/api/account_discovery.go rename to internal/api/platform/account_discovery.go index 116e9e2a..46c4c59b 100644 --- a/internal/api/account_discovery.go +++ b/internal/api/platform/account_discovery.go @@ -1,11 +1,13 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) // Account is the data returned by reading account data. @@ -123,7 +125,7 @@ func (a accountDiscoveryAPI) Read(ctx context.Context, name string) (*AccountDis } if query.AccountDiscovery.ID == "" { - return nil, NotFound{"Account discovery not found"} + return nil, api.NotFound{Message: "Account discovery not found"} } return &query.AccountDiscovery, nil @@ -150,7 +152,7 @@ func (a accountDiscoveryAPI) UpsertAzure(ctx context.Context, input AccountDisco AccountDiscovery AccountDiscovery } `graphql:"upsertAzureAccountDiscovery(input: $input)"` } - ctx = maskSecrets(ctx, input.ClientSecret) + ctx = api.MaskSecrets(ctx, input.ClientSecret) variables := map[string]any{"input": input} if err := a.c.Mutate(ctx, &mutation, variables); err != nil { return nil, err @@ -165,7 +167,7 @@ func (a accountDiscoveryAPI) UpsertGCP(ctx context.Context, input AccountDiscove AccountDiscovery AccountDiscovery } `graphql:"upsertGCPAccountDiscovery(input: $input)"` } - ctx = maskSecrets(ctx, input.CredentialJSON) + ctx = api.MaskSecrets(ctx, input.CredentialJSON) variables := map[string]any{"input": input} if err := a.c.Mutate(ctx, &mutation, variables); err != nil { return nil, err diff --git a/internal/api/account_group.go b/internal/api/platform/account_group.go similarity index 95% rename from internal/api/account_group.go rename to internal/api/platform/account_group.go index 168c7383..2d7bd3c1 100644 --- a/internal/api/account_group.go +++ b/internal/api/platform/account_group.go @@ -1,11 +1,13 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) // AccountGroup is the data returned by reading account group data. @@ -65,7 +67,7 @@ func (a accountGroupAPI) Read(ctx context.Context, uuid string, name string) (*A } if query.AccountGroup.ID == "" { - return nil, NotFound{"Account group not found"} + return nil, api.NotFound{Message: "Account group not found"} } return &query.AccountGroup, nil diff --git a/internal/api/account_group_mapping.go b/internal/api/platform/account_group_mapping.go similarity index 95% rename from internal/api/account_group_mapping.go rename to internal/api/platform/account_group_mapping.go index f9c15612..87b82179 100644 --- a/internal/api/account_group_mapping.go +++ b/internal/api/platform/account_group_mapping.go @@ -1,11 +1,13 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) // AccountGroupMapping is the data returned by reading an account group mapping data. @@ -70,7 +72,7 @@ func (a accountGroupMappingAPI) Read(ctx context.Context, accountKey string, gro } if len(query.AccountGroup.AccountMappings.Edges) == 0 { - return nil, NotFound{"Account group mapping not found"} + return nil, api.NotFound{Message: "Account group mapping not found"} } node := query.AccountGroup.AccountMappings.Edges[0].Node diff --git a/internal/api/anthropic_integration.go b/internal/api/platform/anthropic_integration.go similarity index 92% rename from internal/api/anthropic_integration.go rename to internal/api/platform/anthropic_integration.go index c48f1570..2619e484 100644 --- a/internal/api/anthropic_integration.go +++ b/internal/api/platform/anthropic_integration.go @@ -1,11 +1,13 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) // AnthropicIntegration is the data for an Anthropic organization integration. @@ -60,7 +62,7 @@ func (a anthropicIntegrationAPI) Read(ctx context.Context, orgID string) (*Anthr return nil, err } if query.Payload.AnthropicIntegration == nil { - return nil, NotFound{"Anthropic integration not found"} + return nil, api.NotFound{Message: "Anthropic integration not found"} } return query.Payload.AnthropicIntegration, nil } @@ -75,7 +77,7 @@ func (a anthropicIntegrationAPI) Upsert(ctx context.Context, input AnthropicInte Problems []problem } `graphql:"upsertAnthropicIntegration(input: $input)"` } - ctx = maskSecrets(ctx, input.AdminKey) + ctx = api.MaskSecrets(ctx, input.AdminKey) if err := a.c.Mutate(ctx, &mutation, map[string]any{"input": input}); err != nil { return nil, err } @@ -83,7 +85,7 @@ func (a anthropicIntegrationAPI) Upsert(ctx context.Context, input AnthropicInte return nil, err } if mutation.Payload.AnthropicIntegration == nil { - return nil, NotFound{"Anthropic integration not found after upsert"} + return nil, api.NotFound{Message: "Anthropic integration not found after upsert"} } return mutation.Payload.AnthropicIntegration, nil } diff --git a/internal/api/api.go b/internal/api/platform/api.go similarity index 96% rename from internal/api/api.go rename to internal/api/platform/api.go index 4c7434e2..0de894ca 100644 --- a/internal/api/api.go +++ b/internal/api/platform/api.go @@ -1,7 +1,7 @@ // Copyright Stacklet, Inc. 2025, 2026 -// package api provides access to the GraphQL API. -package api +// package platform provides access to the platform GraphQL API. +package platform // API provides access to the GraphQL API. type API struct { diff --git a/internal/api/binding.go b/internal/api/platform/binding.go similarity index 96% rename from internal/api/binding.go rename to internal/api/platform/binding.go index 54adf1dc..b89a6758 100644 --- a/internal/api/binding.go +++ b/internal/api/platform/binding.go @@ -1,11 +1,13 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) // Binding is the data returned by reading binding details. @@ -152,7 +154,7 @@ func (a bindingAPI) Read(ctx context.Context, uuid string, name string) (*Bindin return nil, err } if query.Binding.ID == "" { - return nil, NotFound{"Binding not found"} + return nil, api.NotFound{Message: "Binding not found"} } return &query.Binding, nil @@ -165,7 +167,7 @@ func (a bindingAPI) Create(ctx context.Context, i BindingCreateInput) (*Binding, Binding Binding } `graphql:"addBinding(input: $input)"` } - ctx = maskSecrets(ctx, i.ExecutionConfig.securityContext()) + ctx = api.MaskSecrets(ctx, i.ExecutionConfig.securityContext()) input := map[string]any{"input": i} if err := a.c.Mutate(ctx, &mutation, input); err != nil { return nil, err @@ -181,7 +183,7 @@ func (a bindingAPI) Update(ctx context.Context, i BindingUpdateInput) (*Binding, Binding Binding } `graphql:"updateBinding(input: $input)"` } - ctx = maskSecrets(ctx, i.ExecutionConfig.securityContext()) + ctx = api.MaskSecrets(ctx, i.ExecutionConfig.securityContext()) input := map[string]any{"input": i} if err := a.c.Mutate(ctx, &mutation, input); err != nil { return nil, err diff --git a/internal/api/platform/client.go b/internal/api/platform/client.go new file mode 100644 index 00000000..4c76e3d7 --- /dev/null +++ b/internal/api/platform/client.go @@ -0,0 +1,93 @@ +// Copyright Stacklet, Inc. 2025, 2026 + +package platform + +import ( + "context" + "encoding/json" + "net/http" + "strings" + + "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" +) + +// ClientConfig is the configuration for the API client. +type ClientConfig struct { + Endpoint string + APIKey string + Version string + PageSize int +} + +// client is the wrapper for the GraphQL client. +type client struct { + c *graphql.Client + pageSize int +} + +// Query makes a GraphQL query call. +func (c *client) Query(ctx context.Context, q any, variables map[string]any) error { + err := c.c.Query(ctx, q, variables) + if err != nil { + return api.NewAPIError(err) + } + return nil +} + +// Mutate makes a GraphQL mutation call. +func (c *client) Mutate(ctx context.Context, m any, variables map[string]any) error { + err := c.c.Mutate(ctx, m, variables) + if err != nil { + return api.NewAPIError(err) + } + return nil +} + +// newClient returns a configured graphql Client. +func newClient(config ClientConfig) *client { + httpClient := &http.Client{ + Transport: &errorTransport{ + Base: api.NewTransport(config.APIKey, config.Version), + }, + } + return &client{ + c: graphql.NewClient(config.Endpoint, httpClient), + pageSize: config.PageSize, + } +} + +// errorTransport is an http.Transport that converts 400 responses with a +// GraphQL-style error payload into Go errors, so callers see the actual +// error messages rather than a generic "400 Bad Request". +type errorTransport struct { + Base http.RoundTripper +} + +func (t *errorTransport) RoundTrip(req *http.Request) (*http.Response, error) { + resp, err := t.Base.RoundTrip(req) + if err != nil || resp == nil || resp.StatusCode != http.StatusBadRequest { + return resp, err + } + + content, err := api.DecodeResponseBody(resp) + if err != nil { + return nil, err + } + + var payload struct { + Errors []struct { + Message string `json:"message"` + } `json:"errors"` + } + if json.Unmarshal([]byte(content), &payload) == nil && len(payload.Errors) > 0 { + msgs := make([]string, len(payload.Errors)) + for i, e := range payload.Errors { + msgs[i] = e.Message + } + return nil, api.APIError{Kind: "API Error", Detail: strings.Join(msgs, "\n")} + } + + return resp, nil +} diff --git a/internal/api/client_test.go b/internal/api/platform/client_test.go similarity index 70% rename from internal/api/client_test.go rename to internal/api/platform/client_test.go index 12dab9b3..6026e37a 100644 --- a/internal/api/client_test.go +++ b/internal/api/platform/client_test.go @@ -1,6 +1,6 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "bytes" @@ -15,56 +15,6 @@ import ( "github.com/stretchr/testify/assert" ) -func TestUserAgentHeader(t *testing.T) { - version := "1.2.3" - expectedUserAgent := "terraform-provider-stacklet/" + version - - var capturedUserAgent string - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - capturedUserAgent = r.Header.Get("User-Agent") - w.WriteHeader(http.StatusOK) - })) - defer server.Close() - - transport := &authTransport{ - APIKey: "test-api-key", - Version: version, - Base: http.DefaultTransport, - } - - client := &http.Client{Transport: transport} - req, _ := http.NewRequest("GET", server.URL, nil) - _, err := client.Do(req) - - assert.NoError(t, err) - assert.Equal(t, expectedUserAgent, capturedUserAgent) -} - -func TestAuthorizationHeader(t *testing.T) { - apiKey := "test-api-key-123" - expectedAuth := "Bearer " + apiKey - - var capturedAuth string - server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - capturedAuth = r.Header.Get("Authorization") - w.WriteHeader(http.StatusOK) - })) - defer server.Close() - - transport := &authTransport{ - APIKey: apiKey, - Version: "1.0.0", - Base: http.DefaultTransport, - } - - client := &http.Client{Transport: transport} - req, _ := http.NewRequest("GET", server.URL, nil) - _, err := client.Do(req) - - assert.NoError(t, err) - assert.Equal(t, expectedAuth, capturedAuth) -} - func TestErrorTransport_400WithGraphQLErrors(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusBadRequest) diff --git a/internal/api/common.go b/internal/api/platform/common.go similarity index 99% rename from internal/api/common.go rename to internal/api/platform/common.go index ac3203dd..caa6ef73 100644 --- a/internal/api/common.go +++ b/internal/api/platform/common.go @@ -1,6 +1,6 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "sort" diff --git a/internal/api/configuration_profile.go b/internal/api/platform/configuration_profile.go similarity index 95% rename from internal/api/configuration_profile.go rename to internal/api/platform/configuration_profile.go index 5fc14fb8..4adb3000 100644 --- a/internal/api/configuration_profile.go +++ b/internal/api/platform/configuration_profile.go @@ -1,11 +1,13 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) // UUID represents a UUID scalar type in GraphQL. @@ -308,7 +310,7 @@ func (a configurationProfileAPI) Read(ctx context.Context, name ConfigurationPro } if query.Configuration.ID == "" { - return nil, NotFound{"Configuration profile not found"} + return nil, api.NotFound{Message: "Configuration profile not found"} } return &query.Configuration, nil @@ -361,7 +363,7 @@ func (a configurationProfileAPI) UpsertJira(ctx context.Context, input JiraConfi Configuration ConfigurationProfile } `graphql:"addJiraProfile(input: $input)"` } - ctx = maskSecrets(ctx, &input.APIKey) + ctx = api.MaskSecrets(ctx, &input.APIKey) variables := map[string]any{ "input": jiraConfigurationInput{ JiraConfiguration: input, @@ -375,7 +377,7 @@ func (a configurationProfileAPI) UpsertJira(ctx context.Context, input JiraConfi } if mutation.Payload.Configuration.ID == "" { - return nil, NotFound{"Configuration profile not found after upsert"} + return nil, api.NotFound{Message: "Configuration profile not found after upsert"} } return &mutation.Payload.Configuration, nil @@ -400,7 +402,7 @@ func (a configurationProfileAPI) UpsertAccountOwners(ctx context.Context, input } if mutation.Payload.Configuration.ID == "" { - return nil, NotFound{"Configuration profile not found after upsert"} + return nil, api.NotFound{Message: "Configuration profile not found after upsert"} } return &mutation.Payload.Configuration, nil @@ -425,7 +427,7 @@ func (a configurationProfileAPI) UpsertResourceOwner(ctx context.Context, input } if mutation.Payload.Configuration.ID == "" { - return nil, NotFound{"Configuration profile not found after upsert"} + return nil, api.NotFound{Message: "Configuration profile not found after upsert"} } return &mutation.Payload.Configuration, nil @@ -442,7 +444,7 @@ func (a configurationProfileAPI) UpsertSlack(ctx context.Context, config SlackCo for _, w := range config.Webhooks { secrets = append(secrets, &w.URL) } - ctx = maskSecrets(ctx, secrets...) + ctx = api.MaskSecrets(ctx, secrets...) variables := map[string]any{ "input": slackConfigurationInput{ SlackConfiguration: config, @@ -456,7 +458,7 @@ func (a configurationProfileAPI) UpsertSlack(ctx context.Context, config SlackCo } if mutation.Payload.Configuration.ID == "" { - return nil, NotFound{"Configuration profile not found after upsert"} + return nil, api.NotFound{Message: "Configuration profile not found after upsert"} } return &mutation.Payload.Configuration, nil @@ -469,7 +471,7 @@ func (a configurationProfileAPI) UpsertServiceNow(ctx context.Context, config Se Configuration ConfigurationProfile } `graphql:"addServiceNowProfile(input: $input)"` } - ctx = maskSecrets(ctx, &config.Password) + ctx = api.MaskSecrets(ctx, &config.Password) variables := map[string]any{ "input": serviceNowConfigurationInput{ ServiceNowConfiguration: config, @@ -483,7 +485,7 @@ func (a configurationProfileAPI) UpsertServiceNow(ctx context.Context, config Se } if mutation.Payload.Configuration.ID == "" { - return nil, NotFound{"Configuration profile not found after upsert"} + return nil, api.NotFound{Message: "Configuration profile not found after upsert"} } return &mutation.Payload.Configuration, nil @@ -496,7 +498,7 @@ func (a configurationProfileAPI) UpsertSymphony(ctx context.Context, config Symp Configuration ConfigurationProfile } `graphql:"addSymphonyProfile(input: $input)"` } - ctx = maskSecrets(ctx, &config.PrivateKey) + ctx = api.MaskSecrets(ctx, &config.PrivateKey) variables := map[string]any{ "input": symphonyConfigurationInput{ SymphonyConfiguration: config, @@ -510,7 +512,7 @@ func (a configurationProfileAPI) UpsertSymphony(ctx context.Context, config Symp } if mutation.Payload.Configuration.ID == "" { - return nil, NotFound{"Configuration profile not found after upsert"} + return nil, api.NotFound{Message: "Configuration profile not found after upsert"} } return &mutation.Payload.Configuration, nil @@ -524,7 +526,7 @@ func (a configurationProfileAPI) UpsertEmail(ctx context.Context, input EmailCon } `graphql:"addEmailProfile(input: $input)"` } if input.SMTP != nil { - ctx = maskSecrets(ctx, input.SMTP.Password) + ctx = api.MaskSecrets(ctx, input.SMTP.Password) } variables := map[string]any{ "input": emailConfigurationInput{ @@ -539,7 +541,7 @@ func (a configurationProfileAPI) UpsertEmail(ctx context.Context, input EmailCon } if mutation.Payload.Configuration.ID == "" { - return nil, NotFound{"Configuration profile not found after upsert"} + return nil, api.NotFound{Message: "Configuration profile not found after upsert"} } return &mutation.Payload.Configuration, nil @@ -565,7 +567,7 @@ func (a configurationProfileAPI) UpsertMSTeams(ctx context.Context, input MSTeam } if mutation.Payload.Configuration.ID == "" { - return nil, NotFound{"Configuration profile not found after upsert"} + return nil, api.NotFound{Message: "Configuration profile not found after upsert"} } return &mutation.Payload.Configuration, nil diff --git a/internal/api/datadog_integration.go b/internal/api/platform/datadog_integration.go similarity index 92% rename from internal/api/datadog_integration.go rename to internal/api/platform/datadog_integration.go index 3997eaa7..30547bd1 100644 --- a/internal/api/datadog_integration.go +++ b/internal/api/platform/datadog_integration.go @@ -1,9 +1,11 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) // DatadogIntegration is the data for the site-wide Datadog integration. @@ -58,7 +60,7 @@ func (a datadogIntegrationAPI) Update(ctx context.Context, input DatadogIntegrat Problems []problem } `graphql:"updateDatadogIntegration(input: $input)"` } - ctx = maskSecrets(ctx, input.APIKey, input.AppKey) + ctx = api.MaskSecrets(ctx, input.APIKey, input.AppKey) if err := a.c.Mutate(ctx, &mutation, map[string]any{"input": input}); err != nil { return nil, err } @@ -66,7 +68,7 @@ func (a datadogIntegrationAPI) Update(ctx context.Context, input DatadogIntegrat return nil, err } if mutation.Payload.DatadogIntegration == nil { - return nil, NotFound{"Datadog integration not found after update"} + return nil, api.NotFound{Message: "Datadog integration not found after update"} } return mutation.Payload.DatadogIntegration, nil } diff --git a/internal/api/enums.go b/internal/api/platform/enums.go similarity index 98% rename from internal/api/enums.go rename to internal/api/platform/enums.go index 6eecc00f..0e900835 100644 --- a/internal/api/enums.go +++ b/internal/api/platform/enums.go @@ -1,6 +1,6 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform // CloudProvider represents a cloud service provider in Stacklet. type CloudProvider StringEnum diff --git a/internal/api/platform/error.go b/internal/api/platform/error.go new file mode 100644 index 00000000..d1eeee1a --- /dev/null +++ b/internal/api/platform/error.go @@ -0,0 +1,35 @@ +// Copyright Stacklet, Inc. 2025, 2026 + +package platform + +import ( + "context" + + "github.com/hashicorp/terraform-plugin-log/tflog" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" +) + +// fromProblems returns an error from a list of API problems. +func fromProblems(ctx context.Context, problems []problem) error { + if len(problems) == 0 { + return nil + } + for _, problem := range problems[1:] { + info := map[string]any{"kind": problem.Kind, "message": problem.Message} + tflog.Error(ctx, "discarding additional error", info) + } + switch problems[0].Kind { + case "NotFound": + return api.NotFound{Message: problems[0].Message} + case "Conflict": + return api.Conflict{Message: problems[0].Message} + } + return api.APIError{Kind: problems[0].Kind, Detail: problems[0].Message} +} + +// problem contains the details for an API query error. +type problem struct { + Kind string `graphql:"__typename"` + Message string +} diff --git a/internal/api/platform/error_test.go b/internal/api/platform/error_test.go new file mode 100644 index 00000000..8a2fbab7 --- /dev/null +++ b/internal/api/platform/error_test.go @@ -0,0 +1,36 @@ +// Copyright Stacklet, Inc. 2025, 2026 + +package platform + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" +) + +func TestFromProblems(t *testing.T) { + ctx := context.Background() + tests := []struct { + name string + problems []problem + want error + }{ + {"none", nil, nil}, + {"not found", []problem{{Kind: "NotFound", Message: "gone"}}, api.NotFound{Message: "gone"}}, + {"conflict", []problem{{Kind: "Conflict", Message: "try again"}}, api.Conflict{Message: "try again"}}, + {"other", []problem{{Kind: "InvalidInput", Message: "bad key"}}, api.APIError{Kind: "InvalidInput", Detail: "bad key"}}, + { + "first of several", + []problem{{Kind: "InvalidInput", Message: "first"}, {Kind: "NotFound", Message: "second"}}, + api.APIError{Kind: "InvalidInput", Detail: "first"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equal(t, tt.want, fromProblems(ctx, tt.problems)) + }) + } +} diff --git a/internal/api/filter.go b/internal/api/platform/filter.go similarity index 99% rename from internal/api/filter.go rename to internal/api/platform/filter.go index 937c6aec..57f56450 100644 --- a/internal/api/filter.go +++ b/internal/api/platform/filter.go @@ -1,6 +1,6 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform // filterBooleanOperator represents a boolean operation fora filter. type filterBooleanOperator StringEnum diff --git a/internal/api/gcp_integration.go b/internal/api/platform/gcp_integration.go similarity index 97% rename from internal/api/gcp_integration.go rename to internal/api/platform/gcp_integration.go index a7eb2140..83b9dd81 100644 --- a/internal/api/gcp_integration.go +++ b/internal/api/platform/gcp_integration.go @@ -1,11 +1,13 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) // GCPIntegration is the data for a GCP integration. @@ -211,7 +213,7 @@ func (a gcpIntegrationAPI) Read(ctx context.Context, key string) (*GCPIntegratio return nil, err } if query.Payload.GCPIntegration == nil { - return nil, NotFound{"GCP integration not found"} + return nil, api.NotFound{Message: "GCP integration not found"} } return query.Payload.GCPIntegration, nil } @@ -231,7 +233,7 @@ func (a gcpIntegrationAPI) Upsert(ctx context.Context, input GCPIntegrationInput return nil, err } if mutation.Payload.GCPIntegration == nil { - return nil, NotFound{"GCP integration not found after upsert"} + return nil, api.NotFound{Message: "GCP integration not found after upsert"} } return mutation.Payload.GCPIntegration, nil } diff --git a/internal/api/notification_template.go b/internal/api/platform/notification_template.go similarity index 92% rename from internal/api/notification_template.go rename to internal/api/platform/notification_template.go index 9fa84ea8..e831fcee 100644 --- a/internal/api/notification_template.go +++ b/internal/api/platform/notification_template.go @@ -1,11 +1,13 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) // Template is the data returned for a notification template. @@ -39,7 +41,7 @@ func (a templateAPI) Read(ctx context.Context, name string) (*Template, error) { return nil, err } if query.Template.ID == "" { - return nil, NotFound{"Template not found"} + return nil, api.NotFound{Message: "Template not found"} } return &query.Template, nil diff --git a/internal/api/policy.go b/internal/api/platform/policy.go similarity index 91% rename from internal/api/policy.go rename to internal/api/platform/policy.go index cb20b8b6..acfaf09a 100644 --- a/internal/api/policy.go +++ b/internal/api/platform/policy.go @@ -1,11 +1,13 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) // Policy is the data returned by reading policy data. @@ -45,7 +47,7 @@ func (a policyAPI) Read(ctx context.Context, uuid string, name string, version i } if query.Policy.ID == "" { - return nil, NotFound{"Policy not found"} + return nil, api.NotFound{Message: "Policy not found"} } return &query.Policy, nil diff --git a/internal/api/policy_collection.go b/internal/api/platform/policy_collection.go similarity index 96% rename from internal/api/policy_collection.go rename to internal/api/platform/policy_collection.go index 9eb359c4..edcabed9 100644 --- a/internal/api/policy_collection.go +++ b/internal/api/platform/policy_collection.go @@ -1,11 +1,13 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) // Account is the data returned by reading policy collection data. @@ -84,7 +86,7 @@ func (a policyCollectionAPI) Read(ctx context.Context, uuid string, name string) } if query.PolicyCollection.ID == "" { - return nil, NotFound{"Policy collection not found"} + return nil, api.NotFound{Message: "Policy collection not found"} } return &query.PolicyCollection, nil diff --git a/internal/api/policy_collection_mapping.go b/internal/api/platform/policy_collection_mapping.go similarity index 95% rename from internal/api/policy_collection_mapping.go rename to internal/api/platform/policy_collection_mapping.go index 7f0e0b00..109785cd 100644 --- a/internal/api/policy_collection_mapping.go +++ b/internal/api/platform/policy_collection_mapping.go @@ -1,11 +1,13 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) // PolicyCollectionMapping is the data returned by reading a policy collection mapping. @@ -75,7 +77,7 @@ func (a policyCollectionMappingAPI) Read(ctx context.Context, collectionUUID str } if len(query.PolicyCollection.PolicyMappings.Edges) == 0 { - return nil, NotFound{"Policy collection mapping not found"} + return nil, api.NotFound{Message: "Policy collection mapping not found"} } return &query.PolicyCollection.PolicyMappings.Edges[0].Node, nil diff --git a/internal/api/report_group.go b/internal/api/platform/report_group.go similarity index 97% rename from internal/api/report_group.go rename to internal/api/platform/report_group.go index 3fdd1db4..0c20f180 100644 --- a/internal/api/report_group.go +++ b/internal/api/platform/report_group.go @@ -1,11 +1,13 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) // ReportGroup is the data for a notification report group. @@ -196,7 +198,7 @@ func (a reportGroupAPI) Read(ctx context.Context, name string) (*ReportGroup, er } if query.ReportGroup.ID == "" { - return nil, NotFound{"Report group not found"} + return nil, api.NotFound{Message: "Report group not found"} } return &query.ReportGroup, nil @@ -219,7 +221,7 @@ func (a reportGroupAPI) Upsert(ctx context.Context, input ReportGroupInput) (*Re } if len(mutation.Payload.ReportGroups) == 0 { - return nil, NotFound{"Report group not found after upsert"} + return nil, api.NotFound{Message: "Report group not found after upsert"} } return &mutation.Payload.ReportGroups[0], nil } diff --git a/internal/api/repository.go b/internal/api/platform/repository.go similarity index 96% rename from internal/api/repository.go rename to internal/api/platform/repository.go index 1ca95eb7..dd8912da 100644 --- a/internal/api/repository.go +++ b/internal/api/platform/repository.go @@ -1,12 +1,14 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" "encoding/json" "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) type Repository struct { @@ -169,7 +171,7 @@ func (a repositoryAPI) FindByURL(ctx context.Context, url string) (string, error } } if !query.Conn.PageInfo.HasNextPage { - return "", NotFound{"Repository not found"} + return "", api.NotFound{Message: "Repository not found"} } cursor = query.Conn.PageInfo.EndCursor } @@ -182,7 +184,7 @@ func (a repositoryAPI) Create(ctx context.Context, i RepositoryCreateInput) (*Re Problems []problem } `graphql:"addRepositoryConfig(input: $input)"` } - ctx = maskSecrets(ctx, i.Auth.secrets()...) + ctx = api.MaskSecrets(ctx, i.Auth.secrets()...) if err := a.c.Mutate(ctx, &m, map[string]any{"input": i}); err != nil { return nil, err } @@ -199,7 +201,7 @@ func (a repositoryAPI) Update(ctx context.Context, i RepositoryUpdateInput) (*Re Problems []problem } `graphql:"updateRepositoryConfig(input: $input)"` } - ctx = maskSecrets(ctx, i.Auth.secrets()...) + ctx = api.MaskSecrets(ctx, i.Auth.secrets()...) if err := a.c.Mutate(ctx, &m, map[string]any{"input": i}); err != nil { return nil, err } diff --git a/internal/api/role.go b/internal/api/platform/role.go similarity index 86% rename from internal/api/role.go rename to internal/api/platform/role.go index adef023d..e0100406 100644 --- a/internal/api/role.go +++ b/internal/api/platform/role.go @@ -1,11 +1,13 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) // Role is the data returned by reading role data. @@ -37,7 +39,7 @@ func (r roleAPI) Read(ctx context.Context, name string) (*Role, error) { } if len(query.Roles.Edges) == 0 { - return nil, NotFound{"Role not found"} + return nil, api.NotFound{Message: "Role not found"} } return &query.Roles.Edges[0].Node, nil diff --git a/internal/api/role_assignment.go b/internal/api/platform/role_assignment.go similarity index 93% rename from internal/api/role_assignment.go rename to internal/api/platform/role_assignment.go index 00680232..cfc1b243 100644 --- a/internal/api/role_assignment.go +++ b/internal/api/platform/role_assignment.go @@ -1,12 +1,14 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" "fmt" "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) // RoleAssignment is the data returned by reading role assignment data. @@ -124,16 +126,16 @@ func (a roleAssignmentAPI) Create(ctx context.Context, roleName string, principa } if len(mutation.UpdateRoleAssignment.Grant) == 0 { - return nil, NotFound{"Role assignment not found after creation"} + return nil, api.NotFound{Message: "Role assignment not found after creation"} } grantPayload := mutation.UpdateRoleAssignment.Grant[0] if grantPayload.Error() != "" { - return nil, newAPIError(fmt.Errorf("failed to grant role assignment: %w", grantPayload)) + return nil, api.NewAPIError(fmt.Errorf("failed to grant role assignment: %w", grantPayload)) } if grantPayload.RoleAssignment == nil { - return nil, NotFound{"Role assignment not found after creation"} + return nil, api.NotFound{Message: "Role assignment not found after creation"} } return a.Read(ctx, roleName, principal, target) @@ -159,7 +161,7 @@ func (a roleAssignmentAPI) Read(ctx context.Context, roleName string, principal return &assignment, nil } } - return nil, NotFound{"Role assignment not found"} + return nil, api.NotFound{Message: "Role assignment not found"} } // Delete removes a role assignment. @@ -195,7 +197,7 @@ func (a roleAssignmentAPI) Delete(ctx context.Context, roleName string, principa if len(mutation.UpdateRoleAssignment.Revoke) > 0 { revokePayload := mutation.UpdateRoleAssignment.Revoke[0] if revokePayload.Error() != "" { - return newAPIError(fmt.Errorf("failed to revoke role assignment: %w", revokePayload)) + return api.NewAPIError(fmt.Errorf("failed to revoke role assignment: %w", revokePayload)) } } diff --git a/internal/api/saml_provider.go b/internal/api/platform/saml_provider.go similarity index 93% rename from internal/api/saml_provider.go rename to internal/api/platform/saml_provider.go index 26a68fb6..7bb90667 100644 --- a/internal/api/saml_provider.go +++ b/internal/api/platform/saml_provider.go @@ -1,11 +1,13 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) // SAMLProvider is the data returned by reading SAML provider data. @@ -76,7 +78,7 @@ func (a samlProviderAPI) Read(ctx context.Context, name string) (*SAMLProvider, return nil, err } if query.SAMLProvider == nil { - return nil, NotFound{"SAML provider not found"} + return nil, api.NotFound{Message: "SAML provider not found"} } return query.SAMLProvider, nil } @@ -96,7 +98,7 @@ func (a samlProviderAPI) Create(ctx context.Context, i SAMLProviderCreateInput) return nil, err } if mutation.Payload.Provider == nil { - return nil, NotFound{"SAML provider not found after creation"} + return nil, api.NotFound{Message: "SAML provider not found after creation"} } return mutation.Payload.Provider, nil } @@ -116,7 +118,7 @@ func (a samlProviderAPI) Update(ctx context.Context, i SAMLProviderUpdateInput) return nil, err } if mutation.Payload.Provider == nil { - return nil, NotFound{"SAML provider not found after update"} + return nil, api.NotFound{Message: "SAML provider not found after update"} } return mutation.Payload.Provider, nil } diff --git a/internal/api/sso_group.go b/internal/api/platform/sso_group.go similarity index 88% rename from internal/api/sso_group.go rename to internal/api/platform/sso_group.go index 576ca309..e1be9027 100644 --- a/internal/api/sso_group.go +++ b/internal/api/platform/sso_group.go @@ -1,12 +1,14 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" "fmt" "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) // SSOGroup is the data returned by reading SSO group data. @@ -91,7 +93,7 @@ func (a ssoGroupAPI) Read(ctx context.Context, name string) (*SSOGroup, error) { } if len(query.SSOGroups.Edges) == 0 { - return nil, NotFound{"SSO group not found"} + return nil, api.NotFound{Message: "SSO group not found"} } return &query.SSOGroups.Edges[0].Node, nil @@ -114,14 +116,14 @@ func (a ssoGroupAPI) Upsert(ctx context.Context, input SSOGroupInput) (*SSOGroup } if len(mutation.Payload.Response) == 0 { - return nil, NotFound{"SSO group not found after upsert"} + return nil, api.NotFound{Message: "SSO group not found after upsert"} } payload := mutation.Payload.Response[0] if payload.Error() != "" { - return nil, newAPIError(fmt.Errorf("failed to upsert SSO group: %w", payload)) + return nil, api.NewAPIError(fmt.Errorf("failed to upsert SSO group: %w", payload)) } if payload.SSOGroup == nil { - return nil, NotFound{"SSO group not found after upsert"} + return nil, api.NotFound{Message: "SSO group not found after upsert"} } return payload.SSOGroup, nil } @@ -142,7 +144,7 @@ func (a ssoGroupAPI) Delete(ctx context.Context, name string) error { if len(mutation.Payload.Response) > 0 { payload := mutation.Payload.Response[0] if payload.Error() != "" { - return newAPIError(fmt.Errorf("failed to remove SSO group: %w", payload)) + return api.NewAPIError(fmt.Errorf("failed to remove SSO group: %w", payload)) } } return nil diff --git a/internal/api/system.go b/internal/api/platform/system.go similarity index 99% rename from internal/api/system.go rename to internal/api/platform/system.go index 4551b6b6..228c05ff 100644 --- a/internal/api/system.go +++ b/internal/api/platform/system.go @@ -1,6 +1,6 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" diff --git a/internal/api/types.go b/internal/api/platform/types.go similarity index 98% rename from internal/api/types.go rename to internal/api/platform/types.go index bd1422a5..f213ab38 100644 --- a/internal/api/types.go +++ b/internal/api/platform/types.go @@ -1,6 +1,6 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "encoding/json" diff --git a/internal/api/user.go b/internal/api/platform/user.go similarity index 95% rename from internal/api/user.go rename to internal/api/platform/user.go index a037ea10..cf02a288 100644 --- a/internal/api/user.go +++ b/internal/api/platform/user.go @@ -1,11 +1,13 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) // User is the data returned by reading user data. @@ -70,7 +72,7 @@ func (u userAPI) Read(ctx context.Context, username string) (*User, error) { } if len(query.Users.Edges) == 0 { - return nil, NotFound{"User not found"} + return nil, api.NotFound{Message: "User not found"} } return &query.Users.Edges[0].Node, nil diff --git a/internal/api/user_group.go b/internal/api/platform/user_group.go similarity index 91% rename from internal/api/user_group.go rename to internal/api/platform/user_group.go index 63fb7723..7cbb5e13 100644 --- a/internal/api/user_group.go +++ b/internal/api/platform/user_group.go @@ -1,11 +1,13 @@ // Copyright Stacklet, Inc. 2025, 2026 -package api +package platform import ( "context" "github.com/hasura/go-graphql-client" + + "github.com/stacklet/terraform-provider-stacklet/internal/api" ) // UserGroup is the data returned by reading user group data. @@ -64,7 +66,7 @@ func (a userGroupAPI) Read(ctx context.Context, uuid string) (*UserGroup, error) return nil, err } if query.UserGroup == nil { - return nil, NotFound{"User group not found"} + return nil, api.NotFound{Message: "User group not found"} } return query.UserGroup, nil } @@ -85,7 +87,7 @@ func (a userGroupAPI) ReadByName(ctx context.Context, name string) (*UserGroup, return nil, err } if len(query.UserGroups.Edges) == 0 { - return nil, NotFound{"User group not found"} + return nil, api.NotFound{Message: "User group not found"} } return &query.UserGroups.Edges[0].Node, nil } @@ -101,7 +103,7 @@ func (a userGroupAPI) Create(ctx context.Context, i UserGroupCreateInput) (*User return nil, err } if mutation.Payload.UserGroup == nil { - return nil, NotFound{"User group not found after creation"} + return nil, api.NotFound{Message: "User group not found after creation"} } return mutation.Payload.UserGroup, nil } @@ -117,7 +119,7 @@ func (a userGroupAPI) Update(ctx context.Context, i UserGroupUpdateInput) (*User return nil, err } if mutation.Payload.UserGroup == nil { - return nil, NotFound{"User group not found after update"} + return nil, api.NotFound{Message: "User group not found after update"} } return mutation.Payload.UserGroup, nil } diff --git a/internal/api/transport.go b/internal/api/transport.go new file mode 100644 index 00000000..02b18206 --- /dev/null +++ b/internal/api/transport.go @@ -0,0 +1,133 @@ +// Copyright Stacklet, Inc. 2025, 2026 + +// package api provides functionality shared by the API clients. +package api + +import ( + "bytes" + "fmt" + "io" + "net/http" + "os" + + "github.com/hashicorp/go-hclog" + "github.com/hashicorp/terraform-plugin-log/tflog" +) + +// NewTransport returns an http.RoundTripper which authenticates and logs requests. +func NewTransport(apiKey string, version string) http.RoundTripper { + tfLog := hclog.LevelFromString(os.Getenv("TF_LOG")) + logBody := tfLog == hclog.Debug || tfLog == hclog.Trace + + return &AuthTransport{ + APIKey: apiKey, + Version: version, + Base: &LogTransport{ + Base: http.DefaultTransport, + LogBody: logBody, + }, + } +} + +// AuthTransport is an http.Transport that adds authorization header. +type AuthTransport struct { + APIKey string + Version string + Base http.RoundTripper +} + +func (t *AuthTransport) RoundTrip(req *http.Request) (*http.Response, error) { + if t.APIKey == "" { + return nil, fmt.Errorf("no API key provided") + } + req.Header.Set("Authorization", "Bearer "+t.APIKey) + req.Header.Set("User-Agent", "terraform-provider-stacklet/"+t.Version) + return t.Base.RoundTrip(req) +} + +// LogTransport is an http.Transport that logs requests/responses through the +// request's context, so the logs apply whatever masking the caller set up. +type LogTransport struct { + Base http.RoundTripper + LogBody bool +} + +func (t *LogTransport) RoundTrip(req *http.Request) (*http.Response, error) { + var reqBody, respBody string + var err error + + // Decode the request before performing it since it will otherwise consume the body + if t.LogBody { + reqBody, err = DecodeRequestBody(req) + if err != nil { + return nil, err + } + } + + tflog.Debug( + req.Context(), + "Performing API request", + map[string]any{ + "req_method": req.Method, + "req_url": req.URL.String(), + "req_body": reqBody, + }, + ) + + resp, reqErr := t.Base.RoundTrip(req) + + if resp != nil { + if t.LogBody { + respBody, err = DecodeResponseBody(resp) + if err != nil { + return nil, err + } + } + + tflog.Debug( + req.Context(), + "Got API response", + map[string]any{ + "req_method": req.Method, + "req_url": req.URL.String(), + "resp_status": resp.Status, + "resp_status_code": resp.StatusCode, + "req_body": reqBody, + "resp_body": respBody, + }, + ) + } + + return resp, reqErr +} + +// DecodeRequestBody returns the request body, leaving it readable again. +func DecodeRequestBody(req *http.Request) (string, error) { + if req.Body == nil || req.Body == http.NoBody { + return "", nil + } + + content, err := io.ReadAll(req.Body) + if err != nil { + return "", err + } + req.Body = io.NopCloser(bytes.NewReader(content)) + + return string(content), nil +} + +// DecodeResponseBody returns the response body, leaving it readable again. +func DecodeResponseBody(resp *http.Response) (string, error) { + if resp.Body == nil || resp.Body == http.NoBody { + return "", nil + } + defer resp.Body.Close() + + content, err := io.ReadAll(resp.Body) + if err != nil { + return "", err + } + resp.Body = io.NopCloser(bytes.NewReader(content)) + + return string(content), nil +} diff --git a/internal/api/transport_test.go b/internal/api/transport_test.go new file mode 100644 index 00000000..b24a115f --- /dev/null +++ b/internal/api/transport_test.go @@ -0,0 +1,61 @@ +// Copyright Stacklet, Inc. 2025, 2026 + +package api + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestUserAgentHeader(t *testing.T) { + version := "1.2.3" + expectedUserAgent := "terraform-provider-stacklet/" + version + + var capturedUserAgent string + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + capturedUserAgent = r.Header.Get("User-Agent") + w.WriteHeader(http.StatusOK) + })) + defer server.Close() + + transport := &AuthTransport{ + APIKey: "test-api-key", + Version: version, + Base: http.DefaultTransport, + } + + client := &http.Client{Transport: transport} + req, _ := http.NewRequest("GET", server.URL, nil) + _, err := client.Do(req) + + assert.NoError(t, err) + assert.Equal(t, expectedUserAgent, capturedUserAgent) +} + +func TestAuthorizationHeader(t *testing.T) { + apiKey := "test-api-key-123" + expectedAuth := "Bearer " + apiKey + + var capturedAuth string + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + capturedAuth = r.Header.Get("Authorization") + w.WriteHeader(http.StatusOK) + })) + defer server.Close() + + transport := &AuthTransport{ + APIKey: apiKey, + Version: "1.0.0", + Base: http.DefaultTransport, + } + + client := &http.Client{Transport: transport} + req, _ := http.NewRequest("GET", server.URL, nil) + _, err := client.Do(req) + + assert.NoError(t, err) + assert.Equal(t, expectedAuth, capturedAuth) +} diff --git a/internal/datasources/datasource.go b/internal/datasources/datasource.go index 8d818922..27dd4370 100644 --- a/internal/datasources/datasource.go +++ b/internal/datasources/datasource.go @@ -7,14 +7,14 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/providerdata" ) // apiDataSource is a datasource based on the API. type apiDataSource struct { - api *api.API + api *platform.API } // Configure sets up API access for the datasource. diff --git a/internal/models/account.go b/internal/models/account.go index 82e86ce6..e8607fe6 100644 --- a/internal/models/account.go +++ b/internal/models/account.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -25,7 +25,7 @@ type AccountDataSource struct { Variables types.String `tfsdk:"variables"` } -func (m *AccountDataSource) Update(account *api.Account) diag.Diagnostics { +func (m *AccountDataSource) Update(account *platform.Account) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(account.ID) @@ -53,7 +53,7 @@ type AccountResource struct { SecurityContextWOVersion types.String `tfsdk:"security_context_wo_version"` } -func (m *AccountResource) Update(account *api.Account) diag.Diagnostics { +func (m *AccountResource) Update(account *platform.Account) diag.Diagnostics { // Save original value for resource-specific logic originalVariables := m.Variables diff --git a/internal/models/account_discovery_aws.go b/internal/models/account_discovery_aws.go index a6662f34..4aea3d10 100644 --- a/internal/models/account_discovery_aws.go +++ b/internal/models/account_discovery_aws.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -22,7 +22,7 @@ type AccountDiscoveryAWSResource struct { CustodianRole types.String `tfsdk:"custodian_role"` } -func (m *AccountDiscoveryAWSResource) Update(accountDiscovery *api.AccountDiscovery) diag.Diagnostics { +func (m *AccountDiscoveryAWSResource) Update(accountDiscovery *platform.AccountDiscovery) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(accountDiscovery.ID) diff --git a/internal/models/account_discovery_azure.go b/internal/models/account_discovery_azure.go index 614d8155..0c9ce491 100644 --- a/internal/models/account_discovery_azure.go +++ b/internal/models/account_discovery_azure.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -21,7 +21,7 @@ type AccountDiscoveryAzureResource struct { ClientSecret types.String `tfsdk:"client_secret_wo"` } -func (m *AccountDiscoveryAzureResource) Update(accountDiscovery *api.AccountDiscovery) diag.Diagnostics { +func (m *AccountDiscoveryAzureResource) Update(accountDiscovery *platform.AccountDiscovery) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(accountDiscovery.ID) diff --git a/internal/models/account_discovery_gcp.go b/internal/models/account_discovery_gcp.go index 58075290..f006d9d2 100644 --- a/internal/models/account_discovery_gcp.go +++ b/internal/models/account_discovery_gcp.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -27,7 +27,7 @@ type AccountDiscoveryGCPResource struct { CredentialJSONVersion types.String `tfsdk:"credential_json_wo_version"` } -func (m *AccountDiscoveryGCPResource) Update(accountDiscovery *api.AccountDiscovery) diag.Diagnostics { +func (m *AccountDiscoveryGCPResource) Update(accountDiscovery *platform.AccountDiscovery) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(accountDiscovery.ID) diff --git a/internal/models/account_group.go b/internal/models/account_group.go index 1946a1fb..209c2beb 100644 --- a/internal/models/account_group.go +++ b/internal/models/account_group.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -22,7 +22,7 @@ type AccountGroupResource struct { RoleAssignmentTarget types.String `tfsdk:"role_assignment_target"` } -func (m *AccountGroupResource) Update(accountGroup *api.AccountGroup) diag.Diagnostics { +func (m *AccountGroupResource) Update(accountGroup *platform.AccountGroup) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(accountGroup.ID) diff --git a/internal/models/account_group_mapping.go b/internal/models/account_group_mapping.go index 6365fb17..c7e9ad2e 100644 --- a/internal/models/account_group_mapping.go +++ b/internal/models/account_group_mapping.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -17,7 +17,7 @@ type AccountGroupMappingResource struct { AccountKey types.String `tfsdk:"account_key"` } -func (m *AccountGroupMappingResource) Update(accountGroupMapping *api.AccountGroupMapping) diag.Diagnostics { +func (m *AccountGroupMappingResource) Update(accountGroupMapping *platform.AccountGroupMapping) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(accountGroupMapping.ID) diff --git a/internal/models/account_test.go b/internal/models/account_test.go index 8ac507db..2bbe44af 100644 --- a/internal/models/account_test.go +++ b/internal/models/account_test.go @@ -6,7 +6,7 @@ import ( "testing" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" ) func strPtr(s string) *string { return &s } @@ -18,11 +18,11 @@ func TestAccountResourceUpdate_VariablesNullWhenAPIReturnsEmptyObject(t *testing m := &AccountResource{} m.Variables = types.StringNull() - account := &api.Account{ + account := &platform.Account{ ID: "id-1", Key: "123456789012", Name: "test", - Provider: api.CloudProvider("AWS"), + Provider: platform.CloudProvider("AWS"), Variables: strPtr("{}"), } @@ -41,11 +41,11 @@ func TestAccountResourceUpdate_VariablesPreservedWhenSet(t *testing.T) { m := &AccountResource{} m.Variables = types.StringValue(`{"env":"prod"}`) - account := &api.Account{ + account := &platform.Account{ ID: "id-1", Key: "123456789012", Name: "test", - Provider: api.CloudProvider("AWS"), + Provider: platform.CloudProvider("AWS"), Variables: strPtr(`{"env":"prod"}`), } @@ -63,11 +63,11 @@ func TestAccountResourceUpdate_VariablesNullWhenAPIReturnsNil(t *testing.T) { m := &AccountResource{} m.Variables = types.StringNull() - account := &api.Account{ + account := &platform.Account{ ID: "id-1", Key: "123456789012", Name: "test", - Provider: api.CloudProvider("AWS"), + Provider: platform.CloudProvider("AWS"), // Variables is nil } diff --git a/internal/models/anthropic_integration.go b/internal/models/anthropic_integration.go index 6b2f8349..17cadca4 100644 --- a/internal/models/anthropic_integration.go +++ b/internal/models/anthropic_integration.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -17,7 +17,7 @@ type AnthropicIntegrationDataSource struct { Configured types.Bool `tfsdk:"configured"` } -func (m *AnthropicIntegrationDataSource) Update(integration *api.AnthropicIntegration) diag.Diagnostics { +func (m *AnthropicIntegrationDataSource) Update(integration *platform.AnthropicIntegration) diag.Diagnostics { m.ID = typehelpers.GraphQLIDValue(integration.ID) m.OrgID = types.StringValue(integration.OrgID) m.Configured = types.BoolValue(integration.Configured) diff --git a/internal/models/binding.go b/internal/models/binding.go index 2507ed1f..6ca782af 100644 --- a/internal/models/binding.go +++ b/internal/models/binding.go @@ -9,7 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -32,7 +32,7 @@ type BindingDataSource struct { Variables types.String `tfsdk:"variables"` } -func (m *BindingDataSource) Update(ctx context.Context, binding *api.Binding) diag.Diagnostics { +func (m *BindingDataSource) Update(ctx context.Context, binding *platform.Binding) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(binding.ID) @@ -68,7 +68,7 @@ func (m *BindingDataSource) Update(ctx context.Context, binding *api.Binding) di policyLimits, d := typehelpers.ObjectList[BindingExecutionConfigPolicyResourceLimit]( binding.PolicyResourceLimits(), - func(entry api.BindingExecutionConfigResourceLimitsPolicyOverrides) (map[string]attr.Value, diag.Diagnostics) { + func(entry platform.BindingExecutionConfigResourceLimitsPolicyOverrides) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "policy_name": types.StringValue(entry.PolicyName), "max_count": types.Int32PointerValue(entry.Limit.MaxCount), @@ -91,7 +91,7 @@ type BindingResource struct { SecurityContextWOVersion types.String `tfsdk:"security_context_wo_version"` } -func (m *BindingResource) Update(ctx context.Context, binding *api.Binding) diag.Diagnostics { +func (m *BindingResource) Update(ctx context.Context, binding *platform.Binding) diag.Diagnostics { // Save original values for resource-specific logic originalVariables := m.Variables originalResourceLimits := m.ResourceLimits diff --git a/internal/models/configuration_profile_account_owners.go b/internal/models/configuration_profile_account_owners.go index 0aa17357..d52bdd8f 100644 --- a/internal/models/configuration_profile_account_owners.go +++ b/internal/models/configuration_profile_account_owners.go @@ -7,7 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -22,7 +22,7 @@ type ConfigurationProfileAccountOwnersDataSource struct { Tags types.List `tfsdk:"tags"` } -func (m *ConfigurationProfileAccountOwnersDataSource) Update(cp api.ConfigurationProfile) diag.Diagnostics { +func (m *ConfigurationProfileAccountOwnersDataSource) Update(cp platform.ConfigurationProfile) diag.Diagnostics { var diags diag.Diagnostics config := cp.Record.AccountOwnersConfiguration @@ -35,7 +35,7 @@ func (m *ConfigurationProfileAccountOwnersDataSource) Update(cp api.Configuratio defaultOwners, d := typehelpers.ObjectList[AccountOwners]( config.Default, - func(entry api.AccountOwners) (map[string]attr.Value, diag.Diagnostics) { + func(entry platform.AccountOwners) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "account": types.StringValue(entry.Account), "owners": typehelpers.StringsList(entry.Owners), diff --git a/internal/models/configuration_profile_email.go b/internal/models/configuration_profile_email.go index 99e6da8d..f34310a6 100644 --- a/internal/models/configuration_profile_email.go +++ b/internal/models/configuration_profile_email.go @@ -9,7 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -23,7 +23,7 @@ type ConfigurationProfileEmailDataSource struct { SMTP types.Object `tfsdk:"smtp"` } -func (m *ConfigurationProfileEmailDataSource) Update(ctx context.Context, cp api.ConfigurationProfile) diag.Diagnostics { +func (m *ConfigurationProfileEmailDataSource) Update(ctx context.Context, cp platform.ConfigurationProfile) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(cp.ID) @@ -56,7 +56,7 @@ type ConfigurationProfileEmailResource struct { ConfigurationProfileEmailDataSource } -func (m *ConfigurationProfileEmailResource) Update(ctx context.Context, cp api.ConfigurationProfile) diag.Diagnostics { +func (m *ConfigurationProfileEmailResource) Update(ctx context.Context, cp platform.ConfigurationProfile) diag.Diagnostics { var diags diag.Diagnostics var origSMTPAttrs map[string]attr.Value diff --git a/internal/models/configuration_profile_jira.go b/internal/models/configuration_profile_jira.go index 31d1e5f7..37c62db5 100644 --- a/internal/models/configuration_profile_jira.go +++ b/internal/models/configuration_profile_jira.go @@ -7,7 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -39,7 +39,7 @@ type ConfigurationProfileJiraDataSource struct { APIKey types.String `tfsdk:"api_key"` } -func (m *ConfigurationProfileJiraDataSource) Update(cp api.ConfigurationProfile) diag.Diagnostics { +func (m *ConfigurationProfileJiraDataSource) Update(cp platform.ConfigurationProfile) diag.Diagnostics { var diags diag.Diagnostics jiraConfig := cp.Record.JiraConfiguration @@ -52,7 +52,7 @@ func (m *ConfigurationProfileJiraDataSource) Update(cp api.ConfigurationProfile) projects, d := typehelpers.ObjectList[JiraProject]( jiraConfig.Projects, - func(entry api.JiraProject) (map[string]attr.Value, diag.Diagnostics) { + func(entry platform.JiraProject) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "closed_status": types.StringValue(entry.ClosedStatus), "issue_type": types.StringValue(entry.IssueType), @@ -75,7 +75,7 @@ type ConfigurationProfileJiraResource struct { APIKeyWOVersion types.String `tfsdk:"api_key_wo_version"` } -func (m *ConfigurationProfileJiraResource) Update(cp api.ConfigurationProfile) diag.Diagnostics { +func (m *ConfigurationProfileJiraResource) Update(cp platform.ConfigurationProfile) diag.Diagnostics { var diags diag.Diagnostics // fetch current project names to preserve declared order diff --git a/internal/models/configuration_profile_msteams.go b/internal/models/configuration_profile_msteams.go index 30a17548..38c4ef2b 100644 --- a/internal/models/configuration_profile_msteams.go +++ b/internal/models/configuration_profile_msteams.go @@ -7,7 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -41,7 +41,7 @@ func (c ConfigurationProfileMSTeamsDataSource) AttributeTypes() map[string]attr. } } -func (m *ConfigurationProfileMSTeamsDataSource) Update(cp api.ConfigurationProfile) diag.Diagnostics { +func (m *ConfigurationProfileMSTeamsDataSource) Update(cp platform.ConfigurationProfile) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(cp.ID) @@ -49,7 +49,7 @@ func (m *ConfigurationProfileMSTeamsDataSource) Update(cp api.ConfigurationProfi channelMappings, d := typehelpers.ObjectList[MSTeamsChannelMapping]( cp.Record.MSTeamsConfiguration.ChannelMappings, - func(entry api.MSTeamsChannelMapping) (map[string]attr.Value, diag.Diagnostics) { + func(entry platform.MSTeamsChannelMapping) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "name": types.StringValue(entry.Name), "team_id": types.StringValue(string(entry.TeamID)), @@ -75,7 +75,7 @@ func (m *ConfigurationProfileMSTeamsDataSource) Update(cp api.ConfigurationProfi return diags } -func (m ConfigurationProfileMSTeamsDataSource) buildAccessConfig(cp api.ConfigurationProfile) (types.Object, diag.Diagnostics) { +func (m ConfigurationProfileMSTeamsDataSource) buildAccessConfig(cp platform.ConfigurationProfile) (types.Object, diag.Diagnostics) { var diags diag.Diagnostics nullObj := types.ObjectNull(MSTeamsAccessConfig{}.AttributeTypes()) @@ -127,7 +127,7 @@ func (m ConfigurationProfileMSTeamsDataSource) buildAccessConfig(cp api.Configur ) } -func (m ConfigurationProfileMSTeamsDataSource) buildCustomerConfig(cp api.ConfigurationProfile) (types.Object, diag.Diagnostics) { +func (m ConfigurationProfileMSTeamsDataSource) buildCustomerConfig(cp platform.ConfigurationProfile) (types.Object, diag.Diagnostics) { var diags diag.Diagnostics nullObj := types.ObjectNull(MSTeamsCustomerConfig{}.AttributeTypes()) @@ -171,12 +171,12 @@ func (m ConfigurationProfileMSTeamsDataSource) buildCustomerConfig(cp api.Config ) } -func (m ConfigurationProfileMSTeamsDataSource) buildEntityDetails(cp api.ConfigurationProfile) (types.Object, diag.Diagnostics) { +func (m ConfigurationProfileMSTeamsDataSource) buildEntityDetails(cp platform.ConfigurationProfile) (types.Object, diag.Diagnostics) { nullObj := types.ObjectNull(MSTeamsEntityDetails{}.AttributeTypes()) channels, diags := typehelpers.ObjectList[MSTeamsChannelDetails]( cp.Record.MSTeamsConfiguration.EntityDetails.Channels, - func(entry api.MSTeamsChannelDetail) (map[string]attr.Value, diag.Diagnostics) { + func(entry platform.MSTeamsChannelDetail) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "id": types.StringValue(entry.ID), "name": types.StringValue(entry.Name), @@ -189,7 +189,7 @@ func (m ConfigurationProfileMSTeamsDataSource) buildEntityDetails(cp api.Configu teams, teamsDiags := typehelpers.ObjectList[MSTeamsTeamDetails]( cp.Record.MSTeamsConfiguration.EntityDetails.Teams, - func(entry api.MSTeamsTeamDetail) (map[string]attr.Value, diag.Diagnostics) { + func(entry platform.MSTeamsTeamDetail) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "id": types.StringValue(entry.ID), "name": types.StringValue(entry.Name), @@ -229,7 +229,7 @@ func (r ConfigurationProfileMSTeamsResource) AttributeTypes() map[string]attr.Ty return attrTypes } -func (m *ConfigurationProfileMSTeamsResource) Update(cp api.ConfigurationProfile) diag.Diagnostics { +func (m *ConfigurationProfileMSTeamsResource) Update(cp platform.ConfigurationProfile) diag.Diagnostics { diags := m.ConfigurationProfileMSTeamsDataSource.Update(cp) // update state for input fields to match what's returned by the API. diff --git a/internal/models/configuration_profile_resource_owner.go b/internal/models/configuration_profile_resource_owner.go index 2987ff5b..174a914a 100644 --- a/internal/models/configuration_profile_resource_owner.go +++ b/internal/models/configuration_profile_resource_owner.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -20,7 +20,7 @@ type ConfigurationProfileResourceOwnerDataSource struct { Tags types.List `tfsdk:"tags"` } -func (m *ConfigurationProfileResourceOwnerDataSource) Update(cp api.ConfigurationProfile) diag.Diagnostics { +func (m *ConfigurationProfileResourceOwnerDataSource) Update(cp platform.ConfigurationProfile) diag.Diagnostics { var diags diag.Diagnostics config := cp.Record.ResourceOwnerConfiguration diff --git a/internal/models/configuration_profile_servicenow.go b/internal/models/configuration_profile_servicenow.go index a925caf2..1dc9423a 100644 --- a/internal/models/configuration_profile_servicenow.go +++ b/internal/models/configuration_profile_servicenow.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -21,7 +21,7 @@ type ConfigurationProfileServiceNowDataSource struct { ClosedState types.String `tfsdk:"closed_state"` } -func (m *ConfigurationProfileServiceNowDataSource) Update(cp api.ConfigurationProfile) diag.Diagnostics { +func (m *ConfigurationProfileServiceNowDataSource) Update(cp platform.ConfigurationProfile) diag.Diagnostics { var diags diag.Diagnostics config := cp.Record.ServiceNowConfiguration diff --git a/internal/models/configuration_profile_slack.go b/internal/models/configuration_profile_slack.go index 9277613c..e2c50598 100644 --- a/internal/models/configuration_profile_slack.go +++ b/internal/models/configuration_profile_slack.go @@ -9,7 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -23,7 +23,7 @@ type ConfigurationProfileSlackDataSource struct { Webhooks types.List `tfsdk:"webhook"` } -func (m *ConfigurationProfileSlackDataSource) Update(cp api.ConfigurationProfile) diag.Diagnostics { +func (m *ConfigurationProfileSlackDataSource) Update(cp platform.ConfigurationProfile) diag.Diagnostics { var diags diag.Diagnostics slackConfig := cp.Record.SlackConfiguration @@ -35,7 +35,7 @@ func (m *ConfigurationProfileSlackDataSource) Update(cp api.ConfigurationProfile webhooks, d := typehelpers.ObjectList[SlackWebhook]( cp.Record.SlackConfiguration.Webhooks, - func(entry api.SlackWebhook) (map[string]attr.Value, diag.Diagnostics) { + func(entry platform.SlackWebhook) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "name": types.StringValue(entry.Name), "url": types.StringValue(entry.URL), @@ -56,7 +56,7 @@ type ConfigurationProfileSlackResource struct { TokenWOVersion types.String `tfsdk:"token_wo_version"` } -func (m *ConfigurationProfileSlackResource) Update(ctx context.Context, cp api.ConfigurationProfile, webhookVersions map[string]string) diag.Diagnostics { +func (m *ConfigurationProfileSlackResource) Update(ctx context.Context, cp platform.ConfigurationProfile, webhookVersions map[string]string) diag.Diagnostics { var diags diag.Diagnostics // fetch current webhook names to preserve declared order diff --git a/internal/models/configuration_profile_symphony.go b/internal/models/configuration_profile_symphony.go index bbd0a64d..4e09613f 100644 --- a/internal/models/configuration_profile_symphony.go +++ b/internal/models/configuration_profile_symphony.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -19,7 +19,7 @@ type ConfigurationProfileSymphonyDataSource struct { PrivateKey types.String `tfsdk:"private_key"` } -func (m *ConfigurationProfileSymphonyDataSource) Update(cp api.ConfigurationProfile) diag.Diagnostics { +func (m *ConfigurationProfileSymphonyDataSource) Update(cp platform.ConfigurationProfile) diag.Diagnostics { var diags diag.Diagnostics config := cp.Record.SymphonyConfiguration diff --git a/internal/models/datadog_integration.go b/internal/models/datadog_integration.go index 14a275fa..1f844324 100644 --- a/internal/models/datadog_integration.go +++ b/internal/models/datadog_integration.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" ) @@ -25,7 +25,7 @@ type DatadogIntegrationDataSource struct { Status types.Object `tfsdk:"status"` } -func (m *DatadogIntegrationDataSource) Update(integration *api.DatadogIntegration) diag.Diagnostics { +func (m *DatadogIntegrationDataSource) Update(integration *platform.DatadogIntegration) diag.Diagnostics { var diags diag.Diagnostics m.ID = types.StringValue(DatadogIntegrationID) diff --git a/internal/models/gcp_integration.go b/internal/models/gcp_integration.go index 8087e8a0..6a16888c 100644 --- a/internal/models/gcp_integration.go +++ b/internal/models/gcp_integration.go @@ -7,7 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -20,7 +20,7 @@ type GCPIntegrationDataSource struct { AccessConfig types.Object `tfsdk:"access_config"` } -func (m *GCPIntegrationDataSource) Update(integration *api.GCPIntegration) diag.Diagnostics { +func (m *GCPIntegrationDataSource) Update(integration *platform.GCPIntegration) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(integration.ID) @@ -37,7 +37,7 @@ func (m *GCPIntegrationDataSource) Update(integration *api.GCPIntegration) diag. return diags } -func (m GCPIntegrationDataSource) buildCustomerConfig(config api.GCPIntegrationCustomerConfig) (types.Object, diag.Diagnostics) { +func (m GCPIntegrationDataSource) buildCustomerConfig(config platform.GCPIntegrationCustomerConfig) (types.Object, diag.Diagnostics) { var diags diag.Diagnostics nullObj := types.ObjectNull(GCPIntegrationCustomerConfigModel{}.AttributeTypes()) @@ -49,7 +49,7 @@ func (m GCPIntegrationDataSource) buildCustomerConfig(config api.GCPIntegrationC organizations, d := typehelpers.ObjectList[GCPIntegrationCustomerOrgModel]( config.Organizations, - func(org api.GCPIntegrationCustomerOrganization) (map[string]attr.Value, diag.Diagnostics) { + func(org platform.GCPIntegrationCustomerOrganization) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "org_id": types.StringValue(org.OrgID), "folder_ids": typehelpers.StringsList(org.FolderIDs), @@ -64,7 +64,7 @@ func (m GCPIntegrationDataSource) buildCustomerConfig(config api.GCPIntegrationC costSources, d := typehelpers.ObjectList[GCPIntegrationCustomerCostSourceModel]( config.CostSources, - func(cs api.GCPIntegrationCustomerCostSource) (map[string]attr.Value, diag.Diagnostics) { + func(cs platform.GCPIntegrationCustomerCostSource) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "billing_table": types.StringValue(cs.BillingTable), }, nil @@ -77,7 +77,7 @@ func (m GCPIntegrationDataSource) buildCustomerConfig(config api.GCPIntegrationC securityContexts, d := typehelpers.ObjectList[GCPIntegrationCustomerSecurityContextModel]( config.SecurityContexts, - func(sc api.GCPIntegrationCustomerSecurityContext) (map[string]attr.Value, diag.Diagnostics) { + func(sc platform.GCPIntegrationCustomerSecurityContext) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "name": types.StringValue(sc.Name), "extra_roles": typehelpers.StringsList(sc.ExtraRoles), @@ -107,7 +107,7 @@ func (m GCPIntegrationDataSource) buildCustomerConfig(config api.GCPIntegrationC ) } -func (m GCPIntegrationDataSource) buildCustomerInfra(infra *api.GCPIntegrationCustomerInfrastructure) (types.Object, diag.Diagnostics) { +func (m GCPIntegrationDataSource) buildCustomerInfra(infra *platform.GCPIntegrationCustomerInfrastructure) (types.Object, diag.Diagnostics) { var diags diag.Diagnostics nullObj := types.ObjectNull(GCPIntegrationCustomerInfraModel{}.AttributeTypes()) @@ -132,7 +132,7 @@ func (m GCPIntegrationDataSource) buildCustomerInfra(infra *api.GCPIntegrationCu ) } -func (m GCPIntegrationDataSource) buildCustomerCreateProject(cp *api.GCPIntegrationCustomerCreateProject) (types.Object, diag.Diagnostics) { +func (m GCPIntegrationDataSource) buildCustomerCreateProject(cp *platform.GCPIntegrationCustomerCreateProject) (types.Object, diag.Diagnostics) { var diags diag.Diagnostics nullObj := types.ObjectNull(GCPIntegrationCustomerCreateProjectModel{}.AttributeTypes()) @@ -157,7 +157,7 @@ func (m GCPIntegrationDataSource) buildCustomerCreateProject(cp *api.GCPIntegrat ) } -func (m GCPIntegrationDataSource) buildTerraformModule(tm *api.TerraformModule) (types.Object, diag.Diagnostics) { +func (m GCPIntegrationDataSource) buildTerraformModule(tm *platform.TerraformModule) (types.Object, diag.Diagnostics) { var diags diag.Diagnostics nullObj := types.ObjectNull(TerraformModule{}.AttributeTypes()) @@ -176,7 +176,7 @@ func (m GCPIntegrationDataSource) buildTerraformModule(tm *api.TerraformModule) ) } -func (m GCPIntegrationDataSource) buildAccessConfig(config *api.GCPIntegrationAccessConfig) (types.Object, diag.Diagnostics) { +func (m GCPIntegrationDataSource) buildAccessConfig(config *platform.GCPIntegrationAccessConfig) (types.Object, diag.Diagnostics) { var diags diag.Diagnostics nullObj := types.ObjectNull(GCPIntegrationAccessConfigModel{}.AttributeTypes()) @@ -192,10 +192,10 @@ func (m GCPIntegrationDataSource) buildAccessConfig(config *api.GCPIntegrationAc organizations, d := typehelpers.ObjectList[GCPIntegrationAccessOrgModel]( config.Organizations, - func(org api.GCPIntegrationAccessOrganization) (map[string]attr.Value, diag.Diagnostics) { + func(org platform.GCPIntegrationAccessOrganization) (map[string]attr.Value, diag.Diagnostics) { folders, d := typehelpers.ObjectList[GCPIntegrationAccessOrgFolderModel]( org.Folders, - func(f api.GCPIntegrationAccessOrganizationFolder) (map[string]attr.Value, diag.Diagnostics) { + func(f platform.GCPIntegrationAccessOrganizationFolder) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "id": types.StringValue(f.ID), "name": types.StringValue(f.Name), @@ -208,7 +208,7 @@ func (m GCPIntegrationDataSource) buildAccessConfig(config *api.GCPIntegrationAc projects, d := typehelpers.ObjectList[GCPIntegrationAccessOrgProjectModel]( org.Projects, - func(p api.GCPIntegrationAccessOrganizationProject) (map[string]attr.Value, diag.Diagnostics) { + func(p platform.GCPIntegrationAccessOrganizationProject) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "id": types.StringValue(p.ID), "number": types.StringValue(p.Number), @@ -234,7 +234,7 @@ func (m GCPIntegrationDataSource) buildAccessConfig(config *api.GCPIntegrationAc costSources, d := typehelpers.ObjectList[GCPIntegrationAccessCostSourceModel]( config.CostSources, - func(cs api.GCPIntegrationAccessCostSource) (map[string]attr.Value, diag.Diagnostics) { + func(cs platform.GCPIntegrationAccessCostSource) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "billing_table": types.StringValue(cs.BillingTable), "location": types.StringValue(cs.Location), @@ -248,7 +248,7 @@ func (m GCPIntegrationDataSource) buildAccessConfig(config *api.GCPIntegrationAc securityContexts, d := typehelpers.ObjectList[GCPIntegrationAccessSecurityContextModel]( config.SecurityContexts, - func(sc api.GCPIntegrationAccessSecurityContext) (map[string]attr.Value, diag.Diagnostics) { + func(sc platform.GCPIntegrationAccessSecurityContext) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "name": types.StringValue(sc.Name), "extra_roles": typehelpers.StringsList(sc.ExtraRoles), @@ -273,7 +273,7 @@ func (m GCPIntegrationDataSource) buildAccessConfig(config *api.GCPIntegrationAc ) } -func (m GCPIntegrationDataSource) buildAccessInfra(infra api.GCPIntegrationAccessInfrastructure) (types.Object, diag.Diagnostics) { +func (m GCPIntegrationDataSource) buildAccessInfra(infra platform.GCPIntegrationAccessInfrastructure) (types.Object, diag.Diagnostics) { var diags diag.Diagnostics nullObj := types.ObjectNull(GCPIntegrationAccessInfraModel{}.AttributeTypes()) diff --git a/internal/models/gcp_integration_surface.go b/internal/models/gcp_integration_surface.go index f1813aea..9a7eed9a 100644 --- a/internal/models/gcp_integration_surface.go +++ b/internal/models/gcp_integration_surface.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" ) // GCPIntegrationSurfaceTrustAWS holds details for the AWS trust configuration for GCP integration. @@ -32,7 +32,7 @@ type GCPIntegrationSurfaceDataSource struct { AWSRelay *GCPIntegrationSurfaceAWSRelay `tfsdk:"aws_relay"` } -func (m *GCPIntegrationSurfaceDataSource) Update(_ context.Context, surface *api.GCPIntegrationSurface) diag.Diagnostics { +func (m *GCPIntegrationSurfaceDataSource) Update(_ context.Context, surface *platform.GCPIntegrationSurface) diag.Diagnostics { var diags diag.Diagnostics m.TrustAWS = &GCPIntegrationSurfaceTrustAWS{ diff --git a/internal/models/msteams_integration_surface.go b/internal/models/msteams_integration_surface.go index 2b615ee4..c5e6e598 100644 --- a/internal/models/msteams_integration_surface.go +++ b/internal/models/msteams_integration_surface.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" ) // MSTeamsIntegrationSurfaceDataSource is the model for the MS Teams integration surface data source. @@ -18,7 +18,7 @@ type MSTeamsIntegrationSurfaceDataSource struct { TrustRoleARN types.String `tfsdk:"trust_role_arn"` } -func (m *MSTeamsIntegrationSurfaceDataSource) Update(ctx context.Context, surface *api.MSTeamsIntegrationSurface) diag.Diagnostics { +func (m *MSTeamsIntegrationSurfaceDataSource) Update(ctx context.Context, surface *platform.MSTeamsIntegrationSurface) diag.Diagnostics { var diags diag.Diagnostics m.BotEndpoint = types.StringValue(surface.BotEndpoint) diff --git a/internal/models/notification_template.go b/internal/models/notification_template.go index 1c9b4630..727bda04 100644 --- a/internal/models/notification_template.go +++ b/internal/models/notification_template.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -19,7 +19,7 @@ type NotificationTemplateResource struct { Content types.String `tfsdk:"content"` } -func (m *NotificationTemplateResource) Update(template *api.Template) diag.Diagnostics { +func (m *NotificationTemplateResource) Update(template *platform.Template) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(template.ID) diff --git a/internal/models/platform.go b/internal/models/platform.go index 2258eee6..38298503 100644 --- a/internal/models/platform.go +++ b/internal/models/platform.go @@ -9,7 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -23,7 +23,7 @@ type PlatformDataSource struct { AWSOrgReadCustomerConfig types.Object `tfsdk:"aws_org_read_customer_config"` } -func (m *PlatformDataSource) Update(ctx context.Context, platform *api.Platform) diag.Diagnostics { +func (m *PlatformDataSource) Update(ctx context.Context, platform *platform.Platform) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(platform.ID) @@ -41,7 +41,7 @@ func (m *PlatformDataSource) Update(ctx context.Context, platform *api.Platform) return diags } -func (m PlatformDataSource) getCustomerConfig(ctx context.Context, config api.PlatformCustomerConfig) (types.Object, diag.Diagnostics) { +func (m PlatformDataSource) getCustomerConfig(ctx context.Context, config platform.PlatformCustomerConfig) (types.Object, diag.Diagnostics) { terraformModule, diags := typehelpers.ObjectValue( ctx, &config.TerraformModule, diff --git a/internal/models/policy.go b/internal/models/policy.go index 6f2dd36b..5b0a859e 100644 --- a/internal/models/policy.go +++ b/internal/models/policy.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -31,7 +31,7 @@ type PolicyDataSource struct { UnqualifiedName types.String `tfsdk:"unqualified_name"` } -func (m *PolicyDataSource) Update(ctx context.Context, policy *api.Policy) diag.Diagnostics { +func (m *PolicyDataSource) Update(ctx context.Context, policy *platform.Policy) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(policy.ID) diff --git a/internal/models/policy_collection.go b/internal/models/policy_collection.go index 4829310e..b2987676 100644 --- a/internal/models/policy_collection.go +++ b/internal/models/policy_collection.go @@ -9,7 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -28,7 +28,7 @@ type PolicyCollectionResource struct { RoleAssignmentTarget types.String `tfsdk:"role_assignment_target"` } -func (m *PolicyCollectionResource) Update(ctx context.Context, policyCollection *api.PolicyCollection) diag.Diagnostics { +func (m *PolicyCollectionResource) Update(ctx context.Context, policyCollection *platform.PolicyCollection) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(policyCollection.ID) diff --git a/internal/models/policy_collection_mapping.go b/internal/models/policy_collection_mapping.go index 8d1cbc17..2eb8aa07 100644 --- a/internal/models/policy_collection_mapping.go +++ b/internal/models/policy_collection_mapping.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -18,7 +18,7 @@ type PolicyCollectionMappingResource struct { PolicyVersion types.Int32 `tfsdk:"policy_version"` } -func (m *PolicyCollectionMappingResource) Update(policyCollectionMapping *api.PolicyCollectionMapping) diag.Diagnostics { +func (m *PolicyCollectionMappingResource) Update(policyCollectionMapping *platform.PolicyCollectionMapping) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(policyCollectionMapping.ID) diff --git a/internal/models/report_group.go b/internal/models/report_group.go index bfc4c845..2ea09281 100644 --- a/internal/models/report_group.go +++ b/internal/models/report_group.go @@ -7,7 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -30,7 +30,7 @@ type ReportGroupDataSource struct { Source types.String `tfsdk:"source"` } -func (m *ReportGroupDataSource) Update(rg api.ReportGroup) diag.Diagnostics { +func (m *ReportGroupDataSource) Update(rg platform.ReportGroup) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(rg.ID) @@ -44,10 +44,10 @@ func (m *ReportGroupDataSource) Update(rg api.ReportGroup) diag.Diagnostics { emailDeliverySettings, d := typehelpers.ObjectList[EmailDeliverySettings]( rg.EmailDeliverySettings(), - func(entry api.EmailDeliverySettings) (map[string]attr.Value, diag.Diagnostics) { + func(entry platform.EmailDeliverySettings) (map[string]attr.Value, diag.Diagnostics) { recipients, diags := typehelpers.ObjectList[Recipient]( entry.Recipients, - func(entry api.Recipient) (map[string]attr.Value, diag.Diagnostics) { + func(entry platform.Recipient) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "account_owner": types.BoolPointerValue(entry.AccountOwner), "event_owner": types.BoolPointerValue(entry.EventOwner), @@ -78,10 +78,10 @@ func (m *ReportGroupDataSource) Update(rg api.ReportGroup) diag.Diagnostics { slackDeliverySettings, d := typehelpers.ObjectList[SlackDeliverySettings]( rg.SlackDeliverySettings(), - func(entry api.SlackDeliverySettings) (map[string]attr.Value, diag.Diagnostics) { + func(entry platform.SlackDeliverySettings) (map[string]attr.Value, diag.Diagnostics) { recipients, diags := typehelpers.ObjectList[Recipient]( entry.Recipients, - func(entry api.Recipient) (map[string]attr.Value, diag.Diagnostics) { + func(entry platform.Recipient) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "account_owner": types.BoolPointerValue(entry.AccountOwner), "event_owner": types.BoolPointerValue(entry.EventOwner), @@ -107,10 +107,10 @@ func (m *ReportGroupDataSource) Update(rg api.ReportGroup) diag.Diagnostics { msteamsDeliverySettings, d := typehelpers.ObjectList[MSTeamsDeliverySettings]( rg.MSTeamsDeliverySettings(), - func(entry api.MSTeamsDeliverySettings) (map[string]attr.Value, diag.Diagnostics) { + func(entry platform.MSTeamsDeliverySettings) (map[string]attr.Value, diag.Diagnostics) { recipients, diags := typehelpers.ObjectList[Recipient]( entry.Recipients, - func(entry api.Recipient) (map[string]attr.Value, diag.Diagnostics) { + func(entry platform.Recipient) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "account_owner": types.BoolPointerValue(entry.AccountOwner), "event_owner": types.BoolPointerValue(entry.EventOwner), @@ -136,10 +136,10 @@ func (m *ReportGroupDataSource) Update(rg api.ReportGroup) diag.Diagnostics { servicenowDeliverySettings, d := typehelpers.ObjectList[ServiceNowDeliverySettings]( rg.ServiceNowDeliverySettings(), - func(entry api.ServiceNowDeliverySettings) (map[string]attr.Value, diag.Diagnostics) { + func(entry platform.ServiceNowDeliverySettings) (map[string]attr.Value, diag.Diagnostics) { recipients, diags := typehelpers.ObjectList[Recipient]( entry.Recipients, - func(entry api.Recipient) (map[string]attr.Value, diag.Diagnostics) { + func(entry platform.Recipient) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "account_owner": types.BoolPointerValue(entry.AccountOwner), "event_owner": types.BoolPointerValue(entry.EventOwner), @@ -168,10 +168,10 @@ func (m *ReportGroupDataSource) Update(rg api.ReportGroup) diag.Diagnostics { jiraDeliverySettings, d := typehelpers.ObjectList[JiraDeliverySettings]( rg.JiraDeliverySettings(), - func(entry api.JiraDeliverySettings) (map[string]attr.Value, diag.Diagnostics) { + func(entry platform.JiraDeliverySettings) (map[string]attr.Value, diag.Diagnostics) { recipients, diags := typehelpers.ObjectList[Recipient]( entry.Recipients, - func(entry api.Recipient) (map[string]attr.Value, diag.Diagnostics) { + func(entry platform.Recipient) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "account_owner": types.BoolPointerValue(entry.AccountOwner), "event_owner": types.BoolPointerValue(entry.EventOwner), @@ -200,10 +200,10 @@ func (m *ReportGroupDataSource) Update(rg api.ReportGroup) diag.Diagnostics { symphonyDeliverySettings, d := typehelpers.ObjectList[SymphonyDeliverySettings]( rg.SymphonyDeliverySettings(), - func(entry api.SymphonyDeliverySettings) (map[string]attr.Value, diag.Diagnostics) { + func(entry platform.SymphonyDeliverySettings) (map[string]attr.Value, diag.Diagnostics) { recipients, diags := typehelpers.ObjectList[Recipient]( entry.Recipients, - func(entry api.Recipient) (map[string]attr.Value, diag.Diagnostics) { + func(entry platform.Recipient) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "account_owner": types.BoolPointerValue(entry.AccountOwner), "event_owner": types.BoolPointerValue(entry.EventOwner), diff --git a/internal/models/repository.go b/internal/models/repository.go index 86a5ae86..de78f1a3 100644 --- a/internal/models/repository.go +++ b/internal/models/repository.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -26,7 +26,7 @@ type RepositoryDataSource struct { RoleAssignmentTarget types.String `tfsdk:"role_assignment_target"` } -func (m *RepositoryDataSource) Update(repo *api.Repository) diag.Diagnostics { +func (m *RepositoryDataSource) Update(repo *platform.Repository) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(repo.ID) diff --git a/internal/models/role.go b/internal/models/role.go index a52457b0..3c2a2520 100644 --- a/internal/models/role.go +++ b/internal/models/role.go @@ -8,7 +8,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -21,7 +21,7 @@ type RoleDataSource struct { System types.Bool `tfsdk:"system"` } -func (m *RoleDataSource) Update(ctx context.Context, role *api.Role) diag.Diagnostics { +func (m *RoleDataSource) Update(ctx context.Context, role *platform.Role) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(role.ID) diff --git a/internal/models/role_assignment.go b/internal/models/role_assignment.go index 92db32e1..a732680e 100644 --- a/internal/models/role_assignment.go +++ b/internal/models/role_assignment.go @@ -9,7 +9,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -23,7 +23,7 @@ type RoleAssignmentResource struct { } // Update updates the model from an API role assignment. -func (m *RoleAssignmentResource) Update(ctx context.Context, assignment *api.RoleAssignment) diag.Diagnostics { +func (m *RoleAssignmentResource) Update(ctx context.Context, assignment *platform.RoleAssignment) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(assignment.ID) @@ -70,7 +70,7 @@ func (i RoleAssignmentItem) AttributeTypes() map[string]attr.Type { } // Update updates the data source model from API role assignments. -func (m *RoleAssignmentsDataSource) Update(ctx context.Context, assignments []api.RoleAssignment) diag.Diagnostics { +func (m *RoleAssignmentsDataSource) Update(ctx context.Context, assignments []platform.RoleAssignment) diag.Diagnostics { var diags diag.Diagnostics // Convert each assignment to a list item diff --git a/internal/models/saml_provider.go b/internal/models/saml_provider.go index b89c14f4..f8829187 100644 --- a/internal/models/saml_provider.go +++ b/internal/models/saml_provider.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -21,7 +21,7 @@ type SAMLProviderDataSource struct { IDPAlias types.String `tfsdk:"idp_alias"` } -func (m *SAMLProviderDataSource) Update(samlProvider *api.SAMLProvider) diag.Diagnostics { +func (m *SAMLProviderDataSource) Update(samlProvider *platform.SAMLProvider) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(samlProvider.ID) diff --git a/internal/models/sso_group.go b/internal/models/sso_group.go index 8f40618c..428ea251 100644 --- a/internal/models/sso_group.go +++ b/internal/models/sso_group.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -18,7 +18,7 @@ type SSOGroupDataSource struct { RoleAssignmentPrincipal types.String `tfsdk:"role_assignment_principal"` } -func (m *SSOGroupDataSource) Update(ssoGroup *api.SSOGroup) diag.Diagnostics { +func (m *SSOGroupDataSource) Update(ssoGroup *platform.SSOGroup) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(ssoGroup.ID) diff --git a/internal/models/status.go b/internal/models/status.go index 1d703d03..6352ca43 100644 --- a/internal/models/status.go +++ b/internal/models/status.go @@ -9,7 +9,7 @@ import ( resSchema "github.com/hashicorp/terraform-plugin-framework/resource/schema" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -62,12 +62,12 @@ func (s StatusDetail) AttributeTypes() map[string]attr.Type { } // NewStatusInfo returns the object value for a status returned by the API. -func NewStatusInfo(info api.StatusInfo) (types.Object, diag.Diagnostics) { +func NewStatusInfo(info platform.StatusInfo) (types.Object, diag.Diagnostics) { var diags diag.Diagnostics details, d := typehelpers.ObjectList[StatusDetail]( info.Details, - func(detail api.StatusDetail) (map[string]attr.Value, diag.Diagnostics) { + func(detail platform.StatusDetail) (map[string]attr.Value, diag.Diagnostics) { return map[string]attr.Value{ "component": types.StringValue(detail.Component), "status": types.StringPointerValue(detail.Status), diff --git a/internal/models/status_test.go b/internal/models/status_test.go index 16694fee..78925e54 100644 --- a/internal/models/status_test.go +++ b/internal/models/status_test.go @@ -10,13 +10,13 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" ) func TestNewStatusInfo(t *testing.T) { - info, diags := NewStatusInfo(api.StatusInfo{ + info, diags := NewStatusInfo(platform.StatusInfo{ Status: "PARTIAL_SUCCESS", - Details: []api.StatusDetail{ + Details: []platform.StatusDetail{ { Component: "us-east-1-secret", Status: strPtr("SUCCESS"), @@ -79,7 +79,7 @@ func TestNewStatusInfo(t *testing.T) { func TestNewStatusInfo_NoDetails(t *testing.T) { // Nothing has reported yet, which is a known-empty list rather than an // unknown one, so the attribute is readable straight after an apply. - info, diags := NewStatusInfo(api.StatusInfo{Status: "SKIPPED", Details: []api.StatusDetail{}}) + info, diags := NewStatusInfo(platform.StatusInfo{Status: "SKIPPED", Details: []platform.StatusDetail{}}) require.False(t, diags.HasError(), "unexpected diagnostics: %v", diags) details, ok := info.Attributes()["details"].(types.List) diff --git a/internal/models/user.go b/internal/models/user.go index 1f3282ab..f53cca20 100644 --- a/internal/models/user.go +++ b/internal/models/user.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -23,7 +23,7 @@ type UserDataSource struct { Username types.String `tfsdk:"username"` } -func (m *UserDataSource) Update(user *api.User) diag.Diagnostics { +func (m *UserDataSource) Update(user *platform.User) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(user.ID) diff --git a/internal/models/user_group.go b/internal/models/user_group.go index 820cac0f..d829daab 100644 --- a/internal/models/user_group.go +++ b/internal/models/user_group.go @@ -6,7 +6,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/diag" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/typehelpers" ) @@ -20,7 +20,7 @@ type UserGroupDataSource struct { RoleAssignmentTarget types.String `tfsdk:"role_assignment_target"` } -func (m *UserGroupDataSource) Update(userGroup *api.UserGroup) diag.Diagnostics { +func (m *UserGroupDataSource) Update(userGroup *platform.UserGroup) diag.Diagnostics { var diags diag.Diagnostics m.ID = typehelpers.GraphQLIDValue(userGroup.ID) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 45e0d091..a83a28f0 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -17,7 +17,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/datasources" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/providerdata" @@ -114,7 +114,7 @@ func (p *stackletProvider) Configure(ctx context.Context, req provider.Configure // Make provider data accessible to the Configure method of resources and data sources providerData := providerdata.New( - api.ClientConfig{ + platform.ClientConfig{ Endpoint: creds.Endpoint, APIKey: creds.APIKey, Version: p.version, diff --git a/internal/providerdata/providerdata.go b/internal/providerdata/providerdata.go index 96bcd368..f5f1ab98 100644 --- a/internal/providerdata/providerdata.go +++ b/internal/providerdata/providerdata.go @@ -8,18 +8,18 @@ import ( "github.com/hashicorp/terraform-plugin-framework/datasource" "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" ) // providerData holds shared data for available in requests. type providerData struct { - API *api.API + API *platform.API } // New returns configured provider data. -func New(config api.ClientConfig) *providerData { +func New(config platform.ClientConfig) *providerData { return &providerData{ - API: api.New(config), + API: platform.New(config), } } diff --git a/internal/resources/account.go b/internal/resources/account.go index 7485d303..8b821529 100644 --- a/internal/resources/account.go +++ b/internal/resources/account.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" "github.com/stacklet/terraform-provider-stacklet/internal/schemavalidate" @@ -112,10 +112,10 @@ func (r *accountResource) Create(ctx context.Context, req resource.CreateRequest return } - input := api.AccountCreateInput{ + input := platform.AccountCreateInput{ Name: plan.Name.ValueString(), Key: plan.Key.ValueString(), - Provider: api.CloudProvider(plan.CloudProvider.ValueString()), + Provider: platform.CloudProvider(plan.CloudProvider.ValueString()), ShortName: plan.ShortName.ValueStringPointer(), Description: plan.Description.ValueStringPointer(), Email: plan.Email.ValueStringPointer(), @@ -163,9 +163,9 @@ func (r *accountResource) Update(ctx context.Context, req resource.UpdateRequest securityContext = config.SecurityContextWO.ValueStringPointer() } - input := api.AccountUpdateInput{ + input := platform.AccountUpdateInput{ Key: plan.Key.ValueString(), - Provider: api.CloudProvider(plan.CloudProvider.ValueString()), + Provider: platform.CloudProvider(plan.CloudProvider.ValueString()), Name: plan.Name.ValueStringPointer(), ShortName: plan.ShortName.ValueStringPointer(), Description: plan.Description.ValueStringPointer(), diff --git a/internal/resources/account_discovery_aws.go b/internal/resources/account_discovery_aws.go index 70091e0a..8e2b5309 100644 --- a/internal/resources/account_discovery_aws.go +++ b/internal/resources/account_discovery_aws.go @@ -12,7 +12,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" ) @@ -96,7 +96,7 @@ func (r *accountDiscoveryAWSResource) Create(ctx context.Context, req resource.C return } - input := api.AccountDiscoveryAWSInput{ + input := platform.AccountDiscoveryAWSInput{ Name: plan.Name.ValueString(), Description: plan.Description.ValueStringPointer(), CustodianRole: plan.CustodianRole.ValueString(), @@ -143,7 +143,7 @@ func (r *accountDiscoveryAWSResource) Update(ctx context.Context, req resource.U return } - input := api.AccountDiscoveryAWSInput{ + input := platform.AccountDiscoveryAWSInput{ Name: plan.Name.ValueString(), Description: plan.Description.ValueStringPointer(), CustodianRole: plan.CustodianRole.ValueString(), diff --git a/internal/resources/account_discovery_azure.go b/internal/resources/account_discovery_azure.go index 0fcb9cb2..54308d95 100644 --- a/internal/resources/account_discovery_azure.go +++ b/internal/resources/account_discovery_azure.go @@ -12,7 +12,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" ) @@ -91,7 +91,7 @@ func (r *accountDiscoveryAzureResource) Create(ctx context.Context, req resource return } - input := api.AccountDiscoveryAzureInput{ + input := platform.AccountDiscoveryAzureInput{ Name: plan.Name.ValueString(), Description: plan.Description.ValueStringPointer(), ClientID: plan.ClientID.ValueStringPointer(), @@ -146,7 +146,7 @@ func (r *accountDiscoveryAzureResource) Update(ctx context.Context, req resource clientID = plan.ClientID.ValueStringPointer() clientSecret = config.ClientSecret.ValueStringPointer() } - input := api.AccountDiscoveryAzureInput{ + input := platform.AccountDiscoveryAzureInput{ Name: plan.Name.ValueString(), Description: plan.Description.ValueStringPointer(), ClientID: clientID, diff --git a/internal/resources/account_discovery_gcp.go b/internal/resources/account_discovery_gcp.go index 6a98f324..f7b3d049 100644 --- a/internal/resources/account_discovery_gcp.go +++ b/internal/resources/account_discovery_gcp.go @@ -13,7 +13,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" ) @@ -118,12 +118,12 @@ func (r *accountDiscoveryGCPResource) Create(ctx context.Context, req resource.C return } - input := api.AccountDiscoveryGCPInput{ + input := platform.AccountDiscoveryGCPInput{ Name: plan.Name.ValueString(), Description: plan.Description.ValueStringPointer(), OrgID: plan.OrgID.ValueString(), - RootFolderIDs: api.StringsList(plan.RootFolderIDs), - ExcludeFolderIDs: api.StringsList(plan.ExcludeFolderIDs), + RootFolderIDs: platform.StringsList(plan.RootFolderIDs), + ExcludeFolderIDs: platform.StringsList(plan.ExcludeFolderIDs), CredentialJSON: config.CredentialJSON.ValueStringPointer(), } accountDiscovery, err := r.api.AccountDiscovery.UpsertGCP(ctx, input) @@ -172,12 +172,12 @@ func (r *accountDiscoveryGCPResource) Update(ctx context.Context, req resource.U if state.CredentialJSONVersion != plan.CredentialJSONVersion { credentialJSON = config.CredentialJSON.ValueStringPointer() } - input := api.AccountDiscoveryGCPInput{ + input := platform.AccountDiscoveryGCPInput{ Name: plan.Name.ValueString(), Description: plan.Description.ValueStringPointer(), OrgID: plan.OrgID.ValueString(), - RootFolderIDs: api.StringsList(plan.RootFolderIDs), - ExcludeFolderIDs: api.StringsList(plan.ExcludeFolderIDs), + RootFolderIDs: platform.StringsList(plan.RootFolderIDs), + ExcludeFolderIDs: platform.StringsList(plan.ExcludeFolderIDs), CredentialJSON: credentialJSON, // this might be nil, in which case it's not updated } accountDiscovery, err := r.api.AccountDiscovery.UpsertGCP(ctx, input) diff --git a/internal/resources/account_group.go b/internal/resources/account_group.go index 731f60bd..6202bab8 100644 --- a/internal/resources/account_group.go +++ b/internal/resources/account_group.go @@ -12,7 +12,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" "github.com/stacklet/terraform-provider-stacklet/internal/planmodifiers" @@ -99,12 +99,12 @@ func (r *accountGroupResource) Create(ctx context.Context, req resource.CreateRe return } - input := api.AccountGroupCreateInput{ + input := platform.AccountGroupCreateInput{ Name: plan.Name.ValueString(), Provider: plan.CloudProvider.ValueString(), Description: plan.Description.ValueStringPointer(), DynamicFilter: plan.DynamicFilter.ValueStringPointer(), - Regions: api.StringsList(plan.Regions), + Regions: platform.StringsList(plan.Regions), } account_group, err := r.api.AccountGroup.Create(ctx, input) @@ -141,12 +141,12 @@ func (r *accountGroupResource) Update(ctx context.Context, req resource.UpdateRe return } - input := api.AccountGroupUpdateInput{ + input := platform.AccountGroupUpdateInput{ UUID: plan.UUID.ValueString(), Name: plan.Name.ValueStringPointer(), Description: plan.Description.ValueStringPointer(), DynamicFilter: plan.DynamicFilter.ValueStringPointer(), - Regions: api.StringsList(plan.Regions), + Regions: platform.StringsList(plan.Regions), } account_group, err := r.api.AccountGroup.Update(ctx, input) diff --git a/internal/resources/anthropic_integration.go b/internal/resources/anthropic_integration.go index f8b24642..49a894ac 100644 --- a/internal/resources/anthropic_integration.go +++ b/internal/resources/anthropic_integration.go @@ -11,6 +11,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" ) @@ -83,7 +84,7 @@ func (r *anthropicIntegrationResource) Create(ctx context.Context, req resource. return } - input := api.AnthropicIntegrationInput{ + input := platform.AnthropicIntegrationInput{ OrgID: plan.OrgID.ValueString(), AdminKey: config.AdminKeyWO.ValueStringPointer(), } @@ -125,7 +126,7 @@ func (r *anthropicIntegrationResource) Update(ctx context.Context, req resource. // The organization can't change in place, so the only update is a new key, // sent when its version says there is one. - input := api.AnthropicIntegrationInput{ + input := platform.AnthropicIntegrationInput{ OrgID: plan.OrgID.ValueString(), AdminKey: credentialToSend(&resp.Diagnostics, !state.AdminKeyWOVersion.Equal(plan.AdminKeyWOVersion), "admin_key_wo", config.AdminKeyWO), } diff --git a/internal/resources/binding.go b/internal/resources/binding.go index f558239f..c9d59260 100644 --- a/internal/resources/binding.go +++ b/internal/resources/binding.go @@ -15,7 +15,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" "github.com/stacklet/terraform-provider-stacklet/internal/schemavalidate" @@ -187,7 +187,7 @@ func (r *bindingResource) Create(ctx context.Context, req resource.CreateRequest return } - input := api.BindingCreateInput{ + input := platform.BindingCreateInput{ Name: plan.Name.ValueString(), Description: plan.Description.ValueStringPointer(), AutoDeploy: plan.AutoDeploy.ValueBool(), @@ -249,7 +249,7 @@ func (r *bindingResource) Update(ctx context.Context, req resource.UpdateRequest if resp.Diagnostics.HasError() { return } - input := api.BindingUpdateInput{ + input := platform.BindingUpdateInput{ UUID: plan.UUID.ValueString(), Name: plan.Name.ValueString(), Description: plan.Description.ValueStringPointer(), @@ -285,31 +285,31 @@ func (r *bindingResource) ImportState(ctx context.Context, req resource.ImportSt importState(ctx, req, resp, []string{"uuid"}) } -func (r bindingResource) getExecutionConfig(ctx context.Context, plan models.BindingResource, securityContextString *string) (api.BindingExecutionConfig, diag.Diagnostics) { - var dryRun *api.BindingExecutionConfigDryRun +func (r bindingResource) getExecutionConfig(ctx context.Context, plan models.BindingResource, securityContextString *string) (platform.BindingExecutionConfig, diag.Diagnostics) { + var dryRun *platform.BindingExecutionConfigDryRun if !plan.DryRun.IsNull() { - dryRun = &api.BindingExecutionConfigDryRun{Default: plan.DryRun.ValueBool()} + dryRun = &platform.BindingExecutionConfigDryRun{Default: plan.DryRun.ValueBool()} } - var securityContext *api.BindingExecutionConfigSecurityContext + var securityContext *platform.BindingExecutionConfigSecurityContext if securityContextString != nil { - securityContext = &api.BindingExecutionConfigSecurityContext{Default: *securityContextString} + securityContext = &platform.BindingExecutionConfigSecurityContext{Default: *securityContextString} } - var defaultResourceLimits *api.BindingExecutionConfigResourceLimit + var defaultResourceLimits *platform.BindingExecutionConfigResourceLimit if !plan.ResourceLimits.IsNull() { var defLimitsObj models.BindingExecutionConfigResourceLimit if diags := plan.ResourceLimits.As(ctx, &defLimitsObj, objectAsOptions); diags.HasError() { - return api.BindingExecutionConfig{}, diags + return platform.BindingExecutionConfig{}, diags } - defaultResourceLimits = &api.BindingExecutionConfigResourceLimit{ + defaultResourceLimits = &platform.BindingExecutionConfigResourceLimit{ MaxCount: defLimitsObj.MaxCount.ValueInt32Pointer(), MaxPercentage: defLimitsObj.MaxPercentage.ValueFloat32Pointer(), RequiresBoth: defLimitsObj.RequiresBoth.ValueBool(), } } - policyResourceLimits := make([]api.BindingExecutionConfigResourceLimitsPolicyOverrides, 0) + policyResourceLimits := make([]platform.BindingExecutionConfigResourceLimitsPolicyOverrides, 0) if !plan.PolicyResourceLimits.IsNull() { for i, elem := range plan.PolicyResourceLimits.Elements() { resourceLimit, ok := elem.(types.Object) @@ -320,18 +320,18 @@ func (r bindingResource) getExecutionConfig(ctx context.Context, plan models.Bin "Invalid limits", "Limits block is invalid,", ) - return api.BindingExecutionConfig{}, diags + return platform.BindingExecutionConfig{}, diags } var limitsObj models.BindingExecutionConfigPolicyResourceLimit if diags := resourceLimit.As(ctx, &limitsObj, objectAsOptions); diags.HasError() { - return api.BindingExecutionConfig{}, diags + return platform.BindingExecutionConfig{}, diags } policyResourceLimits = append( policyResourceLimits, - api.BindingExecutionConfigResourceLimitsPolicyOverrides{ + platform.BindingExecutionConfigResourceLimitsPolicyOverrides{ PolicyName: limitsObj.PolicyName.ValueString(), - Limit: api.BindingExecutionConfigResourceLimit{ + Limit: platform.BindingExecutionConfigResourceLimit{ MaxCount: limitsObj.MaxCount.ValueInt32Pointer(), MaxPercentage: limitsObj.MaxPercentage.ValueFloat32Pointer(), RequiresBoth: limitsObj.RequiresBoth.ValueBool(), @@ -341,9 +341,9 @@ func (r bindingResource) getExecutionConfig(ctx context.Context, plan models.Bin } } - return api.BindingExecutionConfig{ + return platform.BindingExecutionConfig{ DryRun: dryRun, - ResourceLimits: &api.BindingExecutionConfigResourceLimits{ + ResourceLimits: &platform.BindingExecutionConfigResourceLimits{ Default: defaultResourceLimits, PolicyOverrides: policyResourceLimits, }, diff --git a/internal/resources/configuration_profile_account_owners.go b/internal/resources/configuration_profile_account_owners.go index 5732ec47..731b59ac 100644 --- a/internal/resources/configuration_profile_account_owners.go +++ b/internal/resources/configuration_profile_account_owners.go @@ -16,7 +16,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" "github.com/stacklet/terraform-provider-stacklet/internal/schemadefault" @@ -135,11 +135,11 @@ func (r *configurationProfileAccountOwnersResource) Create(ctx context.Context, return } - input := api.AccountOwnersConfiguration{ + input := platform.AccountOwnersConfiguration{ Default: defaultOwners, OrgDomain: plan.OrgDomain.ValueStringPointer(), OrgDomainTag: plan.OrgDomainTag.ValueStringPointer(), - Tags: api.StringsList(plan.Tags), + Tags: platform.StringsList(plan.Tags), } profileConfig, err := r.api.ConfigurationProfile.UpsertAccountOwners(ctx, input) if err != nil { @@ -164,11 +164,11 @@ func (r *configurationProfileAccountOwnersResource) Update(ctx context.Context, return } - input := api.AccountOwnersConfiguration{ + input := platform.AccountOwnersConfiguration{ Default: defaultOwners, OrgDomain: plan.OrgDomain.ValueStringPointer(), OrgDomainTag: plan.OrgDomainTag.ValueStringPointer(), - Tags: api.StringsList(plan.Tags), + Tags: platform.StringsList(plan.Tags), } profileConfig, err := r.api.ConfigurationProfile.UpsertAccountOwners(ctx, input) if err != nil { @@ -194,17 +194,17 @@ func (r *configurationProfileAccountOwnersResource) Delete(ctx context.Context, } func (r *configurationProfileAccountOwnersResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("profile"), string(api.ConfigurationProfileAccountOwners))...) + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("profile"), string(platform.ConfigurationProfileAccountOwners))...) } -func (r configurationProfileAccountOwnersResource) getDefaultOwners(ctx context.Context, m models.ConfigurationProfileAccountOwnersResource) ([]api.AccountOwners, diag.Diagnostics) { +func (r configurationProfileAccountOwnersResource) getDefaultOwners(ctx context.Context, m models.ConfigurationProfileAccountOwnersResource) ([]platform.AccountOwners, diag.Diagnostics) { if m.Default.IsNull() { return nil, nil } var diags diag.Diagnostics - owners := make([]api.AccountOwners, 0) + owners := make([]platform.AccountOwners, 0) for i, elem := range m.Default.Elements() { block, ok := elem.(types.Object) if !ok { @@ -222,9 +222,9 @@ func (r configurationProfileAccountOwnersResource) getDefaultOwners(ctx context. owners = append( owners, - api.AccountOwners{ + platform.AccountOwners{ Account: o.Account.ValueString(), - Owners: api.StringsList(o.Owners), + Owners: platform.StringsList(o.Owners), }, ) } diff --git a/internal/resources/configuration_profile_email.go b/internal/resources/configuration_profile_email.go index 1117fb4a..2d4d9d5d 100644 --- a/internal/resources/configuration_profile_email.go +++ b/internal/resources/configuration_profile_email.go @@ -12,7 +12,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" ) @@ -134,9 +134,9 @@ func (r *configurationProfileEmailResource) Create(ctx context.Context, req reso return } - var smtp *api.SMTPConfiguration + var smtp *platform.SMTPConfiguration if !smtpPlan.Server.IsNull() { - smtp = &api.SMTPConfiguration{ + smtp = &platform.SMTPConfiguration{ Server: smtpPlan.Server.ValueString(), Port: smtpPlan.Port.ValueString(), SSL: smtpPlan.SSL.ValueBoolPointer(), @@ -145,7 +145,7 @@ func (r *configurationProfileEmailResource) Create(ctx context.Context, req reso } } - input := api.EmailConfiguration{ + input := platform.EmailConfiguration{ FromEmail: plan.From.ValueString(), SESRegion: plan.SESRegion.ValueStringPointer(), SMTP: smtp, @@ -180,7 +180,7 @@ func (r *configurationProfileEmailResource) Update(ctx context.Context, req reso return } - var smtp *api.SMTPConfiguration + var smtp *platform.SMTPConfiguration if !smtpPlan.Server.IsNull() { var password *string @@ -190,7 +190,7 @@ func (r *configurationProfileEmailResource) Update(ctx context.Context, req reso password = smtpConfig.PasswordWO.ValueStringPointer() // send the new value from the config } - smtp = &api.SMTPConfiguration{ + smtp = &platform.SMTPConfiguration{ Server: smtpPlan.Server.ValueString(), Port: smtpPlan.Port.ValueString(), SSL: smtpPlan.SSL.ValueBoolPointer(), @@ -199,7 +199,7 @@ func (r *configurationProfileEmailResource) Update(ctx context.Context, req reso } } - input := api.EmailConfiguration{ + input := platform.EmailConfiguration{ FromEmail: plan.From.ValueString(), SESRegion: plan.SESRegion.ValueStringPointer(), SMTP: smtp, @@ -222,7 +222,7 @@ func (r *configurationProfileEmailResource) Delete(ctx context.Context, req reso } func (r *configurationProfileEmailResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("profile"), string(api.ConfigurationProfileEmail))...) + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("profile"), string(platform.ConfigurationProfileEmail))...) } func (r configurationProfileEmailResource) getSMTPResource(ctx context.Context, m models.ConfigurationProfileEmailResource) (models.SMTPResource, diag.Diagnostics) { diff --git a/internal/resources/configuration_profile_jira.go b/internal/resources/configuration_profile_jira.go index 2892e252..c023a48e 100644 --- a/internal/resources/configuration_profile_jira.go +++ b/internal/resources/configuration_profile_jira.go @@ -15,7 +15,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" ) @@ -144,7 +144,7 @@ func (r *configurationProfileJiraResource) Create(ctx context.Context, req resou return } - input := api.JiraConfiguration{ + input := platform.JiraConfiguration{ URL: plan.URL.ValueStringPointer(), Projects: projects, User: plan.User.ValueString(), @@ -182,7 +182,7 @@ func (r *configurationProfileJiraResource) Update(ctx context.Context, req resou return } - input := api.JiraConfiguration{ + input := platform.JiraConfiguration{ URL: plan.URL.ValueStringPointer(), Projects: projects, User: plan.User.ValueString(), @@ -212,17 +212,17 @@ func (r *configurationProfileJiraResource) Delete(ctx context.Context, req resou } func (r *configurationProfileJiraResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("profile"), string(api.ConfigurationProfileJira))...) + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("profile"), string(platform.ConfigurationProfileJira))...) } -func (r configurationProfileJiraResource) getProjects(ctx context.Context, m models.ConfigurationProfileJiraResource) ([]api.JiraProject, diag.Diagnostics) { +func (r configurationProfileJiraResource) getProjects(ctx context.Context, m models.ConfigurationProfileJiraResource) ([]platform.JiraProject, diag.Diagnostics) { if m.Projects.IsNull() { return nil, nil } var diags diag.Diagnostics - projects := make([]api.JiraProject, 0) + projects := make([]platform.JiraProject, 0) for i, elem := range m.Projects.Elements() { block, ok := elem.(types.Object) if !ok { @@ -240,7 +240,7 @@ func (r configurationProfileJiraResource) getProjects(ctx context.Context, m mod projects = append( projects, - api.JiraProject{ + platform.JiraProject{ ClosedStatus: p.ClosedStatus.ValueString(), IssueType: p.IssueType.ValueString(), Name: p.Name.ValueString(), diff --git a/internal/resources/configuration_profile_msteams.go b/internal/resources/configuration_profile_msteams.go index fce9cbfc..5a72d7c1 100644 --- a/internal/resources/configuration_profile_msteams.go +++ b/internal/resources/configuration_profile_msteams.go @@ -16,7 +16,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" "github.com/stacklet/terraform-provider-stacklet/internal/planmodifiers" @@ -327,12 +327,12 @@ func (r *configurationProfileMSTeamsResource) Delete(ctx context.Context, req re } func (r *configurationProfileMSTeamsResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("profile"), string(api.ConfigurationProfileMSTeams))...) + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("profile"), string(platform.ConfigurationProfileMSTeams))...) } -func (r *configurationProfileMSTeamsResource) buildInput(ctx context.Context, data models.ConfigurationProfileMSTeamsResource) (api.MSTeamsConfigurationInput, diag.Diagnostics) { +func (r *configurationProfileMSTeamsResource) buildInput(ctx context.Context, data models.ConfigurationProfileMSTeamsResource) (platform.MSTeamsConfigurationInput, diag.Diagnostics) { var diags diag.Diagnostics - input := api.MSTeamsConfigurationInput{} + input := platform.MSTeamsConfigurationInput{} if !data.AccessConfigInput.IsNull() && !data.AccessConfigInput.IsUnknown() { var accessConfigInput models.MSTeamsAccessConfigInput @@ -341,7 +341,7 @@ func (r *configurationProfileMSTeamsResource) buildInput(ctx context.Context, da return input, diags } - input.AccessConfig = &api.MSTeamsAccessConfigInput{ + input.AccessConfig = &platform.MSTeamsAccessConfigInput{ ClientID: accessConfigInput.ClientID.ValueString(), RoundtripDigest: accessConfigInput.RoundtripDigest.ValueString(), TenantID: accessConfigInput.TenantID.ValueString(), @@ -355,9 +355,9 @@ func (r *configurationProfileMSTeamsResource) buildInput(ctx context.Context, da return input, diags } - input.CustomerConfig = &api.MSTeamsCustomerConfigInput{ + input.CustomerConfig = &platform.MSTeamsCustomerConfigInput{ Prefix: customerConfigInput.Prefix.ValueString(), - Tags: api.NewTagsList(customerConfigInput.Tags), + Tags: platform.NewTagsList(customerConfigInput.Tags), } } @@ -368,11 +368,11 @@ func (r *configurationProfileMSTeamsResource) buildInput(ctx context.Context, da return input, diags } - apiMappings := make([]api.MSTeamsChannelMapping, len(channelMappings)) + apiMappings := make([]platform.MSTeamsChannelMapping, len(channelMappings)) for i, mapping := range channelMappings { - apiMappings[i] = api.MSTeamsChannelMapping{ + apiMappings[i] = platform.MSTeamsChannelMapping{ Name: mapping.Name.ValueString(), - TeamID: api.UUID(mapping.TeamID.ValueString()), + TeamID: platform.UUID(mapping.TeamID.ValueString()), ChannelID: mapping.ChannelID.ValueString(), } } diff --git a/internal/resources/configuration_profile_resource_owner.go b/internal/resources/configuration_profile_resource_owner.go index c6c5a678..c3ac88d9 100644 --- a/internal/resources/configuration_profile_resource_owner.go +++ b/internal/resources/configuration_profile_resource_owner.go @@ -12,7 +12,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" "github.com/stacklet/terraform-provider-stacklet/internal/schemadefault" @@ -103,11 +103,11 @@ func (r *configurationProfileResourceOwnerResource) Create(ctx context.Context, return } - input := api.ResourceOwnerConfiguration{ - Default: api.StringsList(plan.Default), + input := platform.ResourceOwnerConfiguration{ + Default: platform.StringsList(plan.Default), OrgDomain: plan.OrgDomain.ValueStringPointer(), OrgDomainTag: plan.OrgDomainTag.ValueStringPointer(), - Tags: api.StringsList(plan.Tags), + Tags: platform.StringsList(plan.Tags), } config, err := r.api.ConfigurationProfile.UpsertResourceOwner(ctx, input) if err != nil { @@ -126,11 +126,11 @@ func (r *configurationProfileResourceOwnerResource) Update(ctx context.Context, return } - input := api.ResourceOwnerConfiguration{ - Default: api.StringsList(plan.Default), + input := platform.ResourceOwnerConfiguration{ + Default: platform.StringsList(plan.Default), OrgDomain: plan.OrgDomain.ValueStringPointer(), OrgDomainTag: plan.OrgDomainTag.ValueStringPointer(), - Tags: api.StringsList(plan.Tags), + Tags: platform.StringsList(plan.Tags), } config, err := r.api.ConfigurationProfile.UpsertResourceOwner(ctx, input) if err != nil { @@ -156,5 +156,5 @@ func (r *configurationProfileResourceOwnerResource) Delete(ctx context.Context, } func (r *configurationProfileResourceOwnerResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("profile"), string(api.ConfigurationProfileResourceOwner))...) + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("profile"), string(platform.ConfigurationProfileResourceOwner))...) } diff --git a/internal/resources/configuration_profile_servicenow.go b/internal/resources/configuration_profile_servicenow.go index acdd11f3..3e8bc4b8 100644 --- a/internal/resources/configuration_profile_servicenow.go +++ b/internal/resources/configuration_profile_servicenow.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" ) @@ -110,7 +110,7 @@ func (r *configurationProfileServiceNowResource) Create(ctx context.Context, req return } - input := api.ServiceNowConfiguration{ + input := platform.ServiceNowConfiguration{ Endpoint: plan.Endpoint.ValueString(), User: plan.Username.ValueString(), Password: config.PasswordWO.ValueString(), @@ -143,7 +143,7 @@ func (r *configurationProfileServiceNowResource) Update(ctx context.Context, req password = config.PasswordWO.ValueString() // send the new value from the config } - input := api.ServiceNowConfiguration{ + input := platform.ServiceNowConfiguration{ Endpoint: plan.Endpoint.ValueString(), User: plan.Username.ValueString(), Password: password, @@ -174,5 +174,5 @@ func (r *configurationProfileServiceNowResource) Delete(ctx context.Context, req } func (r *configurationProfileServiceNowResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("profile"), string(api.ConfigurationProfileServiceNow))...) + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("profile"), string(platform.ConfigurationProfileServiceNow))...) } diff --git a/internal/resources/configuration_profile_slack.go b/internal/resources/configuration_profile_slack.go index ac4aa56d..f47ce499 100644 --- a/internal/resources/configuration_profile_slack.go +++ b/internal/resources/configuration_profile_slack.go @@ -15,7 +15,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" "github.com/stacklet/terraform-provider-stacklet/internal/schemadefault" @@ -157,8 +157,8 @@ func (r *configurationProfileSlackResource) Create(ctx context.Context, req reso return } - input := api.SlackConfiguration{ - UserFields: api.StringsList(plan.UserFields), + input := platform.SlackConfiguration{ + UserFields: platform.StringsList(plan.UserFields), Token: config.TokenWO.ValueStringPointer(), Webhooks: webhooks, } @@ -200,8 +200,8 @@ func (r *configurationProfileSlackResource) Update(ctx context.Context, req reso token = config.Token.ValueStringPointer() // send the new value from the config } - input := api.SlackConfiguration{ - UserFields: api.StringsList(plan.UserFields), + input := platform.SlackConfiguration{ + UserFields: platform.StringsList(plan.UserFields), Token: token, Webhooks: webhooks, } @@ -229,10 +229,10 @@ func (r *configurationProfileSlackResource) Delete(ctx context.Context, req reso } func (r *configurationProfileSlackResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("profile"), string(api.ConfigurationProfileSlack))...) + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("profile"), string(platform.ConfigurationProfileSlack))...) } -func (r configurationProfileSlackResource) updateSlackModel(ctx context.Context, m *models.ConfigurationProfileSlackResource, webhookSecrets map[string]slackWebhookSecret, cp *api.ConfigurationProfile) diag.Diagnostics { +func (r configurationProfileSlackResource) updateSlackModel(ctx context.Context, m *models.ConfigurationProfileSlackResource, webhookSecrets map[string]slackWebhookSecret, cp *platform.ConfigurationProfile) diag.Diagnostics { webhookVersions := map[string]string{} for name, secret := range webhookSecrets { webhookVersions[name] = secret.Version @@ -269,14 +269,14 @@ func (r configurationProfileSlackResource) getWebhooksSecrets(ctx context.Contex return secrets, diags } -func (r configurationProfileSlackResource) getWebhooksForCreate(ctx context.Context, m models.ConfigurationProfileSlackResource, webhookSecrets map[string]slackWebhookSecret) ([]api.SlackWebhook, diag.Diagnostics) { +func (r configurationProfileSlackResource) getWebhooksForCreate(ctx context.Context, m models.ConfigurationProfileSlackResource, webhookSecrets map[string]slackWebhookSecret) ([]platform.SlackWebhook, diag.Diagnostics) { if m.Webhooks.IsNull() { return nil, nil } var diags diag.Diagnostics - webhooks := make([]api.SlackWebhook, 0) + webhooks := make([]platform.SlackWebhook, 0) for i, elem := range m.Webhooks.Elements() { block, ok := elem.(types.Object) if !ok { @@ -294,7 +294,7 @@ func (r configurationProfileSlackResource) getWebhooksForCreate(ctx context.Cont webhooks = append( webhooks, - api.SlackWebhook{ + platform.SlackWebhook{ Name: w.Name.ValueString(), URL: webhookSecrets[w.Name.ValueString()].Plaintext, }, @@ -303,14 +303,14 @@ func (r configurationProfileSlackResource) getWebhooksForCreate(ctx context.Cont return webhooks, diags } -func (r configurationProfileSlackResource) getWebhooksForUpdate(ctx context.Context, m models.ConfigurationProfileSlackResource, webhookSecretsFromConfig, webhookSecretsFromState map[string]slackWebhookSecret) ([]api.SlackWebhook, diag.Diagnostics) { +func (r configurationProfileSlackResource) getWebhooksForUpdate(ctx context.Context, m models.ConfigurationProfileSlackResource, webhookSecretsFromConfig, webhookSecretsFromState map[string]slackWebhookSecret) ([]platform.SlackWebhook, diag.Diagnostics) { if m.Webhooks.IsNull() { return nil, nil } var diags diag.Diagnostics - webhooks := make([]api.SlackWebhook, 0) + webhooks := make([]platform.SlackWebhook, 0) for i, elem := range m.Webhooks.Elements() { block, ok := elem.(types.Object) if !ok { @@ -337,7 +337,7 @@ func (r configurationProfileSlackResource) getWebhooksForUpdate(ctx context.Cont webhooks = append( webhooks, - api.SlackWebhook{ + platform.SlackWebhook{ Name: w.Name.ValueString(), URL: url, }, diff --git a/internal/resources/configuration_profile_symphony.go b/internal/resources/configuration_profile_symphony.go index 2b4c3aee..07331222 100644 --- a/internal/resources/configuration_profile_symphony.go +++ b/internal/resources/configuration_profile_symphony.go @@ -11,7 +11,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" ) @@ -102,7 +102,7 @@ func (r *configurationProfileSymphonyResource) Create(ctx context.Context, req r return } - input := api.SymphonyConfiguration{ + input := platform.SymphonyConfiguration{ AgentDomain: plan.AgentDomain.ValueString(), ServiceAccount: plan.ServiceAccount.ValueString(), PrivateKey: config.PrivateKeyWO.ValueString(), @@ -133,7 +133,7 @@ func (r *configurationProfileSymphonyResource) Update(ctx context.Context, req r privateKey = config.PrivateKeyWO.ValueString() // send the new value from the config } - input := api.SymphonyConfiguration{ + input := platform.SymphonyConfiguration{ AgentDomain: plan.AgentDomain.ValueString(), ServiceAccount: plan.ServiceAccount.ValueString(), PrivateKey: privateKey, @@ -162,5 +162,5 @@ func (r *configurationProfileSymphonyResource) Delete(ctx context.Context, req r } func (r *configurationProfileSymphonyResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("profile"), string(api.ConfigurationProfileSymphony))...) + resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("profile"), string(platform.ConfigurationProfileSymphony))...) } diff --git a/internal/resources/datadog_integration.go b/internal/resources/datadog_integration.go index 8e30b58f..a206ef1f 100644 --- a/internal/resources/datadog_integration.go +++ b/internal/resources/datadog_integration.go @@ -16,7 +16,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" ) @@ -112,7 +112,7 @@ func (r *datadogIntegrationResource) Create(ctx context.Context, req resource.Cr // A version set without its key is refused here too: it would otherwise be // recorded as the version the stored credential corresponds to, when no // credential was sent at all. - input := api.DatadogIntegrationInput{ + input := platform.DatadogIntegrationInput{ Enabled: plan.Enabled.ValueBoolPointer(), Site: plan.Site.ValueStringPointer(), APIKey: credentialToSend(&resp.Diagnostics, !plan.APIKeyWOVersion.IsNull() || !config.APIKeyWO.IsNull(), "api_key_wo", config.APIKeyWO), @@ -161,7 +161,7 @@ func (r *datadogIntegrationResource) Update(ctx context.Context, req resource.Up // Only send a key whose version says it has changed: omitted fields keep // their stored value, which is the only way to change the site or the // enabled flag without resupplying credentials. - input := api.DatadogIntegrationInput{ + input := platform.DatadogIntegrationInput{ Enabled: plan.Enabled.ValueBoolPointer(), Site: plan.Site.ValueStringPointer(), APIKey: credentialToSend(&resp.Diagnostics, !state.APIKeyWOVersion.Equal(plan.APIKeyWOVersion), "api_key_wo", config.APIKeyWO), diff --git a/internal/resources/gcp_integration.go b/internal/resources/gcp_integration.go index 89f21dd9..1266453c 100644 --- a/internal/resources/gcp_integration.go +++ b/internal/resources/gcp_integration.go @@ -12,7 +12,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" ) @@ -496,12 +496,12 @@ func (r *gcpIntegrationResource) ImportState(ctx context.Context, req resource.I importState(ctx, req, resp, []string{"key"}) } -func buildGCPIntegrationInput(ctx context.Context, plan models.GCPIntegrationResource) (api.GCPIntegrationInput, diag.Diagnostics) { +func buildGCPIntegrationInput(ctx context.Context, plan models.GCPIntegrationResource) (platform.GCPIntegrationInput, diag.Diagnostics) { var diags diag.Diagnostics customerConfig, d := buildCustomerConfigInput(ctx, plan.CustomerConfigInput) diags.Append(d...) - input := api.GCPIntegrationInput{ + input := platform.GCPIntegrationInput{ Key: plan.Key.ValueString(), AccessConfigBlob: plan.AccessConfigBlobInput.ValueStringPointer(), CustomerConfig: customerConfig, @@ -509,7 +509,7 @@ func buildGCPIntegrationInput(ctx context.Context, plan models.GCPIntegrationRes return input, diags } -func buildCustomerConfigInput(ctx context.Context, obj types.Object) (*api.GCPIntegrationCustomerConfigInput, diag.Diagnostics) { +func buildCustomerConfigInput(ctx context.Context, obj types.Object) (*platform.GCPIntegrationCustomerConfigInput, diag.Diagnostics) { var diags diag.Diagnostics if obj.IsNull() || obj.IsUnknown() { @@ -535,7 +535,7 @@ func buildCustomerConfigInput(ctx context.Context, obj types.Object) (*api.GCPIn return nil, diags } - return &api.GCPIntegrationCustomerConfigInput{ + return &platform.GCPIntegrationCustomerConfigInput{ Infrastructure: infrastructure, Organizations: organizations, CostSources: costSources, @@ -543,7 +543,7 @@ func buildCustomerConfigInput(ctx context.Context, obj types.Object) (*api.GCPIn }, diags } -func buildInfrastructureInput(ctx context.Context, obj types.Object) (*api.GCPIntegrationCustomerInfrastructureInput, diag.Diagnostics) { +func buildInfrastructureInput(ctx context.Context, obj types.Object) (*platform.GCPIntegrationCustomerInfrastructureInput, diag.Diagnostics) { var diags diag.Diagnostics if obj.IsNull() || obj.IsUnknown() { @@ -562,7 +562,7 @@ func buildInfrastructureInput(ctx context.Context, obj types.Object) (*api.GCPIn return nil, diags } - return &api.GCPIntegrationCustomerInfrastructureInput{ + return &platform.GCPIntegrationCustomerInfrastructureInput{ ProjectID: m.ProjectID.ValueStringPointer(), ResourceLocation: m.ResourceLocation.ValueStringPointer(), ResourcePrefix: m.ResourcePrefix.ValueStringPointer(), @@ -570,7 +570,7 @@ func buildInfrastructureInput(ctx context.Context, obj types.Object) (*api.GCPIn }, diags } -func buildCreateProjectInput(ctx context.Context, obj types.Object) (*api.GCPIntegrationCustomerCreateProjectInput, diag.Diagnostics) { +func buildCreateProjectInput(ctx context.Context, obj types.Object) (*platform.GCPIntegrationCustomerCreateProjectInput, diag.Diagnostics) { var diags diag.Diagnostics if obj.IsNull() || obj.IsUnknown() { @@ -583,15 +583,15 @@ func buildCreateProjectInput(ctx context.Context, obj types.Object) (*api.GCPInt return nil, diags } - return &api.GCPIntegrationCustomerCreateProjectInput{ + return &platform.GCPIntegrationCustomerCreateProjectInput{ BillingAccountID: m.BillingAccountID.ValueStringPointer(), OrgID: m.OrgID.ValueStringPointer(), FolderID: m.FolderID.ValueStringPointer(), - Labels: api.NewTagsList(m.Labels), + Labels: platform.NewTagsList(m.Labels), }, diags } -func buildOrganizationsInput(ctx context.Context, l types.List) (*[]api.GCPIntegrationCustomerOrganizationInput, diag.Diagnostics) { +func buildOrganizationsInput(ctx context.Context, l types.List) (*[]platform.GCPIntegrationCustomerOrganizationInput, diag.Diagnostics) { var diags diag.Diagnostics if l.IsNull() || l.IsUnknown() { @@ -604,18 +604,18 @@ func buildOrganizationsInput(ctx context.Context, l types.List) (*[]api.GCPInteg return nil, diags } - result := make([]api.GCPIntegrationCustomerOrganizationInput, len(ms)) + result := make([]platform.GCPIntegrationCustomerOrganizationInput, len(ms)) for i, m := range ms { - result[i] = api.GCPIntegrationCustomerOrganizationInput{ + result[i] = platform.GCPIntegrationCustomerOrganizationInput{ OrgID: m.OrgID.ValueString(), - FolderIDs: api.StringsList(m.FolderIDs), - ProjectIDs: api.StringsList(m.ProjectIDs), + FolderIDs: platform.StringsList(m.FolderIDs), + ProjectIDs: platform.StringsList(m.ProjectIDs), } } return &result, diags } -func buildCostSourcesInput(ctx context.Context, l types.List) (*[]api.GCPIntegrationCustomerCostSourceInput, diag.Diagnostics) { +func buildCostSourcesInput(ctx context.Context, l types.List) (*[]platform.GCPIntegrationCustomerCostSourceInput, diag.Diagnostics) { var diags diag.Diagnostics if l.IsNull() || l.IsUnknown() { @@ -628,16 +628,16 @@ func buildCostSourcesInput(ctx context.Context, l types.List) (*[]api.GCPIntegra return nil, diags } - result := make([]api.GCPIntegrationCustomerCostSourceInput, len(ms)) + result := make([]platform.GCPIntegrationCustomerCostSourceInput, len(ms)) for i, m := range ms { - result[i] = api.GCPIntegrationCustomerCostSourceInput{ + result[i] = platform.GCPIntegrationCustomerCostSourceInput{ BillingTable: m.BillingTable.ValueString(), } } return &result, diags } -func buildSecurityContextsInput(ctx context.Context, l types.List) (*[]api.GCPIntegrationCustomerSecurityContextInput, diag.Diagnostics) { +func buildSecurityContextsInput(ctx context.Context, l types.List) (*[]platform.GCPIntegrationCustomerSecurityContextInput, diag.Diagnostics) { var diags diag.Diagnostics if l.IsNull() || l.IsUnknown() { @@ -650,11 +650,11 @@ func buildSecurityContextsInput(ctx context.Context, l types.List) (*[]api.GCPIn return nil, diags } - result := make([]api.GCPIntegrationCustomerSecurityContextInput, len(ms)) + result := make([]platform.GCPIntegrationCustomerSecurityContextInput, len(ms)) for i, m := range ms { - result[i] = api.GCPIntegrationCustomerSecurityContextInput{ + result[i] = platform.GCPIntegrationCustomerSecurityContextInput{ Name: m.Name.ValueString(), - ExtraRoles: api.StringsList(m.ExtraRoles), + ExtraRoles: platform.StringsList(m.ExtraRoles), } } return &result, diags diff --git a/internal/resources/notification_template.go b/internal/resources/notification_template.go index 0dc1f8f5..8174bbe1 100644 --- a/internal/resources/notification_template.go +++ b/internal/resources/notification_template.go @@ -10,7 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" "github.com/stacklet/terraform-provider-stacklet/internal/planmodifiers" @@ -91,7 +91,7 @@ func (r *notificationTemplateResource) Create(ctx context.Context, req resource. return } - input := api.TemplateInput{ + input := platform.TemplateInput{ Name: plan.Name.ValueString(), Description: plan.Description.ValueStringPointer(), Transport: plan.Transport.ValueStringPointer(), @@ -114,7 +114,7 @@ func (r *notificationTemplateResource) Update(ctx context.Context, req resource. return } - input := api.TemplateInput{ + input := platform.TemplateInput{ Name: plan.Name.ValueString(), Description: plan.Description.ValueStringPointer(), Transport: plan.Transport.ValueStringPointer(), diff --git a/internal/resources/policy_collection.go b/internal/resources/policy_collection.go index 76167997..bea56534 100644 --- a/internal/resources/policy_collection.go +++ b/internal/resources/policy_collection.go @@ -16,7 +16,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" "github.com/stacklet/terraform-provider-stacklet/internal/planmodifiers" @@ -161,9 +161,9 @@ func (r *policyCollectionResource) Create(ctx context.Context, req resource.Crea return } - input := api.PolicyCollectionCreateInput{ + input := platform.PolicyCollectionCreateInput{ Name: plan.Name.ValueString(), - Provider: api.CloudProvider(plan.CloudProvider.ValueString()), + Provider: platform.CloudProvider(plan.CloudProvider.ValueString()), Description: plan.Description.ValueStringPointer(), AutoUpdate: plan.AutoUpdate.ValueBoolPointer(), // the following are null if the policy collection is not dynamic @@ -211,10 +211,10 @@ func (r *policyCollectionResource) Update(ctx context.Context, req resource.Upda return } - input := api.PolicyCollectionUpdateInput{ + input := platform.PolicyCollectionUpdateInput{ UUID: plan.UUID.ValueString(), Name: plan.Name.ValueString(), - Provider: api.CloudProvider(plan.CloudProvider.ValueString()), + Provider: platform.CloudProvider(plan.CloudProvider.ValueString()), Description: plan.Description.ValueStringPointer(), AutoUpdate: plan.AutoUpdate.ValueBoolPointer(), RepositoryView: repositoryView, // null if the policy collection is not dynamic @@ -247,19 +247,19 @@ func (r *policyCollectionResource) ImportState(ctx context.Context, req resource importState(ctx, req, resp, []string{"uuid"}) } -func (r policyCollectionResource) getDynamicDetails(ctx context.Context, planDynamicConfig types.Object) (*string, *api.RepositoryViewInput, diag.Diagnostics) { +func (r policyCollectionResource) getDynamicDetails(ctx context.Context, planDynamicConfig types.Object) (*string, *platform.RepositoryViewInput, diag.Diagnostics) { var uuid *string - var view *api.RepositoryViewInput + var view *platform.RepositoryViewInput var diags diag.Diagnostics if !planDynamicConfig.IsNull() { var dynamicConfig models.PolicyCollectionDynamicConfig diags = planDynamicConfig.As(ctx, &dynamicConfig, objectAsOptions) uuid = dynamicConfig.RepositoryUUID.ValueStringPointer() - view = &api.RepositoryViewInput{ + view = &platform.RepositoryViewInput{ BranchName: dynamicConfig.BranchName.ValueStringPointer(), - PolicyDirectories: api.StringsList(dynamicConfig.PolicyDirectories), - PolicyFileSuffix: api.StringsList(dynamicConfig.PolicyFileSuffixes), + PolicyDirectories: platform.StringsList(dynamicConfig.PolicyDirectories), + PolicyFileSuffix: platform.StringsList(dynamicConfig.PolicyFileSuffixes), } } diff --git a/internal/resources/policy_collection_mapping.go b/internal/resources/policy_collection_mapping.go index 059c573e..a90ebf99 100644 --- a/internal/resources/policy_collection_mapping.go +++ b/internal/resources/policy_collection_mapping.go @@ -10,7 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" ) @@ -69,7 +69,7 @@ func (r *policyCollectionMappingResource) Create(ctx context.Context, req resour return } - input := api.PolicyCollectionMappingInput{ + input := platform.PolicyCollectionMappingInput{ CollectionUUID: plan.CollectionUUID.ValueString(), PolicyUUID: plan.PolicyUUID.ValueString(), PolicyVersion: int(plan.PolicyVersion.ValueInt32()), @@ -109,7 +109,7 @@ func (r *policyCollectionMappingResource) Update(ctx context.Context, req resour return } - input := api.PolicyCollectionMappingInput{ + input := platform.PolicyCollectionMappingInput{ CollectionUUID: plan.CollectionUUID.ValueString(), PolicyUUID: plan.PolicyUUID.ValueString(), PolicyVersion: int(plan.PolicyVersion.ValueInt32()), diff --git a/internal/resources/report_group.go b/internal/resources/report_group.go index d6706155..85c24a5e 100644 --- a/internal/resources/report_group.go +++ b/internal/resources/report_group.go @@ -19,7 +19,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/schema/validator" "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" "github.com/stacklet/terraform-provider-stacklet/internal/schemadefault" @@ -519,13 +519,13 @@ func (r *reportGroupResource) Create(ctx context.Context, req resource.CreateReq return } - input := api.ReportGroupInput{ + input := platform.ReportGroupInput{ Name: plan.Name.ValueString(), Enabled: plan.Enabled.ValueBool(), - Bindings: api.StringsList(plan.Bindings), - Source: api.ReportSourceBinding, // only binding-based report groups are managed for now + Bindings: platform.StringsList(plan.Bindings), + Source: platform.ReportSourceBinding, // only binding-based report groups are managed for now Schedule: plan.Schedule.ValueString(), - GroupBy: api.StringsList(plan.GroupBy), + GroupBy: platform.StringsList(plan.GroupBy), UseMessageSettings: plan.UseMessageSettings.ValueBool(), EmailSettings: emailSettings, SlackSettings: slackSettings, @@ -587,13 +587,13 @@ func (r *reportGroupResource) Update(ctx context.Context, req resource.UpdateReq return } - input := api.ReportGroupInput{ + input := platform.ReportGroupInput{ Name: plan.Name.ValueString(), Enabled: plan.Enabled.ValueBool(), - Bindings: api.StringsList(plan.Bindings), - Source: api.ReportSourceBinding, // only binding-based report groups are managed for now + Bindings: platform.StringsList(plan.Bindings), + Source: platform.ReportSourceBinding, // only binding-based report groups are managed for now Schedule: plan.Schedule.ValueString(), - GroupBy: api.StringsList(plan.GroupBy), + GroupBy: platform.StringsList(plan.GroupBy), UseMessageSettings: plan.UseMessageSettings.ValueBool(), EmailSettings: emailSettings, SlackSettings: slackSettings, @@ -629,14 +629,14 @@ func (r *reportGroupResource) ImportState(ctx context.Context, req resource.Impo importState(ctx, req, resp, []string{"name"}) } -func (r reportGroupResource) getEmailDeliverySettings(ctx context.Context, m models.ReportGroupResource) ([]api.EmailDeliverySettings, diag.Diagnostics) { +func (r reportGroupResource) getEmailDeliverySettings(ctx context.Context, m models.ReportGroupResource) ([]platform.EmailDeliverySettings, diag.Diagnostics) { if m.EmailDeliverySettings.IsNull() { return nil, nil } var diags diag.Diagnostics - settings := make([]api.EmailDeliverySettings, 0) + settings := make([]platform.EmailDeliverySettings, 0) for i, elem := range m.EmailDeliverySettings.Elements() { block, ok := elem.(types.Object) if !ok { @@ -659,8 +659,8 @@ func (r reportGroupResource) getEmailDeliverySettings(ctx context.Context, m mod settings = append( settings, - api.EmailDeliverySettings{ - CC: api.StringsList(s.CC), + platform.EmailDeliverySettings{ + CC: platform.StringsList(s.CC), FirstMatchOnly: s.FirstMatchOnly.ValueBoolPointer(), Format: s.Format.ValueStringPointer(), FromEmail: s.From.ValueStringPointer(), @@ -674,14 +674,14 @@ func (r reportGroupResource) getEmailDeliverySettings(ctx context.Context, m mod return settings, diags } -func (r reportGroupResource) getSlackDeliverySettings(ctx context.Context, m models.ReportGroupResource) ([]api.SlackDeliverySettings, diag.Diagnostics) { +func (r reportGroupResource) getSlackDeliverySettings(ctx context.Context, m models.ReportGroupResource) ([]platform.SlackDeliverySettings, diag.Diagnostics) { if m.SlackDeliverySettings.IsNull() { return nil, nil } var diags diag.Diagnostics - settings := make([]api.SlackDeliverySettings, 0) + settings := make([]platform.SlackDeliverySettings, 0) for i, elem := range m.SlackDeliverySettings.Elements() { block, ok := elem.(types.Object) if !ok { @@ -704,7 +704,7 @@ func (r reportGroupResource) getSlackDeliverySettings(ctx context.Context, m mod settings = append( settings, - api.SlackDeliverySettings{ + platform.SlackDeliverySettings{ FirstMatchOnly: s.FirstMatchOnly.ValueBoolPointer(), Recipients: recipients, Template: s.Template.ValueString(), @@ -714,14 +714,14 @@ func (r reportGroupResource) getSlackDeliverySettings(ctx context.Context, m mod return settings, diags } -func (r reportGroupResource) getMSTeamsDeliverySettings(ctx context.Context, m models.ReportGroupResource) ([]api.MSTeamsDeliverySettings, diag.Diagnostics) { +func (r reportGroupResource) getMSTeamsDeliverySettings(ctx context.Context, m models.ReportGroupResource) ([]platform.MSTeamsDeliverySettings, diag.Diagnostics) { if m.MSTeamsDeliverySettings.IsNull() { return nil, nil } var diags diag.Diagnostics - settings := make([]api.MSTeamsDeliverySettings, 0) + settings := make([]platform.MSTeamsDeliverySettings, 0) for i, elem := range m.MSTeamsDeliverySettings.Elements() { block, ok := elem.(types.Object) if !ok { @@ -744,7 +744,7 @@ func (r reportGroupResource) getMSTeamsDeliverySettings(ctx context.Context, m m settings = append( settings, - api.MSTeamsDeliverySettings{ + platform.MSTeamsDeliverySettings{ FirstMatchOnly: s.FirstMatchOnly.ValueBoolPointer(), Recipients: recipients, Template: s.Template.ValueString(), @@ -754,14 +754,14 @@ func (r reportGroupResource) getMSTeamsDeliverySettings(ctx context.Context, m m return settings, diags } -func (r reportGroupResource) getServiceNowDeliverySettings(ctx context.Context, m models.ReportGroupResource) ([]api.ServiceNowDeliverySettings, diag.Diagnostics) { +func (r reportGroupResource) getServiceNowDeliverySettings(ctx context.Context, m models.ReportGroupResource) ([]platform.ServiceNowDeliverySettings, diag.Diagnostics) { if m.ServiceNowDeliverySettings.IsNull() { return nil, nil } var diags diag.Diagnostics - settings := make([]api.ServiceNowDeliverySettings, 0) + settings := make([]platform.ServiceNowDeliverySettings, 0) for i, elem := range m.ServiceNowDeliverySettings.Elements() { block, ok := elem.(types.Object) if !ok { @@ -784,7 +784,7 @@ func (r reportGroupResource) getServiceNowDeliverySettings(ctx context.Context, settings = append( settings, - api.ServiceNowDeliverySettings{ + platform.ServiceNowDeliverySettings{ FirstMatchOnly: s.FirstMatchOnly.ValueBoolPointer(), Impact: s.Impact.ValueString(), Recipients: recipients, @@ -797,14 +797,14 @@ func (r reportGroupResource) getServiceNowDeliverySettings(ctx context.Context, return settings, diags } -func (r reportGroupResource) getJiraDeliverySettings(ctx context.Context, m models.ReportGroupResource) ([]api.JiraDeliverySettings, diag.Diagnostics) { +func (r reportGroupResource) getJiraDeliverySettings(ctx context.Context, m models.ReportGroupResource) ([]platform.JiraDeliverySettings, diag.Diagnostics) { if m.JiraDeliverySettings.IsNull() { return nil, nil } var diags diag.Diagnostics - settings := make([]api.JiraDeliverySettings, 0) + settings := make([]platform.JiraDeliverySettings, 0) for i, elem := range m.JiraDeliverySettings.Elements() { block, ok := elem.(types.Object) if !ok { @@ -827,7 +827,7 @@ func (r reportGroupResource) getJiraDeliverySettings(ctx context.Context, m mode settings = append( settings, - api.JiraDeliverySettings{ + platform.JiraDeliverySettings{ FirstMatchOnly: s.FirstMatchOnly.ValueBoolPointer(), Recipients: recipients, Template: s.Template.ValueString(), @@ -840,14 +840,14 @@ func (r reportGroupResource) getJiraDeliverySettings(ctx context.Context, m mode return settings, diags } -func (r reportGroupResource) getSymphonyDeliverySettings(ctx context.Context, m models.ReportGroupResource) ([]api.SymphonyDeliverySettings, diag.Diagnostics) { +func (r reportGroupResource) getSymphonyDeliverySettings(ctx context.Context, m models.ReportGroupResource) ([]platform.SymphonyDeliverySettings, diag.Diagnostics) { if m.SymphonyDeliverySettings.IsNull() { return nil, nil } var diags diag.Diagnostics - settings := make([]api.SymphonyDeliverySettings, 0) + settings := make([]platform.SymphonyDeliverySettings, 0) for i, elem := range m.SymphonyDeliverySettings.Elements() { block, ok := elem.(types.Object) if !ok { @@ -870,7 +870,7 @@ func (r reportGroupResource) getSymphonyDeliverySettings(ctx context.Context, m settings = append( settings, - api.SymphonyDeliverySettings{ + platform.SymphonyDeliverySettings{ FirstMatchOnly: s.FirstMatchOnly.ValueBoolPointer(), Recipients: recipients, Template: s.Template.ValueString(), @@ -880,14 +880,14 @@ func (r reportGroupResource) getSymphonyDeliverySettings(ctx context.Context, m return settings, diags } -func (r reportGroupResource) getRecipients(ctx context.Context, l types.List) ([]api.Recipient, diag.Diagnostics) { +func (r reportGroupResource) getRecipients(ctx context.Context, l types.List) ([]platform.Recipient, diag.Diagnostics) { if l.IsNull() { return nil, nil } var diags diag.Diagnostics - recipients := make([]api.Recipient, 0) + recipients := make([]platform.Recipient, 0) for i, elem := range l.Elements() { block, ok := elem.(types.Object) if !ok { @@ -905,7 +905,7 @@ func (r reportGroupResource) getRecipients(ctx context.Context, l types.List) ([ recipients = append( recipients, - api.Recipient{ + platform.Recipient{ AccountOwner: r.AccountOwner.ValueBoolPointer(), EventOwner: r.EventOwner.ValueBoolPointer(), ResourceOwner: r.ResourceOwner.ValueBoolPointer(), diff --git a/internal/resources/repository.go b/internal/resources/repository.go index 2f688d3f..dde2db44 100644 --- a/internal/resources/repository.go +++ b/internal/resources/repository.go @@ -12,7 +12,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" ) @@ -159,12 +159,12 @@ func (r *repositoryResource) Create(ctx context.Context, req resource.CreateRequ } // Create remote from plan and config. - auth := api.NewRepositoryConfigAuthInput() + auth := platform.NewRepositoryConfigAuthInput() auth.SetAuthUser(plan.AuthUser.ValueStringPointer()) auth.SetAuthToken(config.AuthTokenWO.ValueStringPointer()) auth.SetSSHPrivateKey(config.SSHPrivateKeyWO.ValueStringPointer()) auth.SetSSHPassphrase(config.SSHPassphraseWO.ValueStringPointer()) - input := api.RepositoryCreateInput{ + input := platform.RepositoryCreateInput{ Name: plan.Name.ValueString(), URL: plan.URL.ValueString(), Description: plan.Description.ValueStringPointer(), @@ -210,7 +210,7 @@ func (r *repositoryResource) Update(ctx context.Context, req resource.UpdateRequ } // Determine which auth fields need to be updated. - auth := api.NewRepositoryConfigAuthInput() + auth := platform.NewRepositoryConfigAuthInput() auth.SetAuthUser(plan.AuthUser.ValueStringPointer()) if state.AuthTokenWOVersion != plan.AuthTokenWOVersion { state.AuthTokenWOVersion = plan.AuthTokenWOVersion @@ -226,7 +226,7 @@ func (r *repositoryResource) Update(ctx context.Context, req resource.UpdateRequ } // Update remote according to the combined grand plan. - input := api.RepositoryUpdateInput{ + input := platform.RepositoryUpdateInput{ UUID: plan.UUID.ValueString(), Name: plan.Name.ValueString(), Description: plan.Description.ValueStringPointer(), @@ -251,7 +251,7 @@ func (r *repositoryResource) Delete(ctx context.Context, req resource.DeleteRequ } // Delete remote - input := api.RepositoryDeleteInput{ + input := platform.RepositoryDeleteInput{ UUID: data.UUID.ValueString(), // Note NOT cascading; we could add a force_delete attr if necessary, but the default // behaviour should *NOT* be to implicitly tear down resources not under management. diff --git a/internal/resources/resource.go b/internal/resources/resource.go index ccabee86..c02c4542 100644 --- a/internal/resources/resource.go +++ b/internal/resources/resource.go @@ -7,14 +7,14 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/providerdata" ) // apiResource is a resource based on the API. type apiResource struct { - api *api.API + api *platform.API } // Configure sets up API access for the resource. diff --git a/internal/resources/saml_provider.go b/internal/resources/saml_provider.go index c78359f2..d332337b 100644 --- a/internal/resources/saml_provider.go +++ b/internal/resources/saml_provider.go @@ -14,7 +14,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" ) @@ -87,7 +87,7 @@ func (r *samlProviderResource) Create(ctx context.Context, req resource.CreateRe return } - input := api.SAMLProviderCreateInput{ + input := platform.SAMLProviderCreateInput{ Name: plan.Name.ValueString(), DisplayName: plan.DisplayName.ValueStringPointer(), MetadataURL: plan.MetadataURL.ValueStringPointer(), @@ -130,7 +130,7 @@ func (r *samlProviderResource) Update(ctx context.Context, req resource.UpdateRe return } - input := api.SAMLProviderUpdateInput{ + input := platform.SAMLProviderUpdateInput{ Name: plan.Name.ValueString(), DisplayName: plan.DisplayName.ValueStringPointer(), MetadataURL: plan.MetadataURL.ValueStringPointer(), diff --git a/internal/resources/sso_group.go b/internal/resources/sso_group.go index d831c196..89c31bf4 100644 --- a/internal/resources/sso_group.go +++ b/internal/resources/sso_group.go @@ -10,7 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" ) @@ -69,7 +69,7 @@ func (r *ssoGroupResource) Create(ctx context.Context, req resource.CreateReques return } - input := api.SSOGroupInput{ + input := platform.SSOGroupInput{ Name: plan.Name.ValueString(), DisplayName: plan.DisplayName.ValueStringPointer(), } @@ -108,7 +108,7 @@ func (r *ssoGroupResource) Update(ctx context.Context, req resource.UpdateReques return } - input := api.SSOGroupInput{ + input := platform.SSOGroupInput{ Name: plan.Name.ValueString(), DisplayName: plan.DisplayName.ValueStringPointer(), } diff --git a/internal/resources/user.go b/internal/resources/user.go index 559b0e9e..61101768 100644 --- a/internal/resources/user.go +++ b/internal/resources/user.go @@ -12,7 +12,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" ) @@ -99,7 +99,7 @@ func (r *userResource) Create(ctx context.Context, req resource.CreateRequest, r return } - input := api.UserCreateInput{ + input := platform.UserCreateInput{ Name: plan.Name.ValueString(), DisplayName: plan.DisplayName.ValueStringPointer(), Username: plan.Username.ValueString(), @@ -143,7 +143,7 @@ func (r *userResource) Update(ctx context.Context, req resource.UpdateRequest, r return } - input := api.UserUpdateInput{ + input := platform.UserUpdateInput{ Name: plan.Name.ValueStringPointer(), DisplayName: plan.DisplayName.ValueStringPointer(), Key: plan.Key.ValueInt64(), diff --git a/internal/resources/user_group.go b/internal/resources/user_group.go index 9a1abc3e..c55f66df 100644 --- a/internal/resources/user_group.go +++ b/internal/resources/user_group.go @@ -10,7 +10,7 @@ import ( "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" "github.com/stacklet/terraform-provider-stacklet/internal/errors" "github.com/stacklet/terraform-provider-stacklet/internal/models" ) @@ -80,7 +80,7 @@ func (r *userGroupResource) Create(ctx context.Context, req resource.CreateReque return } - input := api.UserGroupCreateInput{ + input := platform.UserGroupCreateInput{ Name: plan.Name.ValueString(), DisplayName: plan.DisplayName.ValueStringPointer(), } @@ -119,7 +119,7 @@ func (r *userGroupResource) Update(ctx context.Context, req resource.UpdateReque return } - input := api.UserGroupUpdateInput{ + input := platform.UserGroupUpdateInput{ ID: plan.ID.ValueString(), Name: plan.Name.ValueStringPointer(), DisplayName: plan.DisplayName.ValueStringPointer(), diff --git a/internal/schemavalidate/cloud_provider.go b/internal/schemavalidate/cloud_provider.go index 5915d4b2..b4156327 100644 --- a/internal/schemavalidate/cloud_provider.go +++ b/internal/schemavalidate/cloud_provider.go @@ -6,13 +6,13 @@ import ( "github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator" "github.com/hashicorp/terraform-plugin-framework/schema/validator" - "github.com/stacklet/terraform-provider-stacklet/internal/api" + "github.com/stacklet/terraform-provider-stacklet/internal/api/platform" ) // OneOfCloudProviders is a validator that checks that value is one of the supported cloud providers. func OneOfCloudProviders() validator.String { - allProviders := make([]string, len(api.CLOUD_PROVIDERS)) - for i, provider := range api.CLOUD_PROVIDERS { + allProviders := make([]string, len(platform.CLOUD_PROVIDERS)) + for i, provider := range platform.CLOUD_PROVIDERS { allProviders[i] = string(provider) } return stringvalidator.OneOf(allProviders...)