Skip to content

Commit 58e20d3

Browse files
committed
update
1 parent c65d986 commit 58e20d3

File tree

7 files changed

+218
-18
lines changed

7 files changed

+218
-18
lines changed

cmd/manageDeploymentRepo.go

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ import (
1313
)
1414

1515
const (
16-
FlagGitConfig = "git-config"
16+
FlagGitConfig = "git-config"
17+
FlagOcmConfig = "ocm-config"
18+
FlagClusterProvider = "cluster-provider"
19+
FlagServiceProvider = "service-provider"
20+
FlagPlatformService = "platform-service"
1721
)
1822

1923
type LogWriter struct{}
@@ -90,12 +94,46 @@ openmcp-bootstrapper manageDeploymentRepo <componentLocation> <templateDirectory
9094
return fmt.Errorf("failed to apply templates from directory %s: %w", templateDirectory, err)
9195
}
9296

97+
clusterProviders, err := cmd.Flags().GetStringArray(FlagClusterProvider)
98+
if err != nil {
99+
return fmt.Errorf("failed to get cluster providers flag: %w", err)
100+
}
101+
102+
for _, provider := range clusterProviders {
103+
err = deploymentrepo.TemplateClusterProvider(provider, "foo:1.2.3", repo)
104+
if err != nil {
105+
return fmt.Errorf("failed to apply cluster provider %s: %w", provider, err)
106+
}
107+
}
108+
109+
serviceProviders, err := cmd.Flags().GetStringArray(FlagServiceProvider)
110+
if err != nil {
111+
return fmt.Errorf("failed to get service providers flag: %w", err)
112+
}
113+
for _, provider := range serviceProviders {
114+
err = deploymentrepo.TemplateServiceProvider(provider, "foo:1.2.3", repo)
115+
if err != nil {
116+
return fmt.Errorf("failed to apply service provider %s: %w", provider, err)
117+
}
118+
}
119+
120+
platformServices, err := cmd.Flags().GetStringArray(FlagPlatformService)
121+
if err != nil {
122+
return fmt.Errorf("failed to get platform services flag: %w", err)
123+
}
124+
for _, service := range platformServices {
125+
err = deploymentrepo.TemplatePlatformService(service, "foo:1.2.3", repo)
126+
if err != nil {
127+
return fmt.Errorf("failed to apply platform service %s: %w", service, err)
128+
}
129+
}
130+
93131
err = deploymentrepo.CommitChanges(repo, "apply templates", "openmcp", "[email protected]")
94132
if err != nil {
95133
return fmt.Errorf("failed to commit changes: %w", err)
96134
}
97135

