Skip to content

Commit fee5a78

Browse files
authored
provisioning: Don't "import dot" the provisioning package (#4120)
Go has a feature where you can import a package in a way such that you don't have to qualify symbols with the package name, buy using `.` as the import name. We used this in the provisioning sub-packages to import `provisioning` such that it "felt like" it was part of the sub-package. I think this process in practice leads to more confusion instead of less, it becomes less obvious about where things are defined and what is depending on what and how. The Go Wiki also discourages the use of this pattern except in cases in tests where you need it to address a circular dependency issue, which we do not face here. This change removes the use of the pattern across `azd` (we only used it in the provisioning package, and I think this is an artifact of how it evolved when we introduced the terraform provider to be a sibling of the existing bicep provider (which birthed the provisioning interface).
1 parent 72bc498 commit fee5a78

File tree

9 files changed

+192
-182
lines changed

9 files changed

+192
-182
lines changed

cli/azd/pkg/infra/provisioning/bicep/bicep_provider.go

Lines changed: 62 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import (
3434
"github.com/azure/azure-dev/cli/azd/pkg/convert"
3535
"github.com/azure/azure-dev/cli/azd/pkg/environment"
3636
"github.com/azure/azure-dev/cli/azd/pkg/infra"
37-
. "github.com/azure/azure-dev/cli/azd/pkg/infra/provisioning"
37+
"github.com/azure/azure-dev/cli/azd/pkg/infra/provisioning"
3838
"github.com/azure/azure-dev/cli/azd/pkg/input"
3939
"github.com/azure/azure-dev/cli/azd/pkg/keyvault"
4040
"github.com/azure/azure-dev/cli/azd/pkg/output"
@@ -64,14 +64,14 @@ type BicepProvider struct {
6464
env *environment.Environment
6565
envManager environment.Manager
6666
projectPath string
67-
options Options
67+
options provisioning.Options
6868
console input.Console
6969
bicepCli *bicep.Cli
7070
azCli azcli.AzCli
7171
resourceService *azapi.ResourceService
7272
deploymentManager *infra.DeploymentManager
7373
prompters prompt.Prompter
74-
curPrincipal CurrentPrincipalIdProvider
74+
curPrincipal provisioning.CurrentPrincipalIdProvider
7575
alphaFeatureManager *alpha.FeatureManager
7676
ignoreDeploymentState bool
7777
// compileBicepResult is cached to avoid recompiling the same bicep file multiple times in the same azd run.
@@ -98,7 +98,7 @@ func (p *BicepProvider) RequiredExternalTools() []tools.ExternalTool {
9898

9999
// Initialize initializes provider state from the options.
100100
// It also calls EnsureEnv, which ensures the client-side state is ready for provisioning.
101-
func (p *BicepProvider) Initialize(ctx context.Context, projectPath string, options Options) error {
101+
func (p *BicepProvider) Initialize(ctx context.Context, projectPath string, options provisioning.Options) error {
102102
p.projectPath = projectPath
103103
p.options = options
104104
if p.options.Module == "" {
@@ -130,7 +130,7 @@ func (p *BicepProvider) EnsureEnv(ctx context.Context) error {
130130
// for .bicepparam, we first prompt for environment values before calling compiling bicepparam file
131131
// which can reference these values
132132
if isBicepParamFile(modulePath) {
133-
if err := EnsureSubscriptionAndLocation(ctx, p.envManager, p.env, p.prompters, nil); err != nil {
133+
if err := provisioning.EnsureSubscriptionAndLocation(ctx, p.envManager, p.env, p.prompters, nil); err != nil {
134134
return err
135135
}
136136
}
@@ -154,7 +154,8 @@ func (p *BicepProvider) EnsureEnv(ctx context.Context) error {
154154
return true
155155
}
156156

157-
if err := EnsureSubscriptionAndLocation(ctx, p.envManager, p.env, p.prompters, filterLocation); err != nil {
157+
err := provisioning.EnsureSubscriptionAndLocation(ctx, p.envManager, p.env, p.prompters, filterLocation)
158+
if err != nil {
158159
return err
159160
}
160161

@@ -206,9 +207,9 @@ func (p *BicepProvider) LastDeployment(ctx context.Context) (*azapi.ResourceDepl
206207
return p.latestDeploymentResult(ctx, scope)
207208
}
208209

209-
func (p *BicepProvider) State(ctx context.Context, options *StateOptions) (*StateResult, error) {
210+
func (p *BicepProvider) State(ctx context.Context, options *provisioning.StateOptions) (*provisioning.StateResult, error) {
210211
if options == nil {
211-
options = &StateOptions{}
212+
options = &provisioning.StateOptions{}
212213
}
213214

214215
var err error
@@ -296,11 +297,11 @@ func (p *BicepProvider) State(ctx context.Context, options *StateOptions) (*Stat
296297
Message: fmt.Sprintf("Retrieving Azure deployment (%s)", output.WithHighLightFormat(deployment.Name)),
297298
})
298299

299-
state := State{}
300-
state.Resources = make([]Resource, len(deployment.Resources))
300+
state := provisioning.State{}
301+
state.Resources = make([]provisioning.Resource, len(deployment.Resources))
301302

302303
for idx, res := range deployment.Resources {
303-
state.Resources[idx] = Resource{
304+
state.Resources[idx] = provisioning.Resource{
304305
Id: *res.ID,
305306
}
306307
}
@@ -324,7 +325,7 @@ func (p *BicepProvider) State(ctx context.Context, options *StateOptions) (*Stat
324325
output.WithHyperlink(outputsUrl, deployment.Name),
325326
))
326327

327-
return &StateResult{
328+
return &provisioning.StateResult{
328329
State: &state,
329330
}, nil
330331
}
@@ -444,7 +445,7 @@ func (p *BicepProvider) deploymentState(
444445
return nil, fmt.Errorf("can't get hash from current template: %w", err)
445446
}
446447

447-
if !prevDeploymentEqualToCurrent(ctx, prevDeploymentResult, templateHash, currentParamsHash) {
448+
if !prevDeploymentEqualToCurrent(prevDeploymentResult, templateHash, currentParamsHash) {
448449
return nil, fmt.Errorf("deployment state has changed")
449450
}
450451

@@ -498,8 +499,7 @@ func parametersHash(templateParameters azure.ArmTemplateParameterDefinitions, pa
498499
}
499500

500501
// prevDeploymentEqualToCurrent compares the template hash from a previous deployment against a current template.
501-
func prevDeploymentEqualToCurrent(
502-
ctx context.Context, prev *azapi.ResourceDeployment, templateHash, paramsHash string) bool {
502+
func prevDeploymentEqualToCurrent(prev *azapi.ResourceDeployment, templateHash, paramsHash string) bool {
503503
if prev == nil {
504504
logDS("No previous deployment.")
505505
return false
@@ -536,7 +536,7 @@ func logDS(msg string, v ...any) {
536536
}
537537

538538
// Provisioning the infrastructure within the specified template
539-
func (p *BicepProvider) Deploy(ctx context.Context) (*DeployResult, error) {
539+
func (p *BicepProvider) Deploy(ctx context.Context) (*provisioning.DeployResult, error) {
540540
if p.ignoreDeploymentState {
541541
logDS("Azure Deployment State is disabled by --no-state arg.")
542542
}
@@ -568,9 +568,9 @@ func (p *BicepProvider) Deploy(ctx context.Context) (*DeployResult, error) {
568568
azapi.CreateDeploymentOutput(deploymentState.Outputs),
569569
)
570570

571-
return &DeployResult{
571+
return &provisioning.DeployResult{
572572
Deployment: deployment,
573-
SkippedReason: DeploymentStateSkipped,
573+
SkippedReason: provisioning.DeploymentStateSkipped,
574574
}, nil
575575
}
576576
logDS("%s", err.Error())
@@ -635,13 +635,13 @@ func (p *BicepProvider) Deploy(ctx context.Context) (*DeployResult, error) {
635635
azapi.CreateDeploymentOutput(deployResult.Outputs),
636636
)
637637

638-
return &DeployResult{
638+
return &provisioning.DeployResult{
639639
Deployment: deployment,
640640
}, nil
641641
}
642642

643643
// Preview runs deploy using the what-if argument
644-
func (p *BicepProvider) Preview(ctx context.Context) (*DeployPreviewResult, error) {
644+
func (p *BicepProvider) Preview(ctx context.Context) (*provisioning.DeployPreviewResult, error) {
645645
bicepDeploymentData, err := p.plan(ctx)
646646
if err != nil {
647647
return nil, err
@@ -682,24 +682,24 @@ func (p *BicepProvider) Preview(ctx context.Context) (*DeployPreviewResult, erro
682682
)
683683
}
684684

685-
var changes []*DeploymentPreviewChange
685+
var changes []*provisioning.DeploymentPreviewChange
686686
for _, change := range deployPreviewResult.Properties.Changes {
687687
resourceAfter := change.After.(map[string]interface{})
688688

689-
changes = append(changes, &DeploymentPreviewChange{
690-
ChangeType: ChangeType(*change.ChangeType),
691-
ResourceId: Resource{
689+
changes = append(changes, &provisioning.DeploymentPreviewChange{
690+
ChangeType: provisioning.ChangeType(*change.ChangeType),
691+
ResourceId: provisioning.Resource{
692692
Id: *change.ResourceID,
693693
},
694694
ResourceType: resourceAfter["type"].(string),
695695
Name: resourceAfter["name"].(string),
696696
})
697697
}
698698

699-
return &DeployPreviewResult{
700-
Preview: &DeploymentPreview{
699+
return &provisioning.DeployPreviewResult{
700+
Preview: &provisioning.DeploymentPreview{
701701
Status: *deployPreviewResult.Status,
702-
Properties: &DeploymentPreviewProperties{
702+
Properties: &provisioning.DeploymentPreviewProperties{
703703
Changes: changes,
704704
},
705705
},
@@ -740,7 +740,10 @@ func (p *BicepProvider) inferScopeFromEnv() (infra.Scope, error) {
740740
}
741741

742742
// Destroys the specified deployment by deleting all azure resources, resource groups & deployments that are referenced.
743-
func (p *BicepProvider) Destroy(ctx context.Context, options DestroyOptions) (*DestroyResult, error) {
743+
func (p *BicepProvider) Destroy(
744+
ctx context.Context,
745+
options provisioning.DestroyOptions,
746+
) (*provisioning.DestroyResult, error) {
744747
modulePath := p.modulePath()
745748
// TODO: Report progress, "Compiling Bicep template"
746749
compileResult, err := p.compileBicep(ctx, modulePath)
@@ -868,7 +871,7 @@ func (p *BicepProvider) Destroy(ctx context.Context, options DestroyOptions) (*D
868871
return nil, fmt.Errorf("purging resources: %w", err)
869872
}
870873

871-
destroyResult := &DestroyResult{
874+
destroyResult := &provisioning.DestroyResult{
872875
InvalidatedEnvKeys: slices.Collect(maps.Keys(p.createOutputParameters(
873876
compileResult.Template.Outputs,
874877
azapi.CreateDeploymentOutput(mostRecentDeployment.Outputs),
@@ -1006,7 +1009,7 @@ func (p *BicepProvider) generateResourcesToDelete(groupedResources map[string][]
10061009
// Deletes the azure resources within the deployment
10071010
func (p *BicepProvider) destroyDeploymentWithConfirmation(
10081011
ctx context.Context,
1009-
options DestroyOptions,
1012+
options provisioning.DestroyOptions,
10101013
deployment infra.Deployment,
10111014
groupedResources map[string][]*azapi.Resource,
10121015
resourceCount int,
@@ -1076,7 +1079,7 @@ func itemsCountAsText(items []itemToPurge) string {
10761079
func (p *BicepProvider) purgeItems(
10771080
ctx context.Context,
10781081
items []itemToPurge,
1079-
options DestroyOptions,
1082+
options provisioning.DestroyOptions,
10801083
) error {
10811084
if len(items) == 0 {
10821085
// nothing to purge
@@ -1429,18 +1432,18 @@ func (p *BicepProvider) purgeAPIManagement(
14291432
return nil
14301433
}
14311434

1432-
func (p *BicepProvider) mapBicepTypeToInterfaceType(s string) ParameterType {
1435+
func (p *BicepProvider) mapBicepTypeToInterfaceType(s string) provisioning.ParameterType {
14331436
switch s {
14341437
case "String", "string", "secureString", "securestring":
1435-
return ParameterTypeString
1438+
return provisioning.ParameterTypeString
14361439
case "Bool", "bool":
1437-
return ParameterTypeBoolean
1440+
return provisioning.ParameterTypeBoolean
14381441
case "Int", "int":
1439-
return ParameterTypeNumber
1442+
return provisioning.ParameterTypeNumber
14401443
case "Object", "object", "secureObject", "secureobject":
1441-
return ParameterTypeObject
1444+
return provisioning.ParameterTypeObject
14421445
case "Array", "array":
1443-
return ParameterTypeArray
1446+
return provisioning.ParameterTypeArray
14441447
default:
14451448
panic(fmt.Sprintf("unexpected bicep type: '%s'", s))
14461449
}
@@ -1451,14 +1454,14 @@ func (p *BicepProvider) mapBicepTypeToInterfaceType(s string) ParameterType {
14511454
func (p *BicepProvider) createOutputParameters(
14521455
templateOutputs azure.ArmTemplateOutputs,
14531456
azureOutputParams map[string]azapi.AzCliDeploymentOutput,
1454-
) map[string]OutputParameter {
1457+
) map[string]provisioning.OutputParameter {
14551458
canonicalOutputCasings := make(map[string]string, len(templateOutputs))
14561459

14571460
for key := range templateOutputs {
14581461
canonicalOutputCasings[strings.ToLower(key)] = key
14591462
}
14601463

1461-
outputParams := make(map[string]OutputParameter, len(azureOutputParams))
1464+
outputParams := make(map[string]provisioning.OutputParameter, len(azureOutputParams))
14621465

14631466
for key, azureParam := range azureOutputParams {
14641467
var paramName string
@@ -1472,7 +1475,7 @@ func (p *BicepProvider) createOutputParameters(
14721475
paramName = strings.ToUpper(key)
14731476
}
14741477

1475-
outputParams[paramName] = OutputParameter{
1478+
outputParams[paramName] = provisioning.OutputParameter{
14761479
Type: p.mapBicepTypeToInterfaceType(azureParam.Type),
14771480
Value: azureParam.Value,
14781481
}
@@ -1692,20 +1695,20 @@ func definitionName(typeDefinitionRef string) (string, error) {
16921695
}
16931696

16941697
// Converts a Bicep parameters file to a generic provisioning template
1695-
func (p *BicepProvider) convertToDeployment(bicepTemplate azure.ArmTemplate) (*Deployment, error) {
1696-
template := Deployment{}
1697-
parameters := make(map[string]InputParameter)
1698-
outputs := make(map[string]OutputParameter)
1698+
func (p *BicepProvider) convertToDeployment(bicepTemplate azure.ArmTemplate) (*provisioning.Deployment, error) {
1699+
template := provisioning.Deployment{}
1700+
parameters := make(map[string]provisioning.InputParameter)
1701+
outputs := make(map[string]provisioning.OutputParameter)
16991702

17001703
for key, param := range bicepTemplate.Parameters {
1701-
parameters[key] = InputParameter{
1704+
parameters[key] = provisioning.InputParameter{
17021705
Type: string(p.mapBicepTypeToInterfaceType(param.Type)),
17031706
DefaultValue: param.DefaultValue,
17041707
}
17051708
}
17061709

17071710
for key, param := range bicepTemplate.Outputs {
1708-
outputs[key] = OutputParameter{
1711+
outputs[key] = provisioning.OutputParameter{
17091712
Type: p.mapBicepTypeToInterfaceType(param.Type),
17101713
Value: param.Value,
17111714
}
@@ -1866,7 +1869,7 @@ func (p *BicepProvider) ensureParameters(
18661869
// If the parameter is tagged with {type: "generate"}, skip prompting.
18671870
// We generate it once, then save to config for next attempts.`.
18681871
azdMetadata, hasMetadata := param.AzdMetadata()
1869-
if hasMetadata && parameterType == ParameterTypeString && azdMetadata.Type != nil &&
1872+
if hasMetadata && parameterType == provisioning.ParameterTypeString && azdMetadata.Type != nil &&
18701873
*azdMetadata.Type == azure.AzdMetadataTypeGenerate {
18711874

18721875
// - generate once
@@ -1973,27 +1976,27 @@ func mustSetParamAsConfig(key string, value any, config config.Config, isSecured
19731976
}
19741977

19751978
// Convert the ARM parameters file value into a value suitable for deployment
1976-
func armParameterFileValue(paramType ParameterType, value any, defaultValue any) any {
1979+
func armParameterFileValue(paramType provisioning.ParameterType, value any, defaultValue any) any {
19771980
// Quick return if the value being converted is not a string
19781981
if value == nil || reflect.TypeOf(value).Kind() != reflect.String {
19791982
return value
19801983
}
19811984

19821985
// Relax the handling of bool and number types to accept convertible strings
19831986
switch paramType {
1984-
case ParameterTypeBoolean:
1987+
case provisioning.ParameterTypeBoolean:
19851988
if val, ok := value.(string); ok {
19861989
if boolVal, err := strconv.ParseBool(val); err == nil {
19871990
return boolVal
19881991
}
19891992
}
1990-
case ParameterTypeNumber:
1993+
case provisioning.ParameterTypeNumber:
19911994
if val, ok := value.(string); ok {
19921995
if intVal, err := strconv.ParseInt(val, 10, 64); err == nil {
19931996
return intVal
19941997
}
19951998
}
1996-
case ParameterTypeString:
1999+
case provisioning.ParameterTypeString:
19972000
// Use Cases
19982001
// 1. Non-empty input value, return input value (no prompt)
19992002
// 2. Empty input value and no default - return nil (prompt user)
@@ -2014,15 +2017,15 @@ func armParameterFileValue(paramType ParameterType, value any, defaultValue any)
20142017
return nil
20152018
}
20162019

2017-
func isValueAssignableToParameterType(paramType ParameterType, value any) bool {
2020+
func isValueAssignableToParameterType(paramType provisioning.ParameterType, value any) bool {
20182021
switch paramType {
2019-
case ParameterTypeArray:
2022+
case provisioning.ParameterTypeArray:
20202023
_, ok := value.([]any)
20212024
return ok
2022-
case ParameterTypeBoolean:
2025+
case provisioning.ParameterTypeBoolean:
20232026
_, ok := value.(bool)
20242027
return ok
2025-
case ParameterTypeNumber:
2028+
case provisioning.ParameterTypeNumber:
20262029
switch t := value.(type) {
20272030
case int, int8, int16, int32, int64:
20282031
return true
@@ -2038,10 +2041,10 @@ func isValueAssignableToParameterType(paramType ParameterType, value any) bool {
20382041
default:
20392042
return false
20402043
}
2041-
case ParameterTypeObject:
2044+
case provisioning.ParameterTypeObject:
20422045
_, ok := value.(map[string]any)
20432046
return ok
2044-
case ParameterTypeString:
2047+
case provisioning.ParameterTypeString:
20452048
_, ok := value.(string)
20462049
return ok
20472050
default:
@@ -2059,11 +2062,11 @@ func NewBicepProvider(
20592062
env *environment.Environment,
20602063
console input.Console,
20612064
prompters prompt.Prompter,
2062-
curPrincipal CurrentPrincipalIdProvider,
2065+
curPrincipal provisioning.CurrentPrincipalIdProvider,
20632066
alphaFeatureManager *alpha.FeatureManager,
20642067
keyvaultService keyvault.KeyVaultService,
20652068
cloud *cloud.Cloud,
2066-
) Provider {
2069+
) provisioning.Provider {
20672070
return &BicepProvider{
20682071
envManager: envManager,
20692072
env: env,

0 commit comments

Comments
 (0)