Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Completeness changes / generation preparation for DevCenter #3152

Merged
merged 11 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions config/resources/devcenter.hcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright (c) HashiCorp, Inc.
# SPDX-License-Identifier: MPL-2.0

/*
service "DevCenter" {
terraform_package = "devcenter"

api "2023-04-01" {
package "DevCenters" {
definition "dev_center" {
id = "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.DevCenter/devCenters/{devCenterName}"
display_name = "Dev Center"
website_subcategory = "Dev Center"
description = "Manages a Dev Center"
}
}

package "Projects" {
definition "dev_center_project" {
id = "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.DevCenter/projects/{projectName}"
display_name = "Dev Center Project"
website_subcategory = "Dev Center Project"
description = "Manages a Dev Center Project"
}
}
}
}
*/
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func (d directAssignmentTransformIdentitySystemAndUserAssignedMap) optionalFlatt
if err != nil {
return fmt.Errorf("flattening SystemAndUserAssigned Identity: %%+v", err)
}
%[3]s = %[1]s
%[3]s = *%[1]s
`, outputVariableName, inputAssignment, outputAssignment)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ func TestDirectAssignment_Read_Identity_SystemAndUserAssignedMap_RequiredToOptio
if err != nil {
return fmt.Errorf("flattening SystemAndUserAssigned Identity: %%+v", err)
}
output.Identity = identity
output.Identity = *identity
`),
},
}
Expand Down Expand Up @@ -454,7 +454,7 @@ func TestDirectAssignment_Read_Identity_SystemAndUserAssignedMap_OptionalToOptio
if err != nil {
return fmt.Errorf("flattening SystemAndUserAssigned Identity: %%+v", err)
}
output.Identity = identity
output.Identity = *identity
`),
},
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package dataworkarounds

import (
"fmt"
"github.com/hashicorp/pandora/tools/importer-rest-api-specs/models"
)

// This workaround fixes an issue in DevCenter where the field `DevCenterUri` is not
// marked as ReadOnly, meaning that it's surfaced as an Optional field rather than
// being Computed.
tombuildsstuff marked this conversation as resolved.
Show resolved Hide resolved
//
// PR: https://github.com/Azure/azure-rest-api-specs/pull/26189
// Additional: https://github.com/hashicorp/pandora/pull/2675#issuecomment-1759115231

var _ workaround = workaroundDevCenter26189{}

type workaroundDevCenter26189 struct {
}

func (workaroundDevCenter26189) IsApplicable(apiDefinition *models.AzureApiDefinition) bool {
return apiDefinition.ServiceName == "DevCenter" && apiDefinition.ApiVersion == "2023-04-01"
}

func (workaroundDevCenter26189) Name() string {
return "DevCenter / 26189"
}

func (workaroundDevCenter26189) Process(apiDefinition models.AzureApiDefinition) (*models.AzureApiDefinition, error) {
// First we need to patch the DevCenters issue (marking DevCenterUri as required)
devCentersResource, ok := apiDefinition.Resources["DevCenters"]
if !ok {
return nil, fmt.Errorf("expected a Resource named `DevCenters` but didn't get one")
}

devCenterModel, ok := devCentersResource.Models["DevCenterProperties"]
if !ok {
return nil, fmt.Errorf("expected a Model named `DevCenterProperties` but didn't get one")
}
devCenterField, ok := devCenterModel.Fields["DevCenterUri"]
if !ok {
return nil, fmt.Errorf("expected a Field named `DevCenterUri` but didn't get one")
}
devCenterField.ReadOnly = true

devCenterModel.Fields["DevCenterUri"] = devCenterField
devCentersResource.Models["DevCenterProperties"] = devCenterModel
apiDefinition.Resources["DevCenters"] = devCentersResource

// Next we need to do the same thing for Projects to make the `DevCenterId` field Required
// and make `DevCenterUri` computed
projectsResource, ok := apiDefinition.Resources["Projects"]
if !ok {
return nil, fmt.Errorf("expected a Resource named `Projects` but didn't get one")
}
projectModel, ok := projectsResource.Models["ProjectProperties"]
if !ok {
return nil, fmt.Errorf("expected a Model named `ProjectProperties` but didn't get one")
}
projectDevCenterIdField, ok := projectModel.Fields["DevCenterId"]
if !ok {
return nil, fmt.Errorf("expected a Field named `DevCenterId` but didn't get one")
}
projectDevCenterIdField.Required = true
projectModel.Fields["DevCenterId"] = projectDevCenterIdField

projectDevCenterUriField, ok := projectModel.Fields["DevCenterUri"]
if !ok {
return nil, fmt.Errorf("expected a Field named `DevCenterUri` but didn't get one")
}
projectDevCenterUriField.ReadOnly = true
projectModel.Fields["DevCenterUri"] = projectDevCenterUriField

projectsResource.Models["ProjectProperties"] = projectModel
apiDefinition.Resources["Projects"] = projectsResource

return &apiDefinition, nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var workarounds = []workaround{
workaroundBatch21291{},
workaroundContainerService21394{},
workaroundDataFactory23013{},
workaroundDevCenter26189{},
workaroundLoadTest20961{},
workaroundRedis22407{},
workaroundMachineLearning25142{},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package processors

import "strings"
import (
"strings"
)

var _ FieldNameProcessor = fieldNameRemoveResourcePrefix{}

Expand All @@ -9,6 +11,14 @@ type fieldNameRemoveResourcePrefix struct{}
func (fieldNameRemoveResourcePrefix) ProcessField(fieldName string, metadata FieldMetadata) (*string, error) {
if strings.HasPrefix(fieldName, metadata.TerraformDetails.ResourceName) {
updatedName := strings.Replace(fieldName, metadata.TerraformDetails.ResourceName, "", 1)

// However `Uri` is not a great name for the field, and whilst `DataPlaneUri` or `ServiceUri`
// could make sense, this can create inconsistencies within the Service Package with different
// resources exposing different names for attributes - as such there we use the original name.
if strings.EqualFold(updatedName, "Uri") {
return nil, nil
}

return &updatedName, nil
}
return nil, nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type testDependencies struct {
// NOTE: use the Set methods
needsApplicationInsights bool
needsClientConfig bool
needsDevCenter bool
needsEdgeZone bool
needsKeyVault bool
needsKeyVaultAccessPolicy bool
Expand Down Expand Up @@ -45,6 +46,13 @@ func (d *testDependencies) setNeedsClientConfig() {
d.needsClientConfig = true
}

func (d *testDependencies) setNeedsDevCenter() {
d.setNeedsResourceGroup()
d.needsDevCenter = true

d.variables.needsRandomString = true
}

func (d *testDependencies) setNeedsEdgeZones() {
d.needsEdgeZone = true

Expand Down Expand Up @@ -151,6 +159,7 @@ type dependencyDefinition struct {
func DetermineDependencies(field, providerPrefix string, dependencies *testDependencies) (*string, *testDependencies, error) {
dependencyMapping := map[string]dependencyDefinition{
"application_insights_id": {dependencies.setNeedsApplicationInsights, fmt.Sprintf("%s_application_insights.test.id", providerPrefix)},
"dev_center_id": {dependencies.setNeedsDevCenter, fmt.Sprintf("azurerm_dev_center.test.id")},
"key_vault_id": {dependencies.setNeedsKeyVault, fmt.Sprintf("%s_key_vault.test.id", providerPrefix)},
"key_vault_access_policy_id": {dependencies.setNeedsKeyVaultAccessPolicy, fmt.Sprintf("%s_key_vault_access_policy.test.id", providerPrefix)},
"key_vault_key_id": {dependencies.setNeedsKeyVaultKey, fmt.Sprintf("%s_key_vault_key.test.id", providerPrefix)},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@ data "%[1]s_client_config" "test" {}
`, tb.providerPrefix))
}

