Skip to content

Commit a994a93

Browse files
committed
refactor template store create form
1 parent 16736d8 commit a994a93

8 files changed

Lines changed: 174 additions & 38 deletions

File tree

cyclops-ctrl/cmd/main/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ func main() {
101101
setupLog.Error(err, "failed to set up prom monitor")
102102
}
103103

104-
renderer := render.NewRenderer(k8sClient, templatesRepo)
104+
renderer := render.NewRenderer(k8sClient)
105105

106106
prometheus.StartCacheMetricsUpdater(&monitor, templatesRepo.ReturnCache(), 10*time.Second, setupLog)
107107

cyclops-ctrl/internal/controller/modules.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,8 +654,8 @@ func (m *Modules) ResourcesForModule(ctx *gin.Context) {
654654
t, err := m.templatesRepo.GetTemplate(
655655
module.Spec.TemplateRef.URL,
656656
module.Spec.TemplateRef.Path,
657+
templateVersion,
657658
module.Status.TemplateResolvedVersion,
658-
"",
659659
module.Spec.TemplateRef.SourceType,
660660
)
661661
if err != nil {

cyclops-ctrl/internal/git/writeclient.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,10 @@ func (c *WriteClient) Write(module cyclopsv1alpha1.Module) error {
9999
return err
100100
}
101101

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

cyclops-ctrl/internal/mapper/templatestore.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,15 @@ func TemplateStoreListToDTO(store []v1alpha1.TemplateStore) []dto.TemplateStore
4242
}
4343

4444
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+
4554
return &v1alpha1.TemplateStore{
4655
TypeMeta: metav1.TypeMeta{
4756
Kind: "TemplateStore",
@@ -54,10 +63,11 @@ func DTOToTemplateStore(store dto.TemplateStore, iconURL string) *v1alpha1.Templ
5463
},
5564
},
5665
Spec: v1alpha1.TemplateRef{
57-
URL: store.TemplateRef.URL,
58-
Path: store.TemplateRef.Path,
59-
Version: store.TemplateRef.Version,
60-
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,
6171
},
6272
}
6373
}

cyclops-ctrl/pkg/template/render/render.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,15 @@ import (
1313
"github.com/cyclops-ui/cyclops/cyclops-ctrl/internal/models"
1414
"github.com/cyclops-ui/cyclops/cyclops-ctrl/internal/models/helm"
1515
"github.com/cyclops-ui/cyclops/cyclops-ctrl/pkg/cluster/k8sclient"
16-
"github.com/cyclops-ui/cyclops/cyclops-ctrl/pkg/template"
1716
)
1817

1918
type Renderer struct {
20-
k8sClient k8sclient.IKubernetesClient
21-
templateRepo template.ITemplateRepo
19+
k8sClient k8sclient.IKubernetesClient
2220
}
2321

