Skip to content

Commit

Permalink
feat: support customize namespace through workspace config (#704)
Browse files Browse the repository at this point in the history
  • Loading branch information
adohe committed Dec 20, 2023
1 parent 816225b commit 401821c
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 9 deletions.
2 changes: 1 addition & 1 deletion pkg/modules/generators/app_configurations_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ func (g *appConfigurationGenerator) Generate(i *intent.Intent) error {

// Generate resources
gfs := []modules.NewGeneratorFunc{
NewNamespaceGeneratorFunc(g.project.Name),
NewNamespaceGeneratorFunc(g.project.Name, g.ws),
accessories.NewDatabaseGeneratorFunc(g.project, g.stack, g.appName, g.app.Workload, g.app.Database),
workload.NewWorkloadGeneratorFunc(g.project, g.stack, g.appName, g.app.Workload),
trait.NewOpsRuleGeneratorFunc(g.project, g.stack, g.appName, g.app),
Expand Down
42 changes: 36 additions & 6 deletions pkg/modules/generators/namespace_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,34 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"kusionstack.io/kusion/pkg/apis/intent"
workspaceapi "kusionstack.io/kusion/pkg/apis/workspace"
"kusionstack.io/kusion/pkg/modules"
"kusionstack.io/kusion/pkg/workspace"
)

type namespaceGenerator struct {
projectName string
projectName string
moduleInputs map[string]workspaceapi.GenericConfig
}

func NewNamespaceGenerator(projectName string) (modules.Generator, error) {
func NewNamespaceGenerator(projectName string, ws *workspaceapi.Workspace) (modules.Generator, error) {
if len(projectName) == 0 {
return nil, fmt.Errorf("project name must not be empty")
}
moduleInputs, err := workspace.GetProjectModuleConfigs(ws.Modules, projectName)
if err != nil {
return nil, fmt.Errorf("parse project matched module configs failed: %v", err)
}

return &namespaceGenerator{
projectName: projectName,
projectName: projectName,
moduleInputs: moduleInputs,
}, nil
}

func NewNamespaceGeneratorFunc(projectName string) modules.NewGeneratorFunc {
func NewNamespaceGeneratorFunc(projectName string, workspace *workspaceapi.Workspace) modules.NewGeneratorFunc {
return func() (modules.Generator, error) {
return NewNamespaceGenerator(projectName)
return NewNamespaceGenerator(projectName, workspace)
}
}

Expand All @@ -40,7 +48,7 @@ func (g *namespaceGenerator) Generate(i *intent.Intent) error {
Kind: "Namespace",
APIVersion: v1.SchemeGroupVersion.String(),
},
ObjectMeta: metav1.ObjectMeta{Name: g.projectName},
ObjectMeta: metav1.ObjectMeta{Name: g.getName(g.projectName)},
}

// Avoid generating duplicate namespaces with the same ID.
Expand All @@ -53,3 +61,25 @@ func (g *namespaceGenerator) Generate(i *intent.Intent) error {

return modules.AppendToIntent(intent.Kubernetes, id, i, ns)
}

// getName obtains the name for this Namespace using the following precedence
// (from lower to higher):
// - Project name
// - Namespace module config (specified in corresponding workspace file)
func (g *namespaceGenerator) getName(projectName string) string {
if g.moduleInputs == nil {
return projectName
}

namespaceName := projectName
namespaceModuleConfigs, exist := g.moduleInputs["namespace"]
if exist {
if name, ok := namespaceModuleConfigs["name"]; ok {
customNamespaceName, isString := name.(string)
if isString && len(customNamespaceName) > 0 {
namespaceName = customNamespaceName
}
}
}
return namespaceName
}
81 changes: 79 additions & 2 deletions pkg/modules/generators/namespace_generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import (
"github.com/stretchr/testify/require"

"kusionstack.io/kusion/pkg/apis/intent"
"kusionstack.io/kusion/pkg/apis/workspace"
)

func Test_namespaceGenerator_Generate(t *testing.T) {
type fields struct {
projectName string
projectName string
moduleInputs map[string]workspace.GenericConfig
}
type args struct {
intent *intent.Intent
Expand Down Expand Up @@ -54,11 +56,86 @@ func Test_namespaceGenerator_Generate(t *testing.T) {
},
wantErr: false,
},
{
name: "customize_namespace",
fields: fields{
projectName: "beep",
moduleInputs: map[string]workspace.GenericConfig{
"namespace": {
"name": "foo",
},
},
},
args: args{
intent: &intent.Intent{},
},
want: &intent.Intent{
Resources: []intent.Resource{
{
ID: "v1:Namespace:foo",
Type: "Kubernetes",
Attributes: map[string]interface{}{
"apiVersion": "v1",
"kind": "Namespace",
"metadata": map[string]interface{}{
"creationTimestamp": nil,
"name": "foo",
},
"spec": make(map[string]interface{}),
"status": make(map[string]interface{}),
},
DependsOn: nil,
Extensions: map[string]interface{}{
"GVK": "/v1, Kind=Namespace",
},
},
},
},
wantErr: false,
},
{
name: "mismatch_module_input",
fields: fields{
projectName: "beep",
moduleInputs: map[string]workspace.GenericConfig{
"namespace": {
"type": "foo",
},
},
},
args: args{
intent: &intent.Intent{},
},
want: &intent.Intent{
Resources: []intent.Resource{
{
ID: "v1:Namespace:beep",
Type: "Kubernetes",
Attributes: map[string]interface{}{
"apiVersion": "v1",
"kind": "Namespace",
"metadata": map[string]interface{}{
"creationTimestamp": nil,
"name": "beep",
},
"spec": make(map[string]interface{}),
"status": make(map[string]interface{}),
},
DependsOn: nil,
Extensions: map[string]interface{}{
"GVK": "/v1, Kind=Namespace",
},
},
},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := &namespaceGenerator{
projectName: tt.fields.projectName,
projectName: tt.fields.projectName,
moduleInputs: tt.fields.moduleInputs,
}
if err := g.Generate(tt.args.intent); (err != nil) != tt.wantErr {
t.Errorf("Generate() error = %v, wantErr %v", err, tt.wantErr)
Expand Down

0 comments on commit 401821c

Please sign in to comment.