98-
err = deploymentrepo.PushRepo(repo, gitConfig)
136+
err = deploymentrepo.PushRepo(repo, deploymentRepositoryBranch, gitConfig)
99137
if err != nil {
100138
return fmt.Errorf("failed to push changes to deployment repository: %w", err)
101139
}
@@ -109,11 +147,11 @@ func init() {
109147

110148
manageDeploymentRepoCmd.Flags().SortFlags = false
111149

112-
manageDeploymentRepoCmd.Flags().StringArray("cluster-providers", nil, "List of cluster providers to manage")
113-
manageDeploymentRepoCmd.Flags().StringArray("serviceProviders", nil, "List of service providers to manage")
114-
manageDeploymentRepoCmd.Flags().StringArray("platformServices", nil, "List of platform services to manage")
150+
manageDeploymentRepoCmd.Flags().StringArray(FlagClusterProvider, nil, "List of cluster providers to manage")
151+
manageDeploymentRepoCmd.Flags().StringArray(FlagServiceProvider, nil, "List of service providers to manage")
152+
manageDeploymentRepoCmd.Flags().StringArray(FlagPlatformService, nil, "List of platform services to manage")
115153

116-
manageDeploymentRepoCmd.Flags().String("ocm-config", "", "ocm configuration file")
154+
manageDeploymentRepoCmd.Flags().String(FlagOcmConfig, "", "ocm configuration file")
117155
manageDeploymentRepoCmd.Flags().String(FlagGitConfig, "", "Git configuration file")
118156

119157
if err := manageDeploymentRepoCmd.MarkFlagRequired(FlagGitConfig); err != nil {

internal/deployment-repo/repo.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,15 @@ func CloneRepo(repoURL, path string, gitConfig *gitconfig.Config) (*git.Reposito
4949

5050
// PushRepo pushes the changes in the given repository to the remote.
5151
// It uses the provided gitConfig to configure the push options with authentication.
52-
func PushRepo(repo *git.Repository, gitConfig *gitconfig.Config) error {
52+
func PushRepo(repo *git.Repository, branch string, gitConfig *gitconfig.Config) error {
5353
logger := log.GetLogger()
5454

5555
logger.Debug("Pushing changes to remote repository")
5656

5757
pushOptions := &git.PushOptions{
58+
RefSpecs: []config.RefSpec{
59+
config.RefSpec(plumbing.HEAD + ":" + plumbing.NewBranchReferenceName(branch)),
60+
},
5861
Progress: gitProgressWriter{},
5962
}
6063

@@ -83,7 +86,6 @@ func CommitChanges(repo *git.Repository, message, name, email string) error {
8386
}
8487

8588
_, err = workTree.Commit(message, &git.CommitOptions{
86-
All: true,
8789
Author: &object.Signature{
8890
Name: name,
8991
Email: email,
@@ -159,14 +161,14 @@ func CheckoutAndCreateBranchIfNotExists(repo *git.Repository, branchName string,
159161
if err != nil && !errors.Is(err, git.NoErrAlreadyUpToDate) {
160162
return fmt.Errorf("failed to push new branch: %w", err)
161163
}
162-
} else {
163-
// Checkout existing branch
164-
err = workTree.Checkout(&git.CheckoutOptions{
165-
Branch: remoteRef,
166-
})
167-
if err != nil {
168-
return fmt.Errorf("failed to checkout branch: %w", err)
169-
}
164+
}
165+
166+
// Checkout existing branch
167+
err = workTree.Checkout(&git.CheckoutOptions{
168+
Branch: remoteRef,
169+
})
170+
if err != nil {
171+
return fmt.Errorf("failed to checkout branch: %w", err)
170172
}
171173

172174
return nil

internal/deployment-repo/templater.go

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package deploymentrepo
22

33
import (
4+
_ "embed"
45
"fmt"
56
"os"
67
"path/filepath"
@@ -65,7 +66,7 @@ func TemplateDir(templateDirectory string, repo *git.Repository) error {
6566
return fmt.Errorf("failed to execute template %s: %w", relativePath, err)
6667
}
6768

68-
fileInWorkTree, errInWalk = workTree.Filesystem.OpenFile(relativePath, os.O_WRONLY|os.O_CREATE, 0644)
69+
fileInWorkTree, errInWalk = workTree.Filesystem.OpenFile(relativePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
6970
if errInWalk != nil {
7071
return fmt.Errorf("failed to open file in worktree %s: %w", relativePath, err)
7172
}
@@ -95,3 +96,76 @@ func TemplateDir(templateDirectory string, repo *git.Repository) error {
9596

9697
return nil
9798
}
99+
100+
var (
101+
//go:embed templates/clusterProvider.yaml
102+
clusterProviderTemplate string
103+
//go:embed templates/serviceProvider.yaml
104+
serviceProviderTemplate string
105+
//go:embed templates/platformService.yaml
106+
platformServiceTemplate string
107+
)
108+
109+
func TemplateClusterProvider(name, image string, repo *git.Repository) error {
110+
return templateProvider(name, image, clusterProviderTemplate, "cluster-providers", repo)
111+
}
112+
113+
func TemplateServiceProvider(name, image string, repo *git.Repository) error {
114+
return templateProvider(name, image, serviceProviderTemplate, "service-providers", repo)
115+
}
116+
117+
func TemplatePlatformService(name, image string, repo *git.Repository) error {
118+
return templateProvider(name, image, platformServiceTemplate, "platform-services", repo)
119+
}
120+
121+
func templateProvider(name, image, templateSource, dir string, repo *git.Repository) error {
122+
logger := log.GetLogger()
123+
providerPath := filepath.Join(dir, name+".yaml")
124+
125+
logger.Debugf("Creating provider %s with image %s in path %s", name, image, providerPath)
126+
127+
te := template.NewTemplateExecution()
128+
templateInput := map[string]interface{}{
129+
"values": map[string]interface{}{
130+
"name": name,
131+
"image": map[string]interface{}{
132+
"location": image,
133+
},
134+
},
135+
}
136+
137+
workTree, err := repo.Worktree()
138+
if err != nil {
139+
return fmt.Errorf("failed to get worktree: %w", err)
140+
}
141+
142+
logger.Tracef("Template input: %v", templateInput)
143+
144+
fileInWorkTree, err := workTree.Filesystem.OpenFile(providerPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
145+
if err != nil {
146+
return fmt.Errorf("failed to open file %s in worktree: %w", providerPath, err)
147+
}
148+
149+
defer func(pathInRepo billy.File) {
150+
err := pathInRepo.Close()
151+
if err != nil {
152+
_, _ = fmt.Fprintf(os.Stderr, "failed to close file in worktree: %v\n", err)
153+
}
154+
}(fileInWorkTree)
155+
156+
templateResult, err := te.Execute(providerPath, templateSource, templateInput)
157+
if err != nil {
158+
return fmt.Errorf("failed to execute templateSource for cluster provider %s: %w", name, err)
159+
}
160+
161+
_, err = fileInWorkTree.Write(templateResult)
162+
if err != nil {
163+
return fmt.Errorf("failed to write to file %s in worktree: %w", providerPath, err)
164+
}
165+
166+
if _, err = workTree.Add(providerPath); err != nil {
167+
return fmt.Errorf("failed to add provider %s file to git index: %w", providerPath, err)
168+
}
169+
170+
return nil
171+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
apiVersion: openmcp.cloud/v1alpha1
2+
kind: ClusterProvider
3+
metadata:
4+
name: "{{ .values.name }}"
5+
spec:
6+
image: "{{ .values.image.location }}"
7+
{{- if dig "image" "pullSecret" "" .values }}
8+
imagePullSecret: "{{ .values.image.pullSecret }}"
9+
{{- end }}
10+
{{- if dig "env" "" .values }}
11+
env:
12+
{{- range $key, $value := .values.env }}
13+
{{ $key }}: {{ $value }}
14+
{{- end }}
15+
{{- end }}
16+
{{- if dig "verbosity" "" .values }}
17+
verbosity: {{ .values.verbosity }}
18+
{{- end }}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
apiVersion: openmcp.cloud/v1alpha1
2+
kind: PlatformService
3+
metadata:
4+
name: "{{ .values.name }}"
5+
spec:
6+
image: "{{ .values.image.location }}"
7+
{{- if dig "image" "pullSecret" "" .values }}
8+
imagePullSecret: "{{ .values.image.pullSecret }}"
9+
{{- end }}
10+
{{- if dig "env" "" .values }}
11+
env:
12+
{{- range $key, $value := .values.env }}
13+
{{ $key }}: {{ $value }}
14+
{{- end }}
15+
{{- end }}
16+
{{- if dig "verbosity" "" .values }}
17+
verbosity: {{ .values.verbosity }}
18+
{{- end }}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
apiVersion: openmcp.cloud/v1alpha1
2+
kind: ServiceProvider
3+
metadata:
4+
name: "{{ .values.name }}"
5+
spec:
6+
image: "{{ .values.image.location }}"
7+
{{- if dig "image" "pullSecret" "" .values }}
8+
imagePullSecret: "{{ .values.image.pullSecret }}"
9+
{{- end }}
10+
{{- if dig "env" "" .values }}
11+
env:
12+
{{- range $key, $value := .values.env }}
13+
{{ $key }}: {{ $value }}
14+
{{- end }}
15+
{{- end }}
16+
{{- if dig "verbosity" "" .values }}
17+
verbosity: {{ .values.verbosity }}
18+
{{- end }}

internal/template/template.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,37 @@ package template
22

33
import (
44
"bytes"
5+
"fmt"
56
gotmpl "text/template"
67
)
78

9+
func dig(args ...interface{}) (interface{}, error) {
10+
if len(args) < 3 {
11+
return nil, fmt.Errorf("dig requires at least 3 arguments, got %d", len(args))
12+
}
13+
14+
dict := args[len(args)-1].(map[string]interface{})
15+
defaultValue := args[len(args)-2]
16+
keys := make([]string, len(args)-2)
17+
for i := 0; i < len(args)-2; i++ {
18+
keys[i] = args[i].(string)
19+
}
20+
21+
return findInDict(dict, defaultValue, keys)
22+
}
23+
24+
func findInDict(dict map[string]interface{}, defaultValue interface{}, keys []string) (interface{}, error) {
25+
currentKey, nextKeys := keys[0], keys[1:]
26+
currentValue, exists := dict[currentKey]
27+
if !exists {
28+
return defaultValue, nil
29+
}
30+
if len(nextKeys) == 0 {
31+
return currentValue, nil
32+
}
33+
return findInDict(currentValue.(map[string]interface{}), defaultValue, nextKeys)
34+
}
35+
836
// TemplateExecution is a struct that provides methods to execute templates with input data.
937
type TemplateExecution struct {
1038
funcMaps []gotmpl.FuncMap
@@ -15,7 +43,11 @@ type TemplateExecution struct {
1543
// NewTemplateExecution creates a new TemplateExecution instance with default settings.
1644
func NewTemplateExecution() *TemplateExecution {
1745
t := &TemplateExecution{
18-
funcMaps: make([]gotmpl.FuncMap, 0),
46+
funcMaps: []gotmpl.FuncMap{
47+
{
48+
"dig": dig,
49+
},
50+
},
1951
templateInputFormatter: NewTemplateInputFormatter(true),
2052
missingKeyOption: "error",
2153
}

0 commit comments

Comments
 (0)