Skip to content

Commit ecf0c3f

Browse files
committed
feat: implement variable set
1 parent 4e63425 commit ecf0c3f

33 files changed

+6033
-2521
lines changed

api/openapispec/docs.go

Lines changed: 1690 additions & 947 deletions
Large diffs are not rendered by default.

api/openapispec/swagger.json

Lines changed: 1690 additions & 947 deletions
Large diffs are not rendered by default.

api/openapispec/swagger.yaml

Lines changed: 790 additions & 265 deletions
Large diffs are not rendered by default.

pkg/domain/entity/variable.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package entity
2+
3+
import "errors"
4+
5+
const (
6+
PlainTextType string = "PlainText"
7+
CipherTextType string = "CipherText"
8+
)
9+
10+
// Variable represents the specific configuration code variable,
11+
// which usually includes the global configurations for Terraform providers like
12+
// api host, ak and sk.
13+
type Variable struct {
14+
// VariableKey is the access path for the variable.
15+
VariableKey string `yaml:"variableKey,omitempty" json:"variableKey,omitempty"`
16+
// Value is the value of the variable.
17+
Value string `yaml:"value,omitempty" json:"value,omitempty"`
18+
// Type is the type of the variable.
19+
Type string `yaml:"type,omitempty" json:"type,omitempty"`
20+
// Labels clarifies the scope of the variable.
21+
Labels map[string]string `yaml:"labels,omitempty" json:"labels,omitempty"`
22+
// Fqn is the fully qualified name of the variable.
23+
Fqn string `yaml:"fqn,omitempty" json:"fqn,omitempty"`
24+
}
25+
26+
// VariableFilter represents the filter conditions to list variables.
27+
type VariableFilter struct {
28+
Key string
29+
Pagination *Pagination
30+
}
31+
32+
// VariableListResult represents the result of listing variables.
33+
type VariableListResult struct {
34+
Variables []*Variable
35+
Total int
36+
}
37+
38+
// Validate checks if the variable is valid.
39+
// It returns an error if the variable is not valid.
40+
func (v *Variable) Validate() error {
41+
if v == nil {
42+
return errors.New("variable is nil")
43+
}
44+
45+
if v.VariableKey == "" {
46+
return errors.New("empty variable key")
47+
}
48+
49+
if v.Type != PlainTextType && v.Type != CipherTextType {
50+
return errors.New("invalid variable type")
51+
}
52+
53+
if v.Fqn == "" {
54+
return errors.New("empty fqn")
55+
}
56+
57+
return nil
58+
}

pkg/domain/entity/variable_labels.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package entity
2+
3+
import "errors"
4+
5+
// VariableLabels records the labels of the specific configuration code variable,
6+
// and the labels are sorted in ascending order of priority.
7+
type VariableLabels struct {
8+
// VariableKey is the access path for the variable.
9+
VariableKey string `yaml:"variableKey,omitempty" json:"variableKey,omitempty"`
10+
// Labels is the list of variable labels, which should be sorted
11+
// in ascending order of priority.
12+
Labels []string `yaml:"labels,omitempty" json:"labels,omitempty"`
13+
}
14+
15+
// VariableLabelsFilter represents the filter conditions to list variable labels.
16+
type VariableLabelsFilter struct {
17+
Labels []string
18+
Pagination *Pagination
19+
}
20+
21+
// VariableLabelsListResult represents the result of listing variable labels.
22+
type VariableLabelsListResult struct {
23+
VariableLabels []*VariableLabels
24+
Total int
25+
}
26+
27+
// Validate checks if the variable labels are valid.
28+
// It returns an error if the variable labels are not valid.
29+
func (vl *VariableLabels) Validate() error {
30+
if vl == nil {
31+
return errors.New("nil variable labels")
32+
}
33+
34+
if vl.VariableKey == "" {
35+
return errors.New("empty key for variable labels")
36+
}
37+
38+
if len(vl.Labels) == 0 {
39+
return errors.New("empty variable labels")
40+
}
41+
42+
return nil
43+
}