24-
func NewRenderer(kubernetesClient k8sclient.IKubernetesClient, templateRepo template.ITemplateRepo) *Renderer {
22+
func NewRenderer(kubernetesClient k8sclient.IKubernetesClient) *Renderer {
2523
return &Renderer{
26-
k8sClient: kubernetesClient,
27-
templateRepo: templateRepo,
24+
k8sClient: kubernetesClient,
2825
}
2926
}
3027

cyclops-ui/src/components/pages/TemplateStore/TemplateStore.tsx

Lines changed: 131 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ import {
1515
Radio,
1616
Popover,
1717
Checkbox,
18+
Switch,
1819
} from "antd";
1920
import axios from "axios";
20-
import Title from "antd/es/typography/Title";
2121
import {
2222
DeleteOutlined,
2323
EditOutlined,
@@ -36,8 +36,12 @@ import {
3636
import gitLogo from "../../../static/img/git.png";
3737
import helmLogo from "../../../static/img/helm.png";
3838
import dockerLogo from "../../../static/img/docker-mark-blue.png";
39+
import { useTheme } from "../../theme/ThemeContext";
40+
import Title from "antd/es/typography/Title";
3941

4042
const TemplateStore = () => {
43+
const { mode } = useTheme();
44+
4145
const [templates, setTemplates] = useState([]);
4246
const [query, setQuery] = useState("");
4347
const [filteredTemplates, setFilteredTemplates] = useState([]);
@@ -52,6 +56,7 @@ const TemplateStore = () => {
5256
const [requestStatus, setRequestStatus] = useState<{ [key: string]: string }>(
5357
{},
5458
);
59+
const [enforceGitOpsEnabled, setEnforceGitOpsEnabled] = useState(false);
5560
const [error, setError] = useState({
5661
message: "",
5762
description: "",
@@ -274,6 +279,73 @@ const TemplateStore = () => {
274279
);
275280
};
276281

282+
const advancedTemplateGitOpsWrite = () => {
283+
return (
284+
<div
285+
style={{
286+
backgroundColor: mode === "light" ? "#fafafa" : "#333",
287+
border: `1px solid ${mode === "light" ? "#c3c3c3" : "#707070"}`,
288+
borderRadius: "7px",
289+
padding: "16px",
290+
marginTop: "24px",
291+
}}
292+
>
293+
<div style={{ marginBottom: "16px" }}>
294+
<div
295+
style={{
296+
display: "flex",
297+
alignItems: "center",
298+
gap: "12px",
299+
marginBottom: "8px",
300+
}}
301+
>
302+
<Switch
303+
checked={enforceGitOpsEnabled}
304+
onChange={setEnforceGitOpsEnabled}
305+
/>
306+
<div style={{ margin: 0 }}>Enforce GitOps Write</div>
307+
</div>
308+
<p style={{ color: "#8b8e91", margin: "4px 0 0 0" }}>
309+
Configure GitOps settings to push changes to a git repository
310+
instead of deploying directly to the cluster.
311+
</p>
312+
</div>
313+
{enforceGitOpsEnabled && (
314+
<>
315+
<Form.Item
316+
label="Repository URL"
317+
name={["enforceGitOpsWrite", "repo"]}
318+
labelCol={{ span: 24 }}
319+
wrapperCol={{ span: 24 }}
320+
style={{ marginBottom: 8 }}
321+
>
322+
<Input placeholder="https://github.com/org/repo" />
323+
</Form.Item>
324+
325+
<Form.Item
326+
label="Path"
327+
name={["enforceGitOpsWrite", "path"]}
328+
labelCol={{ span: 24 }}
329+
wrapperCol={{ span: 24 }}
330+
style={{ marginBottom: 8 }}
331+
>
332+
<Input placeholder="/path/to/templates" />
333+
</Form.Item>
334+
335+
<Form.Item
336+
label="Branch"
337+
name={["enforceGitOpsWrite", "branch"]}
338+
labelCol={{ span: 24 }}
339+
wrapperCol={{ span: 24 }}
340+
>
341+
<Input placeholder="main" />
342+
</Form.Item>
343+
</>
344+
)}
345+
</div>
346+
);
347+
};
348+
277349
return (
278350
<div>
279351
{error.message.length !== 0 && (
@@ -432,15 +504,12 @@ const TemplateStore = () => {
432504
<EditOutlined
433505
className={"edittemplate"}
434506
onClick={function () {
435-
editForm.setFieldValue(
436-
["ref", "sourceType"],
437-
template.ref.sourceType,
438-
);
439-
editForm.setFieldValue(["ref", "repo"], template.ref.repo);
440-
editForm.setFieldValue(["ref", "path"], template.ref.path);
441-
editForm.setFieldValue(
442-
["ref", "version"],
443-
template.ref.version,
507+
editForm.setFieldsValue(template);
508+
if (template.enforceGitOpsWrite === undefined) {
509+
editForm.setFieldValue(["enforceGitOpsWrite"], undefined);
510+
}
511+
setEnforceGitOpsEnabled(
512+
template.enforceGitOpsWrite !== undefined,
444513
);
445514
setEditModal(template.name);
446515
}}
@@ -491,10 +560,23 @@ const TemplateStore = () => {
491560
onFinish={handleSubmit}
492561
form={addForm}
493562
initialValues={{ remember: true }}
494-
labelCol={{ span: 6 }}
563+
labelCol={{ span: 24 }}
564+
wrapperCol={{ span: 24 }}
565+
requiredMark={(label, { required }) => (
566+
<Row>
567+
<Col>
568+
{required ? (
569+
<span style={{ color: "red", paddingRight: "3px" }}>*</span>
570+
) : (
571+
<></>
572+
)}
573+
</Col>
574+
<Col>{label}</Col>
575+
</Row>
576+
)}
495577
>
496578
<Form.Item
497-
style={{ paddingTop: "20px" }}
579+
style={{ marginBottom: "12px" }}
498580
label="Name"
499581
name={"name"}
500582
rules={[
@@ -508,7 +590,7 @@ const TemplateStore = () => {
508590
"Template ref name must contain no more than 63 characters",
509591
},
510592
{
511-
pattern: /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/, // only alphanumeric characters and hyphens, cannot start or end with a hyphen and the alpha characters can only be lowercase
593+
pattern: /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/,
512594
message:
513595
"Template ref name must follow the Kubernetes naming convention",
514596
},
@@ -517,11 +599,12 @@ const TemplateStore = () => {
517599
<Input />
518600
</Form.Item>
519601

520-
<Divider />
602+
<Divider style={{ margin: "12px 0" }} />
521603

522604
<Form.Item
523605
name={["ref", "sourceType"]}
524606
label="Select template source"
607+
style={{ marginBottom: "12px" }}
525608
>
526609
<Radio.Group
527610
optionType="button"
@@ -551,6 +634,7 @@ const TemplateStore = () => {
551634
label="Repository URL"
552635
name={["ref", "repo"]}
553636
rules={[{ required: true, message: "Repo URL is required" }]}
637+
style={{ marginBottom: "12px" }}
554638
>
555639
<Input />
556640
</Form.Item>
@@ -559,13 +643,20 @@ const TemplateStore = () => {
559643
label="Path"
560644
name={["ref", "path"]}
561645
rules={[{ required: true, message: "Path is required" }]}
646+
style={{ marginBottom: "12px" }}
562647
>
563648
<Input />
564649
</Form.Item>
565650

566-
<Form.Item label="Version" name={["ref", "version"]}>
651+
<Form.Item
652+
label="Version"
653+
name={["ref", "version"]}
654+
style={{ marginBottom: "12px" }}
655+
>
567656
<Input />
568657
</Form.Item>
658+
659+
{advancedTemplateGitOpsWrite()}
569660
</Form>
570661
</Modal>
571662
<Modal
@@ -597,15 +688,29 @@ const TemplateStore = () => {
597688
/>
598689
)}
599690
<Form
600-
style={{ paddingTop: "50px" }}
691+
style={{ paddingTop: "24px" }}
601692
onFinish={handleUpdateSubmit}
602693
form={editForm}
603694
initialValues={{ remember: false }}
604-
labelCol={{ span: 6 }}
695+
labelCol={{ span: 24 }}
696+
wrapperCol={{ span: 24 }}
697+
requiredMark={(label, { required }) => (
698+
<Row>
699+
<Col>
700+
{required ? (
701+
<span style={{ color: "red", paddingRight: "3px" }}>*</span>
702+
) : (
703+
<></>
704+
)}
705+
</Col>
706+
<Col>{label}</Col>
707+
</Row>
708+
)}
605709
>
606710
<Form.Item
607711
name={["ref", "sourceType"]}
608712
label="Select template source"
713+
style={{ marginBottom: "12px" }}
609714
>
610715
<Radio.Group
611716
optionType="button"
@@ -630,10 +735,12 @@ const TemplateStore = () => {
630735
</Radio>
631736
</Radio.Group>
632737
</Form.Item>
738+
633739
<Form.Item
634740
label="Repository URL"
635741
name={["ref", "repo"]}
636742
rules={[{ required: true, message: "Repo URL is required" }]}
743+
style={{ marginBottom: "12px" }}
637744
>
638745
<Input />
639746
</Form.Item>
@@ -642,13 +749,19 @@ const TemplateStore = () => {
642749
label="Path"
643750
name={["ref", "path"]}
644751
rules={[{ required: true, message: "Path is required" }]}
752+
style={{ marginBottom: "12px" }}
645753
>
646754
<Input />
647755
</Form.Item>
648756

649-
<Form.Item label="Version" name={["ref", "version"]}>
757+
<Form.Item
758+
label="Version"
759+
name={["ref", "version"]}
760+
style={{ marginBottom: "12px" }}
761+
>
650762
<Input />
651763
</Form.Item>
764+
{advancedTemplateGitOpsWrite()}
652765
</Form>
653766
</Modal>
654767
<Modal

cyclops-ui/src/components/pages/TemplateStore/custom.css

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,16 @@
4646
margin-right: 8px; /* Add space between the image and the text */
4747
padding-bottom: 3px;
4848
}
49+
50+
.expandadvanced {
51+
width: 100%;
52+
height: 32px;
53+
border-radius: 0 0 7px 7px;
54+
background-color: red;
55+
transition: background-color 0.2s ease;
56+
display: flex;
57+
justify-content: center;
58+
align-items: center;
59+
text-align: center;
60+
cursor: pointer;
61+
}

0 commit comments

Comments
 (0)