-
Notifications
You must be signed in to change notification settings - Fork 173
/
service_target.go
151 lines (128 loc) · 4.4 KB
/
service_target.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package project
import (
"context"
"encoding/json"
"fmt"
"strings"
"github.com/azure/azure-dev/cli/azd/pkg/async"
"github.com/azure/azure-dev/cli/azd/pkg/environment"
"github.com/azure/azure-dev/cli/azd/pkg/infra"
"github.com/azure/azure-dev/cli/azd/pkg/tools"
)
type ServiceTargetKind string
const (
NonSpecifiedTarget ServiceTargetKind = ""
AppServiceTarget ServiceTargetKind = "appservice"
ContainerAppTarget ServiceTargetKind = "containerapp"
AzureFunctionTarget ServiceTargetKind = "function"
StaticWebAppTarget ServiceTargetKind = "staticwebapp"
SpringAppTarget ServiceTargetKind = "springapp"
AksTarget ServiceTargetKind = "aks"
DotNetContainerAppTarget ServiceTargetKind = "containerapp-dotnet"
)
// RequiresContainer returns true if the service target runs a container image.
func (stk ServiceTargetKind) RequiresContainer() bool {
switch stk {
case ContainerAppTarget,
AksTarget:
return true
}
return false
}
func parseServiceHost(kind ServiceTargetKind) (ServiceTargetKind, error) {
switch kind {
// NOTE: We do not support DotNetContainerAppTarget as a listed service host type in azure.yaml, hence
// it not include in this switch statement. We should think about if we should support this in azure.yaml because
// presently it's the only service target that is tied to a language.
case AppServiceTarget,
ContainerAppTarget,
AzureFunctionTarget,
StaticWebAppTarget,
SpringAppTarget,
AksTarget:
return kind, nil
}
return ServiceTargetKind(""), fmt.Errorf("unsupported host '%s'", kind)
}
type ServiceTarget interface {
// Initializes the service target for the specified service configuration.
// This allows service targets to opt-in to service lifecycle events
Initialize(ctx context.Context, serviceConfig *ServiceConfig) error
// RequiredExternalTools are the tools needed to run the deploy operation for this
// target.
RequiredExternalTools(ctx context.Context) []tools.ExternalTool
// Package prepares artifacts for deployment
Package(
ctx context.Context,
serviceConfig *ServiceConfig,
frameworkPackageOutput *ServicePackageResult,
) *async.TaskWithProgress[*ServicePackageResult, ServiceProgress]
// Deploys the given deployment artifact to the target resource
Deploy(
ctx context.Context,
serviceConfig *ServiceConfig,
servicePackage *ServicePackageResult,
targetResource *environment.TargetResource,
) *async.TaskWithProgress[*ServiceDeployResult, ServiceProgress]
// Endpoints gets the endpoints a service exposes.
Endpoints(
ctx context.Context,
serviceConfig *ServiceConfig,
targetResource *environment.TargetResource,
) ([]string, error)
}
// NewServiceDeployResult is a helper function to create a new ServiceDeployResult
func NewServiceDeployResult(
relatedResourceId string,
kind ServiceTargetKind,
rawResult string,
endpoints []string,
) *ServiceDeployResult {
returnValue := &ServiceDeployResult{
TargetResourceId: relatedResourceId,
Kind: kind,
Endpoints: endpoints,
}
// If the result can be parsed as JSON, store it as such.
// Otherwise, just preserve in raw (string) format.
var detailsObj interface{}
err := json.Unmarshal([]byte(rawResult), &detailsObj)
if err != nil {
returnValue.Details = rawResult
} else {
returnValue.Details = detailsObj
}
return returnValue
}
func resourceTypeMismatchError(
resourceName string,
resourceType string,
expectedResourceType infra.AzureResourceType,
) error {
return fmt.Errorf(
"resource '%s' with type '%s' does not match expected resource type '%s'",
resourceName,
resourceType,
string(expectedResourceType),
)
}
// SupportsDelayedProvisioning returns true if the service target kind
// supports delayed provisioning resources at deployment time, otherwise false.
//
// As an example, ContainerAppTarget is able to provision the container app as part of deployment,
// and thus returns true.
func (st ServiceTargetKind) SupportsDelayedProvisioning() bool {
return st == AksTarget
}
func checkResourceType(resource *environment.TargetResource, expectedResourceType infra.AzureResourceType) error {
if !strings.EqualFold(resource.ResourceType(), string(expectedResourceType)) {
return resourceTypeMismatchError(
resource.ResourceName(),
resource.ResourceType(),
expectedResourceType,
)
}
return nil
}