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

feat: workload generator support create contentFrom based file #875

Merged
merged 1 commit into from
Mar 9, 2024
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
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ require (
google.golang.org/protobuf v1.31.0
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
k8s.io/klog/v2 v2.100.1
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect
lukechampine.com/frand v1.4.2 // indirect
oras.land/oras-go v1.2.3 // indirect
Expand Down
52 changes: 49 additions & 3 deletions pkg/modules/generators/workload/workload_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package workload
import (
"fmt"
"net/url"
"path"
"path/filepath"
"strconv"
"strings"
Expand Down Expand Up @@ -350,7 +351,6 @@ func handleFileCreation(c container.Container, uniqueAppName, containerName stri
) {
var idx int
err = modules.ForeachOrdered(c.Files, func(k string, v container.FileSpec) error {
// for k, v := range c.Files {
// The declared file path needs to include the file name.
if filepath.Base(k) == "." || filepath.Base(k) == "/" {
return fmt.Errorf("the declared file path needs to include the file name")
Expand All @@ -369,8 +369,26 @@ func handleFileCreation(c container.Container, uniqueAppName, containerName stri
}

if v.ContentFrom != "" {
// TODO: support the creation of the file content from a reference source.
panic("not supported the creation the file content from a reference source")
sec, ok, err := parseSecretReference(v.ContentFrom)
adohe marked this conversation as resolved.
Show resolved Hide resolved
if err != nil || !ok {
return fmt.Errorf("invalid content from str")
}

volumes = append(volumes, corev1.Volume{
Name: sec.Name,
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: sec.Name,
DefaultMode: &modeInt32,
},
},
})

volumeMounts = append(volumeMounts, corev1.VolumeMount{
Name: sec.Name,
MountPath: path.Join("/", k),
SubPath: sec.Key,
})
} else if v.Content != "" {
// Create the file content with configMap.
data := make(map[string]string)
Expand Down Expand Up @@ -440,3 +458,31 @@ func completeBaseWorkload(base *workload.Base, config apiv1.GenericConfig) error
}
return nil
}

type secretReference struct {
Name string
Key string
}

// parseSecretReference takes secret reference string as parameter and returns secretReference obj.
// Parameter `ref` is expected in following format: secret://sec-name/key, if the provided ref str
// is not in valid format, this function will return false or err.
func parseSecretReference(ref string) (result secretReference, _ bool, _ error) {
if strings.HasPrefix(ref, "${secret://") && strings.HasSuffix(ref, "}") {
ref = ref[2 : len(ref)-1]
}

if !strings.HasPrefix(ref, "secret://") {
return result, false, nil
}

u, err := url.Parse(ref)
if err != nil {
return result, false, err
}

result.Name = u.Host
result.Key, _, _ = strings.Cut(strings.TrimPrefix(u.Path, "/"), "/")

return result, true, nil
}
52 changes: 52 additions & 0 deletions pkg/modules/generators/workload/workload_generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,58 @@ func TestWorkloadGenerator_Generate(t *testing.T) {
}
}

func TestGenerate(t *testing.T) {
testCases := []struct {
name string
project string
stack string
application string
workload *workload.Workload
}{
{
name: "simple service workload",
project: "helloworld",
stack: "dev",
application: "nginx",
workload: &workload.Workload{
Header: workload.Header{
Type: workload.TypeService,
},
Service: &workload.Service{
Base: workload.Base{
Containers: map[string]container.Container{
"main": {
Image: "nginx:latest",
Files: map[string]container.FileSpec{
"/run/secret/password": {
ContentFrom: "secret://sec-name/key?mode=0400",
Mode: "0644",
},
},
},
},
},
Type: workload.Deployment,
},
},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
g := &Generator{
Project: tc.project,
Stack: tc.stack,
App: tc.application,
Workload: tc.workload,
}
spec := &apiv1.Intent{}
err := g.Generate(spec)
assert.NoError(t, err, "Error should be nil")
})
}
}

func TestToOrderedContainers(t *testing.T) {
t.Run("toOrderedContainers should convert app containers to ordered containers", func(t *testing.T) {
appContainers := make(map[string]container.Container)
Expand Down
Loading