Skip to content

Commit deb416c

Browse files
authored
πŸ— enforce gitops write on template store CRD #793
enforce gitops write on template store CRD
2 parents 0ad3fec + 6a93527 commit deb416c

File tree

12 files changed

+322
-65
lines changed

12 files changed

+322
-65
lines changed

β€Žcyclops-ctrl/api/v1alpha1/module_types.goβ€Ž

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ const (
5656
ResourceFinalizer = "cyclops-ui.com/module-resources"
5757
)
5858

59+
type GitOpsWriteDestination struct {
60+
Repo string `json:"repo"`
61+
Path string `json:"path"`
62+
Version string `json:"version"`
63+
}
64+
5965
type TemplateRef struct {
6066
URL string `json:"repo"`
6167
Path string `json:"path"`
@@ -64,6 +70,9 @@ type TemplateRef struct {
6470
// +kubebuilder:validation:Enum=git;helm;oci
6571
// +kubebuilder:validation:Optional
6672
SourceType TemplateSourceType `json:"sourceType,omitempty"`
73+
74+
// +kubebuilder:validation:Optional
75+
EnforceGitOpsWrite *GitOpsWriteDestination `json:"enforceGitOpsWrite,omitempty"`
6776
}
6877

6978
type TemplateGitRef struct {

β€Žcyclops-ctrl/api/v1alpha1/zz_generated.deepcopy.goβ€Ž

Lines changed: 22 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

β€Žcyclops-ctrl/config/crd/bases/cyclops-ui.com_modules.yamlβ€Ž

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,19 @@ spec:
104104
type: string
105105
template:
106106
properties:
107+
enforceGitOpsWrite:
108+
properties:
109+
path:
110+
type: string
111+
repo:
112+
type: string
113+
version:
114+
type: string
115+
required:
116+
- path
117+
- repo
118+
- version
119+
type: object
107120
path:
108121
type: string
109122
repo:

β€Žcyclops-ctrl/config/crd/bases/cyclops-ui.com_templatestores.yamlβ€Ž

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,19 @@ spec:
5555
type: object
5656
spec:
5757
properties:
58+
enforceGitOpsWrite:
59+
properties:
60+
path:
61+
type: string
62+
repo:
63+
type: string
64+
version:
65+
type: string
66+
required:
67+
- path
68+
- repo
69+
- version
70+
type: object
5871
path:
5972
type: string
6073
repo:

β€Žcyclops-ctrl/internal/git/writeclient.goβ€Ž

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@ import (
44
"bytes"
55
"errors"
66
"fmt"
7+
json "github.com/json-iterator/go"
78
path2 "path"
89
"text/template"
910
"time"
1011

11-
"github.com/cyclops-ui/cyclops/cyclops-ctrl/pkg/auth"
1212
"github.com/go-logr/logr"
1313

14-
cyclopsv1alpha1 "github.com/cyclops-ui/cyclops/cyclops-ctrl/api/v1alpha1"
1514
"github.com/go-git/go-billy/v5"
1615
"github.com/go-git/go-billy/v5/memfs"
1716
"github.com/go-git/go-git/v5"
@@ -20,6 +19,9 @@ import (
2019
"github.com/go-git/go-git/v5/plumbing/transport/http"
2120
"github.com/go-git/go-git/v5/storage/memory"
2221
"sigs.k8s.io/yaml"
22+
23+
cyclopsv1alpha1 "github.com/cyclops-ui/cyclops/cyclops-ctrl/api/v1alpha1"
24+
"github.com/cyclops-ui/cyclops/cyclops-ctrl/pkg/auth"
2325
)
2426

2527
type WriteClient struct {
@@ -50,6 +52,32 @@ func getCommitMessageTemplate(commitMessageTemplate string, logger logr.Logger)
5052
return tmpl
5153
}
5254

55+
func getModulePath(module cyclopsv1alpha1.Module) (string, error) {
56+
path := module.GetAnnotations()[cyclopsv1alpha1.GitOpsWritePathAnnotation]
57+
58+
tmpl, err := template.New("modulePath").Parse(path)
59+
if err != nil {
60+
return "", err
61+
}
62+
63+
moduleMap := make(map[string]interface{})
64+
moduleData, err := json.Marshal(module)
65+
if err != nil {
66+
return "", err
67+
}
68+
if err := json.Unmarshal(moduleData, &moduleMap); err != nil {
69+
return "", err
70+
}
71+
72+
var o bytes.Buffer
73+
err = tmpl.Execute(&o, moduleMap)
74+
if err != nil {
75+
return "", err
76+
}
77+
78+
return o.String(), nil
79+
}
80+
5381
func (c *WriteClient) Write(module cyclopsv1alpha1.Module) error {
5482
module.Status.ReconciliationStatus = nil
5583
module.Status.ManagedGVRs = nil
@@ -59,14 +87,22 @@ func (c *WriteClient) Write(module cyclopsv1alpha1.Module) error {
5987
return errors.New(fmt.Sprintf("module passed to write without git repository; set cyclops-ui.com/write-repo annotation in module %v", module.Name))
6088
}
6189

62-
path := module.GetAnnotations()[cyclopsv1alpha1.GitOpsWritePathAnnotation]
90+
path, err := getModulePath(module)
91+
if err != nil {
92+
return err
93+
}
94+
6395
revision := module.GetAnnotations()[cyclopsv1alpha1.GitOpsWriteRevisionAnnotation]
6496

6597
creds, err := c.templatesResolver.RepoAuthCredentials(repoURL)
6698
if err != nil {
6799
return err
68100
}
69101

102+
if creds == nil {
103+
return errors.New(fmt.Sprintf("failed to fetch creds for repo %v: check template auth rules", repoURL))
104+
}
105+
70106
storer := memory.NewStorage()
71107
fs := memfs.New()
72108

β€Žcyclops-ctrl/internal/mapper/templatestore.goβ€Ž

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@ func TemplateStoreListToDTO(store []v1alpha1.TemplateStore) []dto.TemplateStore
1616
iconURL = templateStore.GetAnnotations()[v1alpha1.IconURLAnnotation]
1717
}
1818

19+
var enforceGitOpsWrite *dto.GitOpsWrite
20+
if templateStore.Spec.EnforceGitOpsWrite != nil {
21+
enforceGitOpsWrite = &dto.GitOpsWrite{
22+
Repo: templateStore.Spec.EnforceGitOpsWrite.Repo,
23+
Path: templateStore.Spec.EnforceGitOpsWrite.Path,
24+
Branch: templateStore.Spec.EnforceGitOpsWrite.Version,
25+
}
26+
}
27+
1928
out = append(out, dto.TemplateStore{
2029
Name: templateStore.Name,
2130
IconURL: iconURL,
@@ -25,13 +34,23 @@ func TemplateStoreListToDTO(store []v1alpha1.TemplateStore) []dto.TemplateStore
2534
Version: templateStore.Spec.Version,
2635
SourceType: string(templateStore.Spec.SourceType),
2736
},
37+
EnforceGitOpsWrite: enforceGitOpsWrite,
2838
})
2939
}
3040

3141
return out
3242
}
3343

