Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Latest commit

 

History

History
History
150 lines (127 loc) · 5.2 KB

File metadata and controls

150 lines (127 loc) · 5.2 KB
Copy raw file
Download raw file
Open symbols panel
Edit and raw actions
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
package api
import (
"context"
"encoding/json"
"fmt"
"github.com/bytebase/bytebase/common"
)
// DeploymentConfig is the API message for deployment configurations.
type DeploymentConfig struct {
ID int `jsonapi:"primary,deploymentConfig"`
// Standard fields
CreatorID int
Creator *Principal `jsonapi:"relation,creator"`
CreatedTs int64 `jsonapi:"attr,createdTs"`
UpdaterID int
Updater *Principal `jsonapi:"relation,updater"`
UpdatedTs int64 `jsonapi:"attr,updatedTs"`
// Related fields
ProjectID int
Project *Project `jsonapi:"relation,project"`
// Domain specific fields
Name string `jsonapi:"attr,name"`
// Payload encapsulates DeploymentSchedule in json string format. We use json instead jsonapi because this configuration isn't queryable as HTTP format.
Payload string `jsonapi:"attr,payload"`
}
// DeploymentSchedule is the API message for deployment schedule.
type DeploymentSchedule struct {
Deployments []*Deployment `json:"deployments"`
}
// Deployment is the API message for deployment.
type Deployment struct {
Name string `json:"name"`
Spec *DeploymentSpec `json:"spec"`
}
// DeploymentSpec is the API message for deployment specification.
type DeploymentSpec struct {
Selector *LabelSelector `json:"selector"`
}
// LabelSelector is the API message for label selector.
type LabelSelector struct {
// MatchExpressions is a list of label selector requirements. The requirements are ANDed.
MatchExpressions []*LabelSelectorRequirement `json:"matchExpressions"`
}
// OperatorType is the type of label selector requirement operator.
// Valid operators are In, Exists.
// Note: NotIn and DoesNotExist are not supported initially.
type OperatorType string
const (
// InOperatorType is the operator type for In.
InOperatorType OperatorType = "In"
// ExistsOperatorType is the operator type for Exists.
ExistsOperatorType OperatorType = "Exists"
)
// LabelSelectorRequirement is the API message for label selector.
type LabelSelectorRequirement struct {
// Key is the label key that the selector applies to.
Key string `json:"key"`
// Operator represents a key's relationship to a set of values.
Operator OperatorType `json:"operator"`
// Values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch.
Values []string `json:"values"`
}
// DeploymentConfigFind is the find request for deployment configs.
type DeploymentConfigFind struct {
ID *int
// Related fields
ProjectID *int
}
// DeploymentConfigUpsert is the message to upsert a deployment configuration.
// NOTE: We use PATCH for Upsert, this is inspired by https://google.aip.dev/134#patch-and-put
type DeploymentConfigUpsert struct {
// Standard fields
// Value is assigned from the jwt subject field passed by the client.
// CreatorID is the ID of the creator.
UpdaterID int
// Related fields
ProjectID int
// Domain specific fields
Name string `jsonapi:"attr,name"`
// Payload is a json serialization of DeploymentSchedule.
Payload string `jsonapi:"attr,payload"`
}
// DeploymentConfigService is the service for deployment configurations.
type DeploymentConfigService interface {
// FindDeploymentConfig finds the deployment configuration in a project.
FindDeploymentConfig(ctx context.Context, find *DeploymentConfigFind) (*DeploymentConfig, error)
// UpsertDeploymentConfig upserts a deployment configuration to a project.
UpsertDeploymentConfig(ctx context.Context, upsert *DeploymentConfigUpsert) (*DeploymentConfig, error)
}
// ValidateAndGetDeploymentSchedule validates and returns the deployment schedule.
// Note: this validation only checks whether the payloads is a valid json, however, invalid field name errors are ignored.
func ValidateAndGetDeploymentSchedule(payload string) (*DeploymentSchedule, error) {
schedule := &DeploymentSchedule{}
if err := json.Unmarshal([]byte(payload), schedule); err != nil {
return nil, err
}
for _, d := range schedule.Deployments {
if d.Name == "" {
return nil, common.Errorf(common.Invalid, fmt.Errorf("Deployment name must not be empty"))
}
hasEnv := false
for _, e := range d.Spec.Selector.MatchExpressions {
switch e.Operator {
case InOperatorType:
if len(e.Values) <= 0 {
return nil, common.Errorf(common.Invalid, fmt.Errorf("expression key %q with %q operator should have at least one value", e.Key, e.Operator))
}
case ExistsOperatorType:
if len(e.Values) > 0 {
return nil, common.Errorf(common.Invalid, fmt.Errorf("expression key %q with %q operator shouldn't have values", e.Key, e.Operator))
}
default:
return nil, common.Errorf(common.Invalid, fmt.Errorf("expression key %q has invalid operator %q", e.Key, e.Operator))
}
if e.Key == EnvironmentKeyName {
hasEnv = true
if e.Operator != InOperatorType || len(e.Values) != 1 {
return nil, common.Errorf(common.Invalid, fmt.Errorf("label %q should must use operator %q with exactly one value", EnvironmentKeyName, InOperatorType))
}
}
}
if !hasEnv {
return nil, common.Errorf(common.Invalid, fmt.Errorf("deployment should contain %q label", EnvironmentKeyName))
}
}
return schedule, nil
}
Morty Proxy This is a proxified and sanitized view of the page, visit original site.