Skip to content

Commit

Permalink
feat: workload generator support create contentFrom based file
Browse files Browse the repository at this point in the history
  • Loading branch information
adohe committed Mar 5, 2024
1 parent b991801 commit 24447d5
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 4 deletions.
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
62 changes: 59 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)
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,41 @@ func completeBaseWorkload(base *workload.Base, config apiv1.GenericConfig) error
}
return nil
}

type secretReference struct {
Name string
Key string
}

func parseSecretReference(s string) (result secretReference, _ bool, _ error) {
if strings.HasPrefix(s, "${secret://") && strings.HasSuffix(s, "}") {
s = s[2 : len(s)-1]
}

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

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

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

/*q := u.Query()
for k, v := range q {
for _, v := range v {
if strings.EqualFold(k, "mode") {
_, err := strconv.ParseInt(v, 8, 32)
if err != nil {
return result, false, fmt.Errorf("invalid file mode %s: %w", v, err)
}
result.Mode = v
}
}
}*/

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) {