if dependencies.needsDevCenter {
components = append(components, fmt.Sprintf(`
resource "%[1]s_dev_center" "test" {
name = "acctestdc-${var.random_string}"
resource_group_name = %[1]s_resource_group.test.name
location = %[1]s_resource_group.test.location

identity {
type = "SystemAssigned"
}
}
`, tb.providerPrefix))
}

if dependencies.needsEdgeZone {
components = append(components, fmt.Sprintf(`
data "%[1]s_extended_locations" "test" {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ func TestDependenciesTemplate_EverythingEnabled(t *testing.T) {
variables: testVariables{},

needsClientConfig: true,
needsDevCenter: true,
needsEdgeZone: true,
needsNetworkInterface: true,
needsPublicIP: true,
Expand All @@ -34,6 +35,16 @@ func TestDependenciesTemplate_EverythingEnabled(t *testing.T) {
expected := `
data "example_client_config" "test" {}

resource "example_dev_center" "test" {
name = "acctestdc-${var.random_string}"
resource_group_name = example_resource_group.test.name
location = example_resource_group.test.location

identity {
type = "SystemAssigned"
}
}

data "example_extended_locations" "test" {
location = var.primary_location
}
Expand Down Expand Up @@ -98,6 +109,28 @@ data "example_client_config" "test" {}
testhelpers.AssertTemplatedCodeMatches(t, expected, actual)
}

func TestDependenciesTemplate_NeedsDevCenter(t *testing.T) {
builder := NewTestBuilder("example", "resource", resourcemanager.TerraformResourceDetails{})
dependencies := testDependencies{
variables: testVariables{},

needsDevCenter: true,
}
expected := `
resource "example_dev_center" "test" {
name = "acctestdc-${var.random_string}"
resource_group_name = example_resource_group.test.name
location = example_resource_group.test.location

identity {
type = "SystemAssigned"
}
}
`
actual := builder.generateTemplateConfigForDependencies(dependencies)
testhelpers.AssertTemplatedCodeMatches(t, expected, actual)
}

func TestDependenciesTemplate_NeedsEdgeZone(t *testing.T) {
builder := NewTestBuilder("example", "resource", resourcemanager.TerraformResourceDetails{})
dependencies := testDependencies{
Expand Down
Loading