Skip to content
This repository was archived by the owner on Mar 9, 2025. It is now read-only.

Commit 6b8a592

Browse files
committed
Image widget edit
1 parent 9b7e94e commit 6b8a592

File tree

8 files changed

+102
-88
lines changed

8 files changed

+102
-88
lines changed

cmd/agent/agent.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ func serverCommunication(
284284
var imageBuildRequest dx.ImageBuildRequest
285285
_ = json.Unmarshal(requestString, &imageBuildRequest)
286286

287-
if imageBuildRequest.Dockerfile != "" {
287+
if imageBuildRequest.Strategy == "dockerfile" {
288288
go dockerfileImageBuild(kubeEnv, gimletHost, buildId, imageBuildRequest, messages)
289289
} else {
290290
go buildImage(gimletHost, agentKey, buildId, imageBuildRequest, messages, config.ImageBuilderHost)

pkg/dashboard/server/api.go

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -301,28 +301,17 @@ func stackConfig(w http.ResponseWriter, r *http.Request) {
301301
return
302302
}
303303

304-
var stackConfig *dx.StackConfig
305304
stackYamlPath := "stack.yaml"
306305
if !env.RepoPerEnv {
307306
stackYamlPath = filepath.Join(env.Name, "stack.yaml")
308307
}
309308

310309
gitRepoCache, _ := r.Context().Value("gitRepoCache").(*nativeGit.RepoCache)
311-
err = gitRepoCache.PerformAction(env.InfraRepo, func(repo *git.Repository) error {
312-
var inerErr error
313-
stackConfig, inerErr = stackYaml(repo, stackYamlPath)
314-
return inerErr
315-
})
310+
stackConfig, err := StackConfig(gitRepoCache, stackYamlPath, env.InfraRepo)
316311
if err != nil {
317-
if !strings.Contains(err.Error(), "file not found") {
318-
logrus.Errorf("cannot get stack yaml from repo: %s", err)
319-
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
320-
return
321-
} else {
322-
logrus.Errorf("cannot get repo: %s", err)
323-
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
324-
return
325-
}
312+
logrus.Errorf("cannot get stack config: %s", err)
313+
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
314+
return
326315
}
327316

328317
stackDefinition, err := loadStackDefinition(stackConfig)
@@ -349,6 +338,23 @@ func stackConfig(w http.ResponseWriter, r *http.Request) {
349338
w.Write(gitopsEnvString)
350339
}
351340

341+
func StackConfig(gitRepoCache *nativeGit.RepoCache, stackYamlPath, infraRepo string) (*dx.StackConfig, error) {
342+
var stackConfig *dx.StackConfig
343+
err := gitRepoCache.PerformAction(infraRepo, func(repo *git.Repository) error {
344+
var inerErr error
345+
stackConfig, inerErr = stackYaml(repo, stackYamlPath)
346+
return inerErr
347+
})
348+
if err != nil {
349+
if !strings.Contains(err.Error(), "file not found") {
350+
return nil, fmt.Errorf("cannot get stack yaml from repo: %s", err)
351+
} else {
352+
return nil, fmt.Errorf("cannot get repo: %s", err)
353+
}
354+
}
355+
return stackConfig, nil
356+
}
357+
352358
func loadStackDefinition(stackConfig *dx.StackConfig) (map[string]interface{}, error) {
353359
var url string
354360
if stackConfig != nil {

pkg/dashboard/server/releases.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ func release(w http.ResponseWriter, r *http.Request) {
295295
Image: imageRepository,
296296
Tag: imageTag,
297297
Dockerfile: dockerfile,
298+
Strategy: strategy,
298299
Registry: registry,
299300
}
300301
break

pkg/dashboard/worker/gitops.go

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,9 @@ import (
2020
"github.com/gimlet-io/gimlet/pkg/dx"
2121
"github.com/gimlet-io/gimlet/pkg/git/customScm"
2222
"github.com/gimlet-io/gimlet/pkg/git/nativeGit"
23-
helper "github.com/gimlet-io/gimlet/pkg/git/nativeGit"
2423
bootstrap "github.com/gimlet-io/gimlet/pkg/gitops"
2524
"github.com/gimlet-io/gimlet/pkg/gitops/sync"
2625
"github.com/joho/godotenv"
27-
"sigs.k8s.io/yaml"
2826

2927
"github.com/go-git/go-git/v5"
3028
"github.com/go-git/go-git/v5/plumbing/object"
@@ -726,23 +724,14 @@ func cloneTemplateWriteAndPush(
726724
}
727725
}
728726

729-
var stackConfig *dx.StackConfig
730727
stackYamlPath := "stack.yaml"
731728
if !envFromStore.RepoPerEnv {
732729
stackYamlPath = filepath.Join(envFromStore.Name, "stack.yaml")
733730
}
734731

735-
err = gitopsRepoCache.PerformAction(envFromStore.InfraRepo, func(repo *git.Repository) error {
736-
var inerErr error
737-
stackConfig, inerErr = stackYaml(repo, stackYamlPath)
738-
return inerErr
739-
})
732+
stackConfig, err := server.StackConfig(gitopsRepoCache, stackYamlPath, envFromStore.InfraRepo)
740733
if err != nil {
741-
if !strings.Contains(err.Error(), "file not found") {
742-
return "", err
743-
} else {
744-
return "", err
745-
}
734+
return "", err
746735
}
747736

748737
imagepullSecretManifest, err := imagepullSecretTemplate(
@@ -808,28 +797,6 @@ func cloneTemplateWriteAndPush(
808797
return sha, nil
809798
}
810799

811-
// TODO Duplication
812-
func stackYaml(repo *git.Repository, path string) (*dx.StackConfig, error) {
813-
var stackConfig dx.StackConfig
814-
815-
headBranch, err := helper.HeadBranch(repo)
816-
if err != nil {
817-
return nil, err
818-
}
819-
820-
yamlString, err := helper.RemoteContentOnBranchWithoutCheckout(repo, headBranch, path)
821-
if err != nil {
822-
return nil, err
823-
}
824-
825-
err = yaml.Unmarshal([]byte(yamlString), &stackConfig)
826-
if err != nil {
827-
return nil, err
828-
}
829-
830-
return &stackConfig, nil
831-
}
832-
833800
func cloneTemplateDeleteAndPush(
834801
gitopsRepoCache *nativeGit.RepoCache,
835802
cleanupPolicy *dx.Cleanup,
@@ -1228,7 +1195,6 @@ func kustomizationTemplate(
12281195
repoPerEnv)
12291196
}
12301197

1231-
// TODO CLEANUP IN CASE OF APP DELETE!!!
12321198
func imagepullSecretTemplate(
12331199
manifest *dx.Manifest,
12341200
stackConfig *dx.StackConfig,
@@ -1261,11 +1227,9 @@ func imagepullSecretTemplate(
12611227
encryptedConfigString = encryptedConfig.(string)
12621228
}
12631229

1264-
secretName := fmt.Sprintf("%s-pullsecret", strings.ToLower(registryString))
12651230
return sync.GenerateImagePullSecret(
12661231
manifest.Env,
12671232
manifest.App,
1268-
secretName,
12691233
manifest.Namespace,
12701234
encryptedConfigString,
12711235
repoPerEnv,

pkg/dashboard/worker/gitops_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func Test_gitopsTemplateAndWrite(t *testing.T) {
9797
repo.CreateRemote(&config.RemoteConfig{Name: "origin", URLs: []string{""}})
9898

9999
repoPerEnv := false
100-
_, err := gitopsTemplateAndWrite(repo, a.Environments[0], &dx.Release{}, "", repoPerEnv, nil, nil, nil)
100+
_, err := gitopsTemplateAndWrite(repo, a.Environments[0], &dx.Release{}, "", repoPerEnv, nil, nil, nil, nil)
101101
assert.Nil(t, err)
102102
content, _ := nativeGit.Content(repo, "staging/my-app/deployment.yaml")
103103
assert.True(t, len(content) > 100)
@@ -107,7 +107,7 @@ func Test_gitopsTemplateAndWrite(t *testing.T) {
107107
assert.True(t, len(content) > 1)
108108

109109
repoPerEnv = true
110-
_, err = gitopsTemplateAndWrite(repo, a.Environments[0], &dx.Release{}, "", repoPerEnv, nil, nil, nil)
110+
_, err = gitopsTemplateAndWrite(repo, a.Environments[0], &dx.Release{}, "", repoPerEnv, nil, nil, nil, nil)
111111
assert.Nil(t, err)
112112
content, _ = nativeGit.Content(repo, "my-app/deployment.yaml")
113113
assert.True(t, len(content) > 100)
@@ -163,10 +163,10 @@ func Test_gitopsTemplateAndWrite_deleteStaleFiles(t *testing.T) {
163163
json.Unmarshal([]byte(withVolume), &a)
164164

165165
repoPerEnv := true
166-
_, err := gitopsTemplateAndWrite(repo, a.Environments[0], &dx.Release{}, "", repoPerEnv, nil, nil, nil)
166+
_, err := gitopsTemplateAndWrite(repo, a.Environments[0], &dx.Release{}, "", repoPerEnv, nil, nil, nil, nil)
167167
assert.Nil(t, err)
168168

169-
_, err = gitopsTemplateAndWrite(repo, a.Environments[0], &dx.Release{}, "", repoPerEnv, nil, nil, nil)
169+
_, err = gitopsTemplateAndWrite(repo, a.Environments[0], &dx.Release{}, "", repoPerEnv, nil, nil, nil, nil)
170170
assert.Nil(t, err)
171171

172172
content, _ := nativeGit.Content(repo, "my-app/deployment.yaml")
@@ -204,7 +204,7 @@ func Test_gitopsTemplateAndWrite_deleteStaleFiles(t *testing.T) {
204204

205205
var b dx.Artifact
206206
json.Unmarshal([]byte(withoutVolume), &b)
207-
_, err = gitopsTemplateAndWrite(repo, b.Environments[0], &dx.Release{}, "", false, nil, nil, nil)
207+
_, err = gitopsTemplateAndWrite(repo, b.Environments[0], &dx.Release{}, "", false, nil, nil, nil, nil)
208208
assert.Nil(t, err)
209209

210210
content, _ = nativeGit.Content(repo, "staging/my-app/pvc.yaml")

pkg/gitops/sync/sync.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -264,8 +264,7 @@ func GenerateKustomizationForApp(
264264
}
265265

266266
func GenerateImagePullSecret(
267-
env, app string,
268-
secretName, namespace string,
267+
env, app, namespace string,
269268
encryptedDockerconfigjson string,
270269
singleEnv bool,
271270
) (*manifestgen.Manifest, error) {
@@ -280,7 +279,7 @@ func GenerateImagePullSecret(
280279
APIVersion: "bitnami.com/v1alpha1",
281280
},
282281
ObjectMeta: metav1.ObjectMeta{
283-
Name: secretName,
282+
Name: "regcred",
284283
Namespace: namespace,
285284
Annotations: map[string]string{
286285
"sealedsecrets.bitnami.com/cluster-wide": "true",

web/dashboard/src/views/envConfig/envConfig.jsx

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class EnvConfig extends Component {
5151

5252
this.setValues = this.setValues.bind(this);
5353
this.resetNotificationStateAfterThreeSeconds = this.resetNotificationStateAfterThreeSeconds.bind(this);
54+
this.setImagePullSecret = this.setImagePullSecret.bind(this);
5455
}
5556

5657
componentDidMount() {
@@ -59,6 +60,14 @@ class EnvConfig extends Component {
5960

6061
const { gimletClient } = this.props;
6162

63+
gimletClient.getStackConfig(env)
64+
.then(data => {
65+
this.setState({
66+
stackConfig: data.stackConfig,
67+
stackDefinition: data.stackDefinition
68+
});
69+
}, () => {/* Generic error handler deals with it */ });
70+
6271
if (action === "new") {
6372
gimletClient.getDefaultDeploymentTemplates()
6473
.then(data => {
@@ -455,6 +464,18 @@ class EnvConfig extends Component {
455464
})
456465
}
457466

467+
setImagePullSecret(secret) {
468+
this.setState(prevState => ({
469+
configFile: {
470+
...prevState.configFile,
471+
values: {
472+
...prevState.configFile.values,
473+
imagePullSecrets: [secret]
474+
}
475+
}
476+
}));
477+
}
478+
458479
renderTemplateFromConfig() {
459480
let title = "Web application template"
460481
let description = "To deploy any web application. Multiple image build options available."
@@ -530,11 +551,6 @@ class EnvConfig extends Component {
530551

531552
const hasChange = JSON.stringify(this.state.configFile) !== JSON.stringify(this.state.defaultConfigFile)
532553

533-
const customFields = {
534-
imageWidget: ImageWidget,
535-
sealedSecretWidget: (props) => <SealedSecretWidget {...props} gimletClient={this.props.gimletClient} store={this.props.store} env={env} />,
536-
}
537-
538554
if (!this.state.configFile) {
539555
return <Spinner />;
540556
}
@@ -543,6 +559,15 @@ class EnvConfig extends Component {
543559
return <Spinner />;
544560
}
545561

562+
if (!this.state.stackConfig) {
563+
return <Spinner />;
564+
}
565+
566+
const customFields = {
567+
imageWidget: (props) => <ImageWidget {...props} setImagePullSecret={this.setImagePullSecret} registry={filterRegistry(this.state.stackConfig, this.state.stackDefinition)} />,
568+
sealedSecretWidget: (props) => <SealedSecretWidget {...props} gimletClient={this.props.gimletClient} store={this.props.store} env={env} />,
569+
}
570+
546571
return (
547572
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
548573
<h1 className="text-3xl font-bold leading-tight text-gray-900">Editing {config} config for {env}</h1>
@@ -850,4 +875,11 @@ class EnvConfig extends Component {
850875
}
851876
}
852877

878+
const filterRegistry = (stackConfig, stackDefinition) => {
879+
const config = stackConfig.config;
880+
const elements = stackDefinition.components.filter(c => c.category === "registry")
881+
882+
return Object.fromEntries(Object.entries(config).filter(([key]) => elements.some(e => e.variable === key)))
883+
}
884+
853885
export default EnvConfig;

web/dashboard/src/views/envConfig/imageWidget.jsx

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ class ImageWidget extends Component {
1212
};
1313
}
1414

15+
// TODO bug input field loses focus on writing
16+
componentDidMount() {
17+
this.props.setImagePullSecret("regcred")
18+
}
19+
1520
defaults(strategy) {
1621
let repository = ""
1722
let tag = ""
@@ -54,37 +59,41 @@ class ImageWidget extends Component {
5459
{
5560
[name]: event.target.value,
5661
},
57-
() => this.props.onChange({"repository": this.state.repository, "tag": this.state.tag, "dockerfile": this.state.dockerfile, "strategy": this.state.strategy, "registry": this.state.registry })
62+
() => this.props.onChange({"repository": this.state.repository, "tag": this.state.tag, "dockerfile": this.state.dockerfile, "strategy": this.state.strategy, "registry": this.state.registry})
5863
);
5964
};
6065
}
6166

62-
selectOnChange(value) {
63-
const { registry } = this.props;
64-
let repository = "";
65-
const login = registry[value].login ?? "your-company"
66-
67-
switch (value) {
68-
case 'dockerhubRegistry':
69-
repository = `${login}/{{ .APP }}`
70-
break;
71-
case 'ghcrRegistry':
72-
repository = `ghcr.io/${login}/{{ .APP }}`
73-
break;
74-
default:
75-
repository = "127.0.0.1:32447/{{ .APP }}"
76-
}
67+
selectOnChange(name) {
68+
return (event) => {
69+
const { registry } = this.props;
70+
const login = registry[event.target.value].login ?? "your-company"
71+
let repository = "";
72+
73+
switch (event.target.value) {
74+
case 'dockerhubRegistry':
75+
repository = `${login}/{{ .APP }}`
76+
break;
77+
case 'ghcrRegistry':
78+
repository = `ghcr.io/${login}/{{ .APP }}`
79+
break;
80+
default:
81+
repository = "127.0.0.1:32447/{{ .APP }}"
82+
}
7783

78-
this.props.onChange({"repository": repository, "tag": this.state.tag, "dockerfile": this.state.dockerfile, "strategy": this.state.strategy, "registry": value})
79-
this.setState({ registry: value });
84+
this.setState(
85+
{
86+
[name]: event.target.value,
87+
},
88+
() => this.props.onChange({"repository": repository, "tag": this.state.tag, "dockerfile": this.state.dockerfile, "strategy": this.state.strategy, "registry": this.state.registry })
89+
);
90+
};
8091
}
8192

8293
render() {
8394
const { strategy, repository, tag, dockerfile } = this.state;
8495
const { registry } = this.props;
8596

86-
console.log(this.state)
87-
8897
return (
8998
<>
9099
<div className="form-group field field-object">
@@ -168,9 +177,12 @@ class ImageWidget extends Component {
168177
</div>
169178
}
170179
{(strategy === "dockerfile" || strategy === "buildpacks") &&
180+
Object.keys(registry).length !== 0 &&
171181
<div className="form-group field">
172182
<label className="control-label" htmlFor="root_tag">Registry<span className="required">*</span></label>
173-
<select id="root_1__anyof_select" className="form-control" value={this.state.registry} onChange={e => this.selectOnChange(e.target.value)}>
183+
<select id="root_1__anyof_select" className="form-control" value={this.state.registry}
184+
onChange={this.selectOnChange('registry')}
185+
>
174186
{
175187
Object.keys(registry).map((item, idx) => {
176188
if (!registry[item].hasOwnProperty("enabled")) {

0 commit comments

Comments
 (0)