cli/azd/pkg/infra/scope.go (300 lines of code) (raw):
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package infra
import (
"context"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources"
"github.com/azure/azure-dev/cli/azd/pkg/async"
"github.com/azure/azure-dev/cli/azd/pkg/azapi"
"github.com/azure/azure-dev/cli/azd/pkg/azure"
)
type Scope interface {
// SubscriptionId is the id of the subscription which this deployment targets.
SubscriptionId() string
// ListDeployments returns all the deployments at this scope.
ListDeployments(ctx context.Context) ([]*azapi.ResourceDeployment, error)
Deployment(deploymentName string) Deployment
}
type Deployment interface {
Scope
// Name is the name of this deployment.
Name() string
// PortalUrl is the URL that may be used to view this deployment resource in the Azure Portal.
PortalUrl(ctx context.Context) (string, error)
// OutputsUrl is the URL that may be used to view this deployment outputs the in Azure Portal.
OutputsUrl(ctx context.Context) (string, error)
// DeploymentUrl is the URL that may be used to view this deployment progress in the Azure Portal.
DeploymentUrl(ctx context.Context) (string, error)
// Validate a given template on preflight API
ValidatePreflight(
ctx context.Context,
template azure.RawArmTemplate,
parameters azure.ArmParameters,
tags map[string]*string,
options map[string]any,
) error
// Deploy a given template with a set of parameters.
Deploy(
ctx context.Context,
template azure.RawArmTemplate,
parameters azure.ArmParameters,
tags map[string]*string,
options map[string]any,
) (*azapi.ResourceDeployment, error)
Delete(ctx context.Context,
options map[string]any,
progress *async.Progress[azapi.DeleteDeploymentProgress],
) error
// Deploy a given template with a set of parameters.
DeployPreview(
ctx context.Context,
template azure.RawArmTemplate,
parameters azure.ArmParameters,
) (*armresources.WhatIfOperationResult, error)
// Deployment fetches information about this deployment.
Get(ctx context.Context) (*azapi.ResourceDeployment, error)
// Operations returns all the operations for this deployment.
Operations(ctx context.Context) ([]*armresources.DeploymentOperation, error)
Resources(ctx context.Context) ([]*armresources.ResourceReference, error)
}
type ResourceGroupDeployment struct {
*ResourceGroupScope
name string
deployment *azapi.ResourceDeployment
}
func (s *ResourceGroupDeployment) Name() string {
return s.name
}
func (s *ResourceGroupDeployment) ValidatePreflight(
ctx context.Context,
template azure.RawArmTemplate,
parameters azure.ArmParameters,
tags map[string]*string,
options map[string]any,
) error {
return s.deploymentService.ValidatePreflightToResourceGroup(
ctx, s.subscriptionId, s.resourceGroupName, s.name, template, parameters, tags, options)
}
func (s *ResourceGroupDeployment) Deploy(
ctx context.Context,
template azure.RawArmTemplate,
parameters azure.ArmParameters,
tags map[string]*string,
options map[string]any,
) (*azapi.ResourceDeployment, error) {
return s.deploymentService.DeployToResourceGroup(
ctx, s.subscriptionId, s.resourceGroupName, s.name, template, parameters, tags, options)
}
func (s *ResourceGroupDeployment) Delete(
ctx context.Context,
options map[string]any,
progress *async.Progress[azapi.DeleteDeploymentProgress],
) error {
return s.deploymentService.DeleteResourceGroupDeployment(
ctx,
s.subscriptionId,
s.resourceGroupName,
s.name,
options,
progress,
)
}
func (s *ResourceGroupDeployment) DeployPreview(
ctx context.Context,
template azure.RawArmTemplate,
parameters azure.ArmParameters) (*armresources.WhatIfOperationResult, error) {
return s.deploymentService.WhatIfDeployToResourceGroup(
ctx, s.subscriptionId, s.resourceGroupName, s.name, template, parameters)
}
// GetDeployment fetches the result of the most recent deployment.
func (s *ResourceGroupDeployment) Get(ctx context.Context) (*azapi.ResourceDeployment, error) {
return s.deploymentService.GetResourceGroupDeployment(ctx, s.subscriptionId, s.resourceGroupName, s.name)
}
// Gets the resource deployment operations for the current scope
func (s *ResourceGroupDeployment) Operations(ctx context.Context) ([]*armresources.DeploymentOperation, error) {
return s.deploymentService.
ListResourceGroupDeploymentOperations(
ctx,
s.subscriptionId,
s.resourceGroupName,
s.name,
)
}
func (s *ResourceGroupDeployment) Resources(ctx context.Context) ([]*armresources.ResourceReference, error) {
return s.deploymentService.ListResourceGroupDeploymentResources(ctx, s.subscriptionId, s.resourceGroupName, s.name)
}
// Gets the url to check deployment resource
func (s *ResourceGroupDeployment) PortalUrl(ctx context.Context) (string, error) {
if s.deployment == nil {
deployment, err := s.Get(ctx)
if err != nil {
return "", err
}
s.deployment = deployment
}
return s.deployment.PortalUrl, nil
}
// Gets the url to view deployment outputs
func (s *ResourceGroupDeployment) OutputsUrl(ctx context.Context) (string, error) {
if s.deployment == nil {
deployment, err := s.Get(ctx)
if err != nil {
return "", err
}
s.deployment = deployment
}
return s.deployment.OutputsUrl, nil
}
// Gets the url to view deployment
func (s *ResourceGroupDeployment) DeploymentUrl(ctx context.Context) (string, error) {
if s.deployment == nil {
deployment, err := s.Get(ctx)
if err != nil {
return "", err
}
s.deployment = deployment
}
return s.deployment.DeploymentUrl, nil
}
func NewResourceGroupDeployment(scope *ResourceGroupScope, deploymentName string) *ResourceGroupDeployment {
return &ResourceGroupDeployment{
ResourceGroupScope: scope,
name: deploymentName,
}
}
type ResourceGroupScope struct {
deploymentService azapi.DeploymentService
subscriptionId string
resourceGroupName string
}
func newResourceGroupScope(
deploymentsService azapi.DeploymentService,
subscriptionId string,
resourceGroupName string,
) *ResourceGroupScope {
return &ResourceGroupScope{
deploymentService: deploymentsService,
subscriptionId: subscriptionId,
resourceGroupName: resourceGroupName,
}
}
func (s *ResourceGroupScope) SubscriptionId() string {
return s.subscriptionId
}
func (s *ResourceGroupScope) ResourceGroupName() string {
return s.resourceGroupName
}
// ListDeployments returns all the deployments in this resource group.
func (s *ResourceGroupScope) ListDeployments(ctx context.Context) ([]*azapi.ResourceDeployment, error) {
return s.deploymentService.ListResourceGroupDeployments(ctx, s.subscriptionId, s.resourceGroupName)
}
// Deployment gets the deployment with the specified name.
func (s *ResourceGroupScope) Deployment(deploymentName string) Deployment {
return NewResourceGroupDeployment(s, deploymentName)
}
type SubscriptionDeployment struct {
*SubscriptionScope
name string
deployment *azapi.ResourceDeployment
}
func (s *SubscriptionDeployment) Name() string {
return s.name
}
// Gets the url to check deployment resource
func (s *SubscriptionDeployment) PortalUrl(ctx context.Context) (string, error) {
if s.deployment == nil {
deployment, err := s.Get(ctx)
if err != nil {
return "", err
}
s.deployment = deployment
}
return s.deployment.PortalUrl, nil
}
// Gets the url to view deployment outputs
func (s *SubscriptionDeployment) OutputsUrl(ctx context.Context) (string, error) {
if s.deployment == nil {
deployment, err := s.Get(ctx)
if err != nil {
return "", err
}
s.deployment = deployment
}
return s.deployment.OutputsUrl, nil
}
// Gets the url to view deployment
func (s *SubscriptionDeployment) DeploymentUrl(ctx context.Context) (string, error) {
if s.deployment == nil {
deployment, err := s.Get(ctx)
if err != nil {
return "", err
}
s.deployment = deployment
}
return s.deployment.DeploymentUrl, nil
}
func (s *SubscriptionDeployment) ValidatePreflight(
ctx context.Context,
template azure.RawArmTemplate,
parameters azure.ArmParameters,
tags map[string]*string,
options map[string]any,
) error {
return s.deploymentService.ValidatePreflightToSubscription(ctx, s.subscriptionId, s.location,
s.name, template, parameters, tags, options)
}
// Deploy a given template with a set of parameters.
func (s *SubscriptionDeployment) Deploy(
ctx context.Context,
template azure.RawArmTemplate,
parameters azure.ArmParameters,
tags map[string]*string,
options map[string]any,
) (*azapi.ResourceDeployment, error) {
return s.deploymentService.DeployToSubscription(
ctx,
s.subscriptionId,
s.location,
s.name,
template,
parameters,
tags,
options,
)
}
func (s *SubscriptionDeployment) Delete(
ctx context.Context,
options map[string]any,
progress *async.Progress[azapi.DeleteDeploymentProgress],
) error {
return s.deploymentService.DeleteSubscriptionDeployment(ctx, s.subscriptionId, s.name, options, progress)
}
// Deploy a given template with a set of parameters.
func (s *SubscriptionDeployment) DeployPreview(
ctx context.Context,
template azure.RawArmTemplate,
parameters azure.ArmParameters) (*armresources.WhatIfOperationResult, error) {
return s.deploymentService.WhatIfDeployToSubscription(
ctx, s.subscriptionId, s.location, s.name, template, parameters)
}
// GetDeployment fetches the result of the most recent deployment.
func (s *SubscriptionDeployment) Get(ctx context.Context) (*azapi.ResourceDeployment, error) {
return s.deploymentService.GetSubscriptionDeployment(ctx, s.subscriptionId, s.name)
}
// Gets the resource deployment operations for the current scope
func (s *SubscriptionDeployment) Operations(ctx context.Context) ([]*armresources.DeploymentOperation, error) {
return s.deploymentService.ListSubscriptionDeploymentOperations(ctx, s.subscriptionId, s.name)
}
func (s *SubscriptionDeployment) Resources(ctx context.Context) ([]*armresources.ResourceReference, error) {
return s.deploymentService.ListSubscriptionDeploymentResources(ctx, s.subscriptionId, s.name)
}
func NewSubscriptionDeployment(
scope *SubscriptionScope,
deploymentName string,
) *SubscriptionDeployment {
return &SubscriptionDeployment{
SubscriptionScope: scope,
name: deploymentName,
}
}
type SubscriptionScope struct {
deploymentService azapi.DeploymentService
subscriptionId string
location string
}
// Gets the Azure subscription id
func (s *SubscriptionScope) SubscriptionId() string {
return s.subscriptionId
}
func (s *SubscriptionScope) Location() string {
return s.location
}
func (s *SubscriptionScope) Deployment(deploymentName string) Deployment {
return NewSubscriptionDeployment(s, deploymentName)
}
// ListDeployments returns all the deployments at subscription scope.
func (s *SubscriptionScope) ListDeployments(ctx context.Context) ([]*azapi.ResourceDeployment, error) {
return s.deploymentService.ListSubscriptionDeployments(ctx, s.subscriptionId)
}
func newSubscriptionScope(
deploymentsService azapi.DeploymentService,
subscriptionId string,
location string,
) *SubscriptionScope {
return &SubscriptionScope{
deploymentService: deploymentsService,
subscriptionId: subscriptionId,
location: location,
}
}