Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: use generic optimization code #455

Merged
merged 1 commit into from
Aug 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func (acg *Generator) GenerateSpec(
}

gfs := []generators.NewGeneratorFunc{}
generators.ForeachOrderedApps(acg.Apps, func(appName string, app appmodel.AppConfiguration) error {
generators.ForeachOrdered(acg.Apps, func(appName string, app appmodel.AppConfiguration) error {
gfs = append(gfs, generators.NewAppConfigurationGeneratorFunc(project.Name, appName, &app))
return nil
})
Expand Down
106 changes: 41 additions & 65 deletions pkg/generator/appconfiguration/generators/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,9 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"kusionstack.io/kusion/pkg/generator"
"kusionstack.io/kusion/pkg/models"
"kusionstack.io/kusion/pkg/models/appconfiguration"
"kusionstack.io/kusion/pkg/models/appconfiguration/workload/container"
)

// kubernetesResourceID returns the unique ID of a Kubernetes resource
// based on its type and metadata.
func kubernetesResourceID(typeMeta metav1.TypeMeta, objectMeta metav1.ObjectMeta) string {
// resource id example: apps/v1:Deployment:code-city:code-citydev
id := typeMeta.APIVersion + ":" + typeMeta.Kind + ":"
if objectMeta.Namespace != "" {
id += objectMeta.Namespace + ":"
}
id += objectMeta.Name
return id
}

// CallGeneratorFuncs calls each NewGeneratorFunc in the given slice
// and returns a slice of Generator instances.
func CallGeneratorFuncs(newGenerators ...NewGeneratorFunc) ([]Generator, error) {
Expand Down Expand Up @@ -53,6 +40,46 @@ func CallGenerators(spec *models.Spec, newGenerators ...NewGeneratorFunc) error
return nil
}

// ForeachOrdered executes the given function on each
// item in the map in order of their keys.
func ForeachOrdered[T any](
m map[string]T,
f func(key string, value T) error,
) error {
keys := make([]string, 0, len(m))
for k := range m {
keys = append(keys, k)
}

sort.Strings(keys)

for _, k := range keys {
v := m[k]
if err := f(k, v); err != nil {
return err
}
}

return nil
}

// IntPtr returns a pointer to the provided value.
func IntPtr[T any](i T) *T {
return &i
}

// kubernetesResourceID returns the unique ID of a Kubernetes resource
// based on its type and metadata.
func kubernetesResourceID(typeMeta metav1.TypeMeta, objectMeta metav1.ObjectMeta) string {
// resource id example: apps/v1:Deployment:code-city:code-citydev
id := typeMeta.APIVersion + ":" + typeMeta.Kind + ":"
if objectMeta.Namespace != "" {
id += objectMeta.Namespace + ":"
}
id += objectMeta.Name
return id
}

// appendToSpec adds a Kubernetes resource to a spec's resources
// slice.
func appendToSpec(resourceID string, resource any, spec *models.Spec) error {
Expand Down Expand Up @@ -86,39 +113,11 @@ func uniqueWorkloadLabels(projectName, appName string) map[string]string {
}
}

// int32Ptr returns a pointer to an int32 value.
func int32Ptr(i int32) *int32 {
return &i
}

// foreachOrderedContainers executes the given function on each
// container in the map in order of their keys.
func foreachOrderedContainers(
m map[string]container.Container,
f func(containerName string, c container.Container) error,
) error {
keys := make([]string, 0, len(m))
for k := range m {
keys = append(keys, k)
}

sort.Strings(keys)

for _, k := range keys {
v := m[k]
if err := f(k, v); err != nil {
return err
}
}

return nil
}

func toOrderedContainers(appContainers map[string]container.Container) ([]corev1.Container, error) {
// Create a slice of containers based on the app's
// containers.
containers := []corev1.Container{}
if err := foreachOrderedContainers(appContainers, func(containerName string, c container.Container) error {
if err := ForeachOrdered(appContainers, func(containerName string, c container.Container) error {
// Create a slice of env vars based on the container's
// envvars.
envs := []corev1.EnvVar{}
Expand All @@ -145,26 +144,3 @@ func toOrderedContainers(appContainers map[string]container.Container) ([]corev1
}
return containers, nil
}

// ForeachOrderedApps executes the given function on each
// app in the map in order of their keys.
func ForeachOrderedApps(
m map[string]appconfiguration.AppConfiguration,
f func(appName string, app appconfiguration.AppConfiguration) error,
) error {
keys := make([]string, 0, len(m))
for k := range m {
keys = append(keys, k)
}

sort.Strings(keys)

for _, k := range keys {
v := m[k]
if err := f(k, v); err != nil {
return err
}
}

return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ func (g *workloadServiceGenerator) Generate(spec *models.Spec) error {
Namespace: g.projectName,
},
Spec: appsv1.DeploymentSpec{
Replicas: int32Ptr(int32(lrs.Replicas)),
Replicas: IntPtr(int32(lrs.Replicas)),
Selector: &metav1.LabelSelector{
MatchLabels: uniqueWorkloadLabels(g.projectName, g.appName),
},
Expand Down
Loading