From 0306b387a219c1a091308384ed821b6ee691de5d Mon Sep 17 00:00:00 2001 From: Siddhu Warrier Date: Mon, 28 Oct 2024 07:03:14 +0000 Subject: [PATCH] feat(lh-86965): add msp_managed_tenant data source (#145) * feat(lh-86965): add msp_managed_tenant data source Add a datasource to read an MSP managed tenant * Run Acc test on branch, revert this before merge * docs(lh-86965): add documentation * fix * refactor(lh-86965): address Tal's comments * Fix * chore(lh-86965): run acceptane test only on merge to main --- .github/workflows/ci.yml | 1 + README.md | 8 +- client/client.go | 8 +- client/internal/url/url.go | 6 +- client/msp/tenants/create.go | 2 +- client/msp/tenants/models.go | 11 +++ client/msp/tenants/read.go | 17 +++- client/msp/tenants/read_test.go | 58 ++++++++++- docs/data-sources/cdfmc.md | 2 +- docs/data-sources/msp_managed_tenant.md | 26 +++++ provider/.github-action.env | 4 + provider/.gitignore | 1 + .../data-sources/msp/tenants/README.md | 11 +++ .../data-sources/msp/tenants/api_token.txt | 1 + .../examples/data-sources/msp/tenants/main.tf | 7 ++ .../data-sources/msp/tenants/providers.tf | 12 +++ provider/internal/acctest/acctest.go | 39 +++++++- provider/internal/acctest/environment.go | 16 +++ provider/internal/cdfmc/data_source.go | 2 +- .../internal/msp/msp_tenant/data_source.go | 99 +++++++++++++++++++ .../msp/msp_tenant/data_source_test.go | 45 +++++++++ provider/internal/msp/msp_tenant/models.go | 18 ++++ provider/internal/msp/msp_tenant/resource.go | 10 +- provider/internal/provider/provider.go | 3 +- 24 files changed, 384 insertions(+), 23 deletions(-) create mode 100644 docs/data-sources/msp_managed_tenant.md create mode 100644 provider/examples/data-sources/msp/tenants/README.md create mode 100644 provider/examples/data-sources/msp/tenants/api_token.txt create mode 100644 provider/examples/data-sources/msp/tenants/main.tf create mode 100644 provider/examples/data-sources/msp/tenants/providers.tf create mode 100644 provider/internal/msp/msp_tenant/data_source.go create mode 100644 provider/internal/msp/msp_tenant/data_source_test.go create mode 100644 provider/internal/msp/msp_tenant/models.go diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8ee815dd..88fe8ca0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -124,6 +124,7 @@ jobs: - run: cat .github-action.env >> $GITHUB_ENV # https://docs.github.com/en/actions/learn-github-actions/variables#default-environment-variables - env: TF_ACC: "1" + ACC_TEST_CISCO_CDO_MSP_API_TOKEN: ${{ secrets.ACC_TEST_CISCO_CDO_MSP_API_TOKEN }} ACC_TEST_CISCO_CDO_API_TOKEN: ${{ secrets.ACC_TEST_CISCO_CDO_API_TOKEN }} IOS_RESOURCE_PASSWORD: ${{ secrets.IOS_RESOURCE_PASSWORD }} ASA_RESOURCE_SDC_PASSWORD: ${{ secrets.ASA_RESOURCE_SDC_PASSWORD }} diff --git a/README.md b/README.md index 32bef021..66685d0a 100644 --- a/README.md +++ b/README.md @@ -65,9 +65,15 @@ ACC_TEST_CISCO_CDO_API_TOKEN= make testacc ``` ## Linting + +Ensure you have golangci-lint installed: +``` +curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.61.0 +``` + Run following command in the `client` or `provider` directory. ```bash -golangci-lint run +~/go/bin/golangci-lint run #change ~/go/bin to your $GOBIN ``` ## Running Examples diff --git a/client/client.go b/client/client.go index 98e5e6b8..67ecbdbe 100644 --- a/client/client.go +++ b/client/client.go @@ -279,6 +279,10 @@ func (c *Client) CreateTenantUsingMspPortal(ctx context.Context, createInput ten return tenants.Create(ctx, c.client, createInput) } -func (c *Client) ReadMspManagedTenant(ctx context.Context, readByUidInput tenants.ReadByUidInput) (*tenants.MspTenantOutput, error) { - return tenants.Read(ctx, c.client, readByUidInput) +func (c *Client) ReadMspManagedTenantByUid(ctx context.Context, readByUidInput tenants.ReadByUidInput) (*tenants.MspTenantOutput, error) { + return tenants.ReadByUid(ctx, c.client, readByUidInput) +} + +func (c *Client) FindMspManagedTenantByName(ctx context.Context, readByNameInput tenants.ReadByNameInput) (*tenants.MspTenantsOutput, error) { + return tenants.ReadByName(ctx, c.client, readByNameInput) } diff --git a/client/internal/url/url.go b/client/internal/url/url.go index c77d841e..b3ebacbc 100644 --- a/client/internal/url/url.go +++ b/client/internal/url/url.go @@ -210,6 +210,10 @@ func CreateMspManagedTenant(baseUrl string) string { return fmt.Sprintf("%s/api/rest/v1/msp/tenants/create", baseUrl) } -func ReadMspManagedTenant(baseUrl string, tenantUid string) string { +func ReadMspManagedTenantByUid(baseUrl string, tenantUid string) string { return fmt.Sprintf("%s/api/rest/v1/msp/tenants/%s", baseUrl, tenantUid) } + +func FindMspManagedTenantsByName(baseUrl string, tenantName string) string { + return fmt.Sprintf("%s/api/rest/v1/msp/tenants?q=name:%s", baseUrl, tenantName) +} diff --git a/client/msp/tenants/create.go b/client/msp/tenants/create.go index 961ffe45..ee68605f 100644 --- a/client/msp/tenants/create.go +++ b/client/msp/tenants/create.go @@ -36,7 +36,7 @@ func Create(ctx context.Context, client http.Client, createInp MspCreateTenantIn } } - readOut, err := Read(ctx, client, ReadByUidInput{Uid: transaction.EntityUid}) + readOut, err := ReadByUid(ctx, client, ReadByUidInput{Uid: transaction.EntityUid}) client.Logger.Println("Created tenant for CDO") if err == nil { return readOut, nil diff --git a/client/msp/tenants/models.go b/client/msp/tenants/models.go index eb812393..cebb1df9 100644 --- a/client/msp/tenants/models.go +++ b/client/msp/tenants/models.go @@ -12,6 +12,17 @@ type MspTenantOutput struct { Region string `json:"region"` } +type MspTenantsOutput struct { + Count int `json:"count"` + Limit int `json:"limit"` + Offset int `json:"offset"` + Items []MspTenantOutput `json:"items"` +} + type ReadByUidInput struct { Uid string `json:"uid"` } + +type ReadByNameInput struct { + Name string `json:"name"` +} diff --git a/client/msp/tenants/read.go b/client/msp/tenants/read.go index ef283074..d24ff418 100644 --- a/client/msp/tenants/read.go +++ b/client/msp/tenants/read.go @@ -6,10 +6,10 @@ import ( "github.com/CiscoDevnet/terraform-provider-cdo/go-client/internal/url" ) -func Read(ctx context.Context, client http.Client, readInp ReadByUidInput) (*MspTenantOutput, error) { +func ReadByUid(ctx context.Context, client http.Client, readInp ReadByUidInput) (*MspTenantOutput, error) { client.Logger.Println("reading tenant by UID " + readInp.Uid) - readUrl := url.ReadMspManagedTenant(client.BaseUrl(), readInp.Uid) + readUrl := url.ReadMspManagedTenantByUid(client.BaseUrl(), readInp.Uid) req := client.NewGet(ctx, readUrl) var outp MspTenantOutput @@ -19,3 +19,16 @@ func Read(ctx context.Context, client http.Client, readInp ReadByUidInput) (*Msp return &outp, nil } + +func ReadByName(ctx context.Context, client http.Client, readInp ReadByNameInput) (*MspTenantsOutput, error) { + client.Logger.Println("reading tenant by name " + readInp.Name) + findByNameUrl := url.FindMspManagedTenantsByName(client.BaseUrl(), readInp.Name) + req := client.NewGet(ctx, findByNameUrl) + + var outp MspTenantsOutput + if err := req.Send(&outp); err != nil { + return nil, err + } + + return &outp, nil +} diff --git a/client/msp/tenants/read_test.go b/client/msp/tenants/read_test.go index 6fd76209..629bb827 100644 --- a/client/msp/tenants/read_test.go +++ b/client/msp/tenants/read_test.go @@ -30,7 +30,7 @@ func TestRead(t *testing.T) { "/api/rest/v1/msp/tenants/"+entityUid, httpmock.NewJsonResponderOrPanic(200, tenantResponse), ) - actual, err := tenants.Read(context.Background(), *http.MustNewWithConfig(baseUrl, "valid_token", 0, 0, time.Minute), tenants.ReadByUidInput{ + actual, err := tenants.ReadByUid(context.Background(), *http.MustNewWithConfig(baseUrl, "valid_token", 0, 0, time.Minute), tenants.ReadByUidInput{ Uid: entityUid, }) @@ -46,11 +46,65 @@ func TestRead(t *testing.T) { "/api/rest/v1/msp/tenants/"+entityUid, httpmock.NewJsonResponderOrPanic(404, "Not found"), ) - actual, err := tenants.Read(context.Background(), *http.MustNewWithConfig(baseUrl, "valid_token", 0, 0, time.Minute), tenants.ReadByUidInput{ + actual, err := tenants.ReadByUid(context.Background(), *http.MustNewWithConfig(baseUrl, "valid_token", 0, 0, time.Minute), tenants.ReadByUidInput{ Uid: entityUid, }) assert.Nil(t, actual) assert.ErrorContains(t, err, "Not Found") }) + + t.Run("Find tenant by name", func(t *testing.T) { + httpmock.Reset() + var tenantName = "test-tenant" + var expectedTenant = tenants.MspTenantOutput{ + Uid: uuid.New().String(), + Name: "test-tenant", + DisplayName: "Pineapple Crushers Inc", + Region: "STAGING", + } + var tenantResponse = tenants.MspTenantsOutput{ + Count: 1, + Limit: 50, + Offset: 0, + Items: []tenants.MspTenantOutput{expectedTenant}, + } + + httpmock.RegisterResponder( + netHttp.MethodGet, + "/api/rest/v1/msp/tenants?q=name%3A"+tenantName, + httpmock.NewJsonResponderOrPanic(200, tenantResponse), + ) + actual, err := tenants.ReadByName(context.Background(), *http.MustNewWithConfig(baseUrl, "valid_token", 0, 0, time.Minute), tenants.ReadByNameInput{ + Name: tenantName, + }) + + assert.NotNil(t, actual) + assert.Equal(t, *actual, tenantResponse) + assert.NoError(t, err) + }) + + t.Run("Find no tenants by name", func(t *testing.T) { + httpmock.Reset() + var tenantName = "test-tenant" + var tenantResponse = tenants.MspTenantsOutput{ + Count: 0, + Limit: 50, + Offset: 0, + Items: []tenants.MspTenantOutput{}, + } + + httpmock.RegisterResponder( + netHttp.MethodGet, + "/api/rest/v1/msp/tenants?q=name%3A"+tenantName, + httpmock.NewJsonResponderOrPanic(200, tenantResponse), + ) + actual, err := tenants.ReadByName(context.Background(), *http.MustNewWithConfig(baseUrl, "valid_token", 0, 0, time.Minute), tenants.ReadByNameInput{ + Name: tenantName, + }) + + assert.NotNil(t, actual) + assert.Equal(t, *actual, tenantResponse) + assert.NoError(t, err) + }) } diff --git a/docs/data-sources/cdfmc.md b/docs/data-sources/cdfmc.md index 93c6df9f..0e2127cc 100644 --- a/docs/data-sources/cdfmc.md +++ b/docs/data-sources/cdfmc.md @@ -18,6 +18,6 @@ Use this data source to get information on the cloud-delivered FMC in your tenan ### Read-Only - `domain_uuid` (String) The domain UUID of the cdFMC. -- `hostname` (String) Name of the tenant. +- `hostname` (String) Name of the cdFMC. - `id` (String) Universally unique identifier for the cdFMC. - `software_version` (String) Software version of the cdFMC. diff --git a/docs/data-sources/msp_managed_tenant.md b/docs/data-sources/msp_managed_tenant.md new file mode 100644 index 00000000..1079d2e3 --- /dev/null +++ b/docs/data-sources/msp_managed_tenant.md @@ -0,0 +1,26 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "cdo_msp_managed_tenant Data Source - cdo" +subcategory: "" +description: |- + Use this data source to get information on the cloud-delivered FMC in your tenant. +--- + +# cdo_msp_managed_tenant (Data Source) + +Use this data source to get information on the cloud-delivered FMC in your tenant. + + + + +## Schema + +### Required + +- `name` (String) Name of the tenant + +### Read-Only + +- `display_name` (String) Display name of the tenant +- `id` (String) Universally unique identifier of the tenant +- `region` (String) CDO region in which the tenant is created. This is the same region as the region of the MSP portal. diff --git a/provider/.github-action.env b/provider/.github-action.env index 3a9332a9..43377302 100644 --- a/provider/.github-action.env +++ b/provider/.github-action.env @@ -61,4 +61,8 @@ DUO_ADMIN_PANEL_RESOURCE_NEW_NAME=new-didi-duo DUO_ADMIN_PANEL_RESOURCE_HOST=api-5ee7adc8.duosecurity.com DUO_ADMIN_PANEL_RESOURCE_TAGS=tag1,tag2,tag3 TENANT_SETTINGS_TENANT_UID=d4200207-e3cc-4495-ad1e-e0bbedf44fe0 +MSP_TENANT_NAME=CDO_terraform-provider-cdo +MSP_TENANT_DISPLAY_NAME=terraform-provider-cdo +MSP_TENANT_REGION=CI +MSP_TENANT_ID=ae98d25f-1089-4286-a3c5-505dcb4431a2 TF_LOG=DEBUG diff --git a/provider/.gitignore b/provider/.gitignore index a54d4166..6ff4d33e 100644 --- a/provider/.gitignore +++ b/provider/.gitignore @@ -32,3 +32,4 @@ website/vendor # Keep windows files with windows line endings *.winfile eol=crlf +**/.terraform.lock.hcl diff --git a/provider/examples/data-sources/msp/tenants/README.md b/provider/examples/data-sources/msp/tenants/README.md new file mode 100644 index 00000000..9429d2a3 --- /dev/null +++ b/provider/examples/data-sources/msp/tenants/README.md @@ -0,0 +1,11 @@ +# MSP tenants Example + +## Pre-requisites + +You need access to an MSP Portal, and API token for the MSP portal. + +## Usage +- Modify `terraform.tfvars` and `providers.tf` accordingly. +- Paste CDO API token for an MSP portal into `api_token.txt` + - see https://docs.defenseorchestrator.com/#!c-api-tokens.html for how to generate this. +- Specify the name of a tenant managed by the MSP Portal. You can get the tenant name by going to Settings in the MSP portal. \ No newline at end of file diff --git a/provider/examples/data-sources/msp/tenants/api_token.txt b/provider/examples/data-sources/msp/tenants/api_token.txt new file mode 100644 index 00000000..6da45083 --- /dev/null +++ b/provider/examples/data-sources/msp/tenants/api_token.txt @@ -0,0 +1 @@ +Paste your API token here \ No newline at end of file diff --git a/provider/examples/data-sources/msp/tenants/main.tf b/provider/examples/data-sources/msp/tenants/main.tf new file mode 100644 index 00000000..9c8fca30 --- /dev/null +++ b/provider/examples/data-sources/msp/tenants/main.tf @@ -0,0 +1,7 @@ +data "cdo_msp_managed_tenant" "tenant" { + name = "CDO_tenant-name" +} + +output "tenant_display_name" { + value = data.cdo_msp_managed_tenant.tenant.display_name +} \ No newline at end of file diff --git a/provider/examples/data-sources/msp/tenants/providers.tf b/provider/examples/data-sources/msp/tenants/providers.tf new file mode 100644 index 00000000..271024b9 --- /dev/null +++ b/provider/examples/data-sources/msp/tenants/providers.tf @@ -0,0 +1,12 @@ +terraform { + required_providers { + cdo = { + source = "CiscoDevnet/cdo" + } + } +} + +provider "cdo" { + base_url = "https://staging.dev.lockhart.io" + api_token = file("${path.module}/api_token.txt") +} diff --git a/provider/internal/acctest/acctest.go b/provider/internal/acctest/acctest.go index 43ca749e..367e3fa9 100644 --- a/provider/internal/acctest/acctest.go +++ b/provider/internal/acctest/acctest.go @@ -12,8 +12,10 @@ import ( ) const ( - apiTokenEnvName = "ACC_TEST_CISCO_CDO_API_TOKEN" - apiTokenSecretName = "staging-terraform-provider-cdo-acceptance-test-api-token" + apiTokenEnvName = "ACC_TEST_CISCO_CDO_API_TOKEN" + mspApiTokenEnvName = "ACC_TEST_CISCO_CDO_MSP_API_TOKEN" + apiTokenSecretName = "staging-terraform-provider-cdo-acceptance-test-api-token" + mspApiTokenSecretName = "staging-terraform-provider-cdo-acceptance-test-api-token" ) var cdoSecretManager = NewCdoSecretManager("us-west-2") @@ -32,12 +34,30 @@ func GetApiToken() (string, error) { return "", fmt.Errorf("failed to retrieve api token from environment variable and secret manager.\nenvironment variable name=%s\nsecret manager secret token name=%s\nplease set one of them.\ncause=%v", apiTokenEnvName, apiTokenSecretName, err) } +func GetMspApiToken() (string, error) { + tokenFromEnv, ok := os.LookupEnv(mspApiTokenEnvName) + if ok { + return tokenFromEnv, nil + } + + tokenFromSecretManager, err := cdoSecretManager.getCurrentSecretValue(mspApiTokenEnvName) + if err == nil { + return tokenFromSecretManager, nil + } + + return "", fmt.Errorf("failed to retrieve api token from environment variable and secret manager.\nenvironment variable name=%s\nsecret manager secret token name=%s\nplease set one of them.\ncause=%v", mspApiTokenEnvName, mspApiTokenSecretName, err) +} + func PreCheckFunc(t *testing.T) func() { return func() { _, err := GetApiToken() + _, mspErr := GetMspApiToken() if err != nil { t.Fatalf("Precheck failed, cause=%v", err) } + if mspErr != nil { + t.Fatalf("Precheck failed, cause=%v", mspErr) + } } } @@ -56,6 +76,21 @@ func ProviderConfig() string { `, token) } +func MspProviderConfig() string { + mspToken, err := GetMspApiToken() + if err != nil { + panic(fmt.Errorf("failed to retrieve api token, cause=%w", err)) + } + + return fmt.Sprintf(` + provider "cdo" { + api_token = "%s" + base_url = "https://ci.manage.security.cisco.com" + } + // New line + `, mspToken) +} + // ProtoV6ProviderFactories are used to instantiate a provider during // acceptance testing. The factory function will be invoked for every Terraform // CLI command executed to create a provider server to which the CLI can diff --git a/provider/internal/acctest/environment.go b/provider/internal/acctest/environment.go index ab67e09d..c14e33f4 100644 --- a/provider/internal/acctest/environment.go +++ b/provider/internal/acctest/environment.go @@ -316,6 +316,22 @@ func (e *env) TenantSettingsTenantUid() string { return e.mustGetString("TENANT_SETTINGS_TENANT_UID") } +func (e *env) MspTenantName() string { + return e.mustGetString("MSP_TENANT_NAME") +} + +func (e *env) MspTenantDisplayName() string { + return e.mustGetString("MSP_TENANT_DISPLAY_NAME") +} + +func (e *env) MspTenantId() string { + return e.mustGetString("MSP_TENANT_ID") +} + +func (e *env) MspTenantRegion() string { + return e.mustGetString("MSP_TENANT_REGION") +} + func (e *env) mustGetString(envName string) string { value, ok := os.LookupEnv(envName) if ok { diff --git a/provider/internal/cdfmc/data_source.go b/provider/internal/cdfmc/data_source.go index 86bca4bb..6547f3b7 100644 --- a/provider/internal/cdfmc/data_source.go +++ b/provider/internal/cdfmc/data_source.go @@ -39,7 +39,7 @@ func (d *DataSource) Schema(ctx context.Context, req datasource.SchemaRequest, r Computed: true, }, "hostname": schema.StringAttribute{ - MarkdownDescription: "Name of the tenant.", + MarkdownDescription: "Name of the cdFMC.", Computed: true, }, "software_version": schema.StringAttribute{ diff --git a/provider/internal/msp/msp_tenant/data_source.go b/provider/internal/msp/msp_tenant/data_source.go new file mode 100644 index 00000000..18bee841 --- /dev/null +++ b/provider/internal/msp/msp_tenant/data_source.go @@ -0,0 +1,99 @@ +package msp_tenant + +import ( + "context" + "fmt" + cdoClient "github.com/CiscoDevnet/terraform-provider-cdo/go-client" + "github.com/CiscoDevnet/terraform-provider-cdo/go-client/msp/tenants" + "github.com/hashicorp/terraform-plugin-framework/datasource" + "github.com/hashicorp/terraform-plugin-framework/datasource/schema" + "github.com/hashicorp/terraform-plugin-framework/types" + "github.com/hashicorp/terraform-plugin-log/tflog" +) + +func NewTenantDataSource() datasource.DataSource { + return &DataSource{} +} + +type DataSource struct { + client *cdoClient.Client +} + +func (d *DataSource) Metadata(ctx context.Context, request datasource.MetadataRequest, response *datasource.MetadataResponse) { + response.TypeName = request.ProviderTypeName + "_msp_managed_tenant" +} + +func (d *DataSource) Schema(ctx context.Context, request datasource.SchemaRequest, response *datasource.SchemaResponse) { + response.Schema = schema.Schema{ + MarkdownDescription: "Use this data source to get information on the cloud-delivered FMC in your tenant.", + Attributes: map[string]schema.Attribute{ + "id": schema.StringAttribute{ + MarkdownDescription: "Universally unique identifier of the tenant", + Computed: true, + }, + "name": schema.StringAttribute{ + MarkdownDescription: "Name of the tenant", + Required: true, + }, + "display_name": schema.StringAttribute{ + MarkdownDescription: "Display name of the tenant", + Computed: true, + }, + "region": schema.StringAttribute{ + MarkdownDescription: "CDO region in which the tenant is created. This is the same region as the region of the MSP portal.", + Computed: true, + }, + }, + } +} + +func (d *DataSource) Read(ctx context.Context, request datasource.ReadRequest, response *datasource.ReadResponse) { + var planData TenantDatasourceModel + + // Read Terraform configuration data into the model + response.Diagnostics.Append(request.Config.Get(ctx, &planData)...) + if response.Diagnostics.HasError() { + return + } + + mspManagedTenants, err := d.client.FindMspManagedTenantByName(ctx, tenants.ReadByNameInput{ + Name: planData.Name.ValueString(), + }) + if err != nil { + response.Diagnostics.AddError("Failed to read MSP Managed Tenant", err.Error()) + return + } + if mspManagedTenants.Count != 1 { + response.Diagnostics.AddError("Cannot find MSP managed tenant by name "+planData.Name.ValueString(), fmt.Sprintf("Found %d tenants by name %s", mspManagedTenants.Count, planData.Name.ValueString())) + } + + tflog.Debug(ctx, fmt.Sprintf("fuckity shit: %v", mspManagedTenants)) + + mspManagedTenant := mspManagedTenants.Items[0] + planData.Id = types.StringValue(mspManagedTenant.Uid) + planData.Name = types.StringValue(mspManagedTenant.Name) + planData.DisplayName = types.StringValue(mspManagedTenant.DisplayName) + planData.Region = types.StringValue(mspManagedTenant.Region) + + // Save data into Terraform state + response.Diagnostics.Append(response.State.Set(ctx, &planData)...) +} + +func (d *DataSource) Configure(ctx context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) { + if req.ProviderData == nil { + return + } + + client, ok := req.ProviderData.(*cdoClient.Client) + + if !ok { + resp.Diagnostics.AddError( + "Unexpected Data Source Configure Type", + fmt.Sprintf("Expected *cdoClient.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData), + ) + + return + } + + d.client = client +} diff --git a/provider/internal/msp/msp_tenant/data_source_test.go b/provider/internal/msp/msp_tenant/data_source_test.go new file mode 100644 index 00000000..06bf9ea5 --- /dev/null +++ b/provider/internal/msp/msp_tenant/data_source_test.go @@ -0,0 +1,45 @@ +package msp_tenant_test + +import ( + "github.com/CiscoDevnet/terraform-provider-cdo/internal/acctest" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "testing" +) + +var testMspTenantDataSource = struct { + Name string + DisplayName string + Id string + Region string +}{ + Name: acctest.Env.MspTenantName(), + DisplayName: acctest.Env.MspTenantDisplayName(), + Id: acctest.Env.MspTenantId(), + Region: acctest.Env.MspTenantRegion(), +} + +const testMspTenantDataSourceTemplate = ` +data "cdo_msp_managed_tenant" "test" { + name = "{{.Name}}" +}` + +var testMspTenantDataSourceConfig = acctest.MustParseTemplate(testMspTenantDataSourceTemplate, testMspTenantDataSource) + +func TestAccMspTenantDataSource(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: acctest.PreCheckFunc(t), + ProtoV6ProviderFactories: acctest.ProtoV6ProviderFactories, + Steps: []resource.TestStep{ + // Read testing + { + Config: acctest.MspProviderConfig() + testMspTenantDataSourceConfig, + Check: resource.ComposeAggregateTestCheckFunc( + resource.TestCheckResourceAttr("data.cdo_msp_managed_tenant.test", "name", testMspTenantDataSource.Name), + resource.TestCheckResourceAttr("data.cdo_msp_managed_tenant.test", "display_name", testMspTenantDataSource.DisplayName), + resource.TestCheckResourceAttr("data.cdo_msp_managed_tenant.test", "id", testMspTenantDataSource.Id), + resource.TestCheckResourceAttr("data.cdo_msp_managed_tenant.test", "region", testMspTenantDataSource.Region), + ), + }, + }, + }) +} diff --git a/provider/internal/msp/msp_tenant/models.go b/provider/internal/msp/msp_tenant/models.go new file mode 100644 index 00000000..dbbca64e --- /dev/null +++ b/provider/internal/msp/msp_tenant/models.go @@ -0,0 +1,18 @@ +package msp_tenant + +import "github.com/hashicorp/terraform-plugin-framework/types" + +type TenantResourceModel struct { + Id types.String `tfsdk:"id"` + Name types.String `tfsdk:"name"` + DisplayName types.String `tfsdk:"display_name"` + GeneratedName types.String `tfsdk:"generated_name"` + Region types.String `tfsdk:"region"` +} + +type TenantDatasourceModel struct { + Id types.String `tfsdk:"id"` + Name types.String `tfsdk:"name"` + DisplayName types.String `tfsdk:"display_name"` + Region types.String `tfsdk:"region"` +} diff --git a/provider/internal/msp/msp_tenant/resource.go b/provider/internal/msp/msp_tenant/resource.go index 55a25815..2b7dca76 100644 --- a/provider/internal/msp/msp_tenant/resource.go +++ b/provider/internal/msp/msp_tenant/resource.go @@ -21,14 +21,6 @@ type TenantResource struct { client *cdoClient.Client } -type TenantResourceModel struct { - Id types.String `tfsdk:"id"` - Name types.String `tfsdk:"name"` - DisplayName types.String `tfsdk:"display_name"` - GeneratedName types.String `tfsdk:"generated_name"` - Region types.String `tfsdk:"region"` -} - func (*TenantResource) Metadata(ctx context.Context, request resource.MetadataRequest, response *resource.MetadataResponse) { response.TypeName = request.ProviderTypeName + "_msp_managed_tenant" } @@ -135,7 +127,7 @@ func (t *TenantResource) Read(ctx context.Context, request resource.ReadRequest, readInp := tenants.ReadByUidInput{ Uid: stateData.Id.ValueString(), } - tenantReadOutp, err := t.client.ReadMspManagedTenant(ctx, readInp) + tenantReadOutp, err := t.client.ReadMspManagedTenantByUid(ctx, readInp) if err != nil { if util.Is404Error(err) { diff --git a/provider/internal/provider/provider.go b/provider/internal/provider/provider.go index 484ba1a1..fba9d64e 100644 --- a/provider/internal/provider/provider.go +++ b/provider/internal/provider/provider.go @@ -77,7 +77,7 @@ func (p *CdoProvider) Schema(ctx context.Context, req provider.SchemaRequest, re MarkdownDescription: "The base CDO URL. This is the URL you enter when logging into your CDO account.", Required: true, Validators: []validator.String{ - stringvalidator.OneOf("https://www.defenseorchestrator.com", "https://www.defenseorchestrator.eu", "https://apj.cdo.cisco.com", "https://staging.dev.lockhart.io", "https://ci.dev.lockhart.io", "https://scale.dev.lockhart.io", "http://localhost:9000", "https://aus.cdo.cisco.com", "https://in.cdo.cisco.com"), + stringvalidator.OneOf("https://www.defenseorchestrator.com", "https://us.manage.security.cisco.com", "https://www.defenseorchestrator.eu", "https://eu.manage.security.cisco.com", "https://apj.cdo.cisco.com", "https://apj.manage.security.cisco.com", "https://staging.dev.lockhart.io", "https://staging.manage.security.cisco.com", "https://ci.dev.lockhart.io", "https://ci.manage.security.cisco.com", "https://scale.dev.lockhart.io", "https://scale.manage.security.cisco.com", "http://localhost:9000", "https://aus.cdo.cisco.com", "https://aus.manage.security.cisco.com", "https://in.cdo.cisco.com", "https://aus.manage.security.cisco.com"), }, }, }, @@ -187,6 +187,7 @@ func (p *CdoProvider) DataSources(ctx context.Context) []func() datasource.DataS tenant.NewDataSource, cdfmc.NewDataSource, tenantsettings.NewTenantSettingsDataSource, + msp_tenant.NewTenantDataSource, } }