pkg/domain/repository/repository.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,33 @@ type RunRepository interface {
152152
// List retrieves all existing run.
153153
List(ctx context.Context, filter *entity.RunFilter) (*entity.RunListResult, error)
154154
}
155+
156+
// VariableLabelsRepository is an interface that defines the repository
157+
// for variable labels. It follows the principles of domain-driven design (DDD).
158+
type VariableLabelsRepository interface {
159+
// Create creates a new set of variable labels.
160+
Create(ctx context.Context, vl *entity.VariableLabels) error
161+
// Delete deletes a set of variable labels by its key.
162+
Delete(ctx context.Context, key string) error
163+
// Update updates an existing set of variable labels.
164+
Update(ctx context.Context, vl *entity.VariableLabels) error
165+
// GetByKey retrieves a set of variable labels by its key.
166+
GetByKey(ctx context.Context, key string) (*entity.VariableLabels, error)
167+
// List retrieves all existing variable labels.
168+
List(ctx context.Context, filter *entity.VariableLabelsFilter) (*entity.VariableLabelsListResult, error)
169+
}
170+
171+
// VariableRepository is an interface that defines the repository operations
172+
// for variables. It follows the principles of domain-driven design (DDD).
173+
type VariableRepository interface {
174+
// Create creates a new variable.
175+
Create(ctx context.Context, v *entity.Variable) error
176+
// Delete deletes a variable by its fqn.
177+
Delete(ctx context.Context, fqn string) error
178+
// Update updates an existing variable.
179+
Update(ctx context.Context, v *entity.Variable) error
180+
// GetByFqn retrieves a variable by its fqn.
181+
GetByFqn(ctx context.Context, fqn string) (*entity.Variable, error)
182+
// List retrieves all existing variables.
183+
List(ctx context.Context, filter *entity.VariableFilter) (*entity.VariableListResult, error)
184+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package request
2+
3+
import "net/http"
4+
5+
// CreateVariableLabelsRequest represents the create request structure
6+
// for variable labels.
7+
type CreateVariableLabelsRequest struct {
8+
// VariableKey is the access path for the variable.
9+
VariableKey string `json:"variableKey" binding:"required"`
10+
// Labels is the list of variable labels, which should be sorted
11+
// in ascending order of priority.
12+
Labels []string `json:"labels" binding:"required"`
13+
}
14+
15+
// UpdateVariableLabelsRequest represents the update request structure
16+
// for variable labels.
17+
type UpdateVariableLabelsRequest struct {
18+
// VariableKey is the access path for the variable.
19+
VariableKey string `json:"variableKey" binding:"required"`
20+
// Labels is the list of variable labels, which should be sorted
21+
// in ascending order of priority.
22+
Labels []string `json:"labels" binding:"required"`
23+
}
24+
25+
func (payload *CreateVariableLabelsRequest) Decode(r *http.Request) error {
26+
return decode(r, payload)
27+
}
28+
29+
func (payload *UpdateVariableLabelsRequest) Decode(r *http.Request) error {
30+
return decode(r, payload)
31+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package request
2+
3+
import "net/http"
4+
5+
// CreateVariableSetRequest represents the create request structure
6+
// for a variable in the variable set.
7+
type CreateVariableSetRequest struct {
8+
// VariableKey is the access path for the variable.
9+
VariableKey string `json:"variableKey" binding:"required"`
10+
// Value is the value of the variable.
11+
Value string `json:"value" binding:"required"`
12+
// Type is the type of the variable.
13+
Type string `json:"type" binding:"required"`
14+
// Labels clarifies the scope of the variable.
15+
Labels map[string]string `json:"labels,omitempty"`
16+
}
17+
18+
// UpdateVariableSetRequest represents the update request structure
19+
// for a variable in the variable set.
20+
type UpdateVariableSetRequest struct {
21+
// VariableKey is the access path for the variable.
22+
VariableKey string `json:"variableKey" binding:"required"`
23+
// Value is the value of the variable.
24+
Value string `json:"value" binding:"required"`
25+
// Type is the type of the variable.
26+
Type string `json:"type" binding:"required"`
27+
// Labels clarifies the scope of the variable.
28+
Labels map[string]string `json:"labels" binding:"required"`
29+
// Fqn is the fully qualified name of the variable.
30+
Fqn string `json:"fqn" binding:"required"`
31+
}
32+
33+
// ListVariableSetRequest represents the list request structure
34+
// for variables matched to the labels in the variable set.
35+
type ListVariableSetRequest struct {
36+
// Labels clarifies the scope of the variables.
37+
Labels map[string]string `json:"labels" binding:"required"`
38+
}
39+
40+
func (payload *CreateVariableSetRequest) Decode(r *http.Request) error {
41+
return decode(r, payload)
42+
}
43+
44+
func (payload *UpdateVariableSetRequest) Decode(r *http.Request) error {
45+
return decode(r, payload)
46+
}
47+
48+
func (payload *ListVariableSetRequest) Decode(r *http.Request) error {
49+
return decode(r, payload)
50+
}

pkg/domain/response/variable.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package response
2+
3+
import "kusionstack.io/kusion/pkg/domain/entity"
4+
5+
type PaginatedVariableResponse struct {
6+
Variables []*entity.Variable `json:"variables"`
7+
Total int `json:"total"`
8+
CurrentPage int `json:"currentPage"`
9+
PageSize int `json:"pageSize"`
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package response
2+
3+
import "kusionstack.io/kusion/pkg/domain/entity"
4+
5+
type PaginatedVariableLabelsResponse struct {
6+
VariableLabels []*entity.VariableLabels `json:"variableLabels"`
7+
Total int `json:"total"`
8+
CurrentPage int `json:"currentPage"`
9+
PageSize int `json:"pageSize"`
10+
}

pkg/infra/persistence/types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ var (
2424
ErrAppConfigModelNil = errors.New("appconfig model can't be nil")
2525
ErrFailedToGetModuleRemote = errors.New("failed to parse module remote")
2626
ErrResourceModelNil = errors.New("resource model can't be nil")
27+
ErrVariableLabelsModelNil = errors.New("variable labels model can't be nil")
28+
ErrVariableModelNil = errors.New("variable model can't be nil")
2729
ErrFailedToGetModuleDocRemote = errors.New("failed to parse module doc remote")
2830
ErrRunModelNil = errors.New("run model can't be nil")
2931
ErrFailedToGetRunType = errors.New("failed to parse run type")

pkg/infra/persistence/util.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,34 @@ func GetRunQuery(filter *entity.RunFilter) (string, []interface{}) {
179179
return CombineQueryParts(pattern), args
180180
}
181181

182+
func GetVariableLabelsQuery(filter *entity.VariableLabelsFilter) (string, []interface{}) {
183+
pattern := make([]string, 0)
184+
args := make([]interface{}, 0)
185+
186+
if len(filter.Labels) != 0 {
187+
var labelsPattern []string
188+
for _, label := range filter.Labels {
189+
labelsPattern = append(labelsPattern, "labels LIKE ?")
190+
args = append(args, "%"+label+"%")
191+
}
192+
pattern = append(pattern, "("+strings.Join(labelsPattern, " OR ")+")")
193+
}
194+
195+
return CombineQueryParts(pattern), args
196+
}
197+
198+
func GetVariableQuery(filter *entity.VariableFilter) (string, []interface{}) {
199+
pattern := make([]string, 0)
200+
args := make([]interface{}, 0)
201+
202+
if filter.Key != "" {
203+
pattern = append(pattern, "variable_key = ?")
204+
args = append(args, fmt.Sprintf(filter.Key))
205+
}
206+
207+
return CombineQueryParts(pattern), args
208+
}
209+
182210
func CombineQueryParts(queryParts []string) string {
183211
queryString := ""
184212
if len(queryParts) > 0 {
@@ -218,5 +246,11 @@ func AutoMigrate(db *gorm.DB) error {
218246
if err := db.AutoMigrate(&RunModel{}); err != nil {
219247
return err
220248
}
249+
if err := db.AutoMigrate(&VariableLabelsModel{}); err != nil {
250+
return err
251+
}
252+
if err := db.AutoMigrate(&VariableModel{}); err != nil {
253+
return err
254+
}
221255
return nil
222256
}

0 commit comments

Comments
 (0)