3444
func DTOToTemplateStore(store dto.TemplateStore, iconURL string) *v1alpha1.TemplateStore {
45+
var enforceGitOpsWrite *v1alpha1.GitOpsWriteDestination
46+
if store.EnforceGitOpsWrite != nil {
47+
enforceGitOpsWrite = &v1alpha1.GitOpsWriteDestination{
48+
Repo: store.EnforceGitOpsWrite.Repo,
49+
Path: store.EnforceGitOpsWrite.Path,
50+
Version: store.EnforceGitOpsWrite.Branch,
51+
}
52+
}
53+
3554
return &v1alpha1.TemplateStore{
3655
TypeMeta: metav1.TypeMeta{
3756
Kind: "TemplateStore",
@@ -44,10 +63,11 @@ func DTOToTemplateStore(store dto.TemplateStore, iconURL string) *v1alpha1.Templ
4463
},
4564
},
4665
Spec: v1alpha1.TemplateRef{
47-
URL: store.TemplateRef.URL,
48-
Path: store.TemplateRef.Path,
49-
Version: store.TemplateRef.Version,
50-
SourceType: v1alpha1.TemplateSourceType(store.TemplateRef.SourceType),
66+
URL: store.TemplateRef.URL,
67+
Path: store.TemplateRef.Path,
68+
Version: store.TemplateRef.Version,
69+
SourceType: v1alpha1.TemplateSourceType(store.TemplateRef.SourceType),
70+
EnforceGitOpsWrite: enforceGitOpsWrite,
5171
},
5272
}
5373
}
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package dto
22

33
type TemplateStore struct {
4-
Name string `json:"name" binding:"required"`
5-
IconURL string `json:"iconURL"`
6-
TemplateRef Template `json:"ref"`
4+
Name string `json:"name" binding:"required"`
5+
IconURL string `json:"iconURL"`
6+
TemplateRef Template `json:"ref"`
7+
EnforceGitOpsWrite *GitOpsWrite `json:"enforceGitOpsWrite,omitempty"`
78
}

β€Žcyclops-ctrl/internal/modulecontroller/module_controller.goβ€Ž

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -91,13 +91,6 @@ func NewModuleReconciler(
9191

9292
// Reconcile is part of the main kubernetes reconciliation loop which aims to
9393
// move the current state of the cluster closer to the desired state.
94-
// TODO(user): Modify the Reconcile function to compare the state specified by
95-
// the Module object against the actual cluster state, and then
96-
// perform operations to make the cluster state reflect the state specified by
97-
// the user.
98-
//
99-
// For more details, check Reconcile and its Result here:
100-
// - https://pkg.go.dev/sigs.k8s.io/[email protected]/pkg/reconcile
10194
func (r *ModuleReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
10295
_ = log.FromContext(ctx)
10396
r.telemetryClient.ModuleReconciliation()

β€Žcyclops-ui/src/components/pages/Modules/Modules.tsxβ€Ž

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ const Modules = () => {
107107
const handleClick = () => {
108108
window.location.href = "/modules/new";
109109
};
110+
110111
const handleSelectItem = (selectedItems: any[]) => {
111112
setModuleHealthFilter(selectedItems);
112113
};

0 commit comments

Comments
Β (0)