Skip to content

Commit 1fa92db

Browse files
zmotsoSergK
authored andcommitted
feat: Allow usage of any branch name for CodebaseBranch (#198)
Relation beetwen CodebaseBranch and CodebaseImageStream changed from some naming pattern to label. CodebaseImageStream now contains label app.edp.epam.com/cbis-codebasebranch with CodebaseBranch name as value. This allows to use any branch name for CodebaseBranch.spec.branchName. This change is backward compatible. All previous CodebaseImageStream will be updated with new label.
1 parent 84af831 commit 1fa92db

File tree

15 files changed

+345
-97
lines changed

15 files changed

+345
-97
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,4 @@ tags
8282
.history
8383
.idea/*
8484
# End of https://www.gitignore.io/api/go,vim,emacs,visualstudiocode
85+
.DS_Store

api/v1/codebaseimagestream_types.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ import (
44
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
55
)
66

7-
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
8-
97
// CodebaseImageStreamSpec defines the desired state of CodebaseImageStream.
108
type CodebaseImageStreamSpec struct {
119
// Name of Codebase associated with.

api/v1/labels.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,10 @@ const (
99

1010
// CdStageDeployLabel is a label that is used to store the name of the CD stage deploy in the related resources.
1111
CdStageDeployLabel = "app.edp.epam.com/cdstagedeploy"
12+
13+
// CodebaseImageStreamCodebaseBranchLabel is a label that is used to store CodebaseBranch name of the CodebaseImageStreamCodebaseImageStream.
14+
CodebaseImageStreamCodebaseBranchLabel = "app.edp.epam.com/cbis-codebasebranch"
15+
16+
// CodebaseImageStreamCodebaseLabel is a label that is used to store Codebase name of the CodebaseImageStreamCodebaseImageStream.
17+
CodebaseImageStreamCodebaseLabel = "app.edp.epam.com/cbis-codebase"
1218
)

controllers/codebasebranch/chain/check_commit_hash.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ func (c CheckCommitHashExists) ServeRequest(ctx context.Context, codebaseBranch
7272
return c.processErr(codebaseBranch, fmt.Errorf("failed to get secret %s: %w", gitServer.Spec.NameSshKeySecret, err))
7373
}
7474

75-
workDir := util.GetWorkDir(codebaseBranch.Spec.CodebaseName, fmt.Sprintf("%v-%v", codebaseBranch.Namespace, codebaseBranch.Spec.BranchName))
75+
workDir := GetCodebaseBranchWorkingDirectory(codebaseBranch)
7676
if !DirectoryExistsNotEmpty(workDir) {
7777
repoSshUrl := util.GetSSHUrl(gitServer, codebase.Spec.GetProjectID())
7878

controllers/codebasebranch/chain/clean_tmp_directory/clean_tmp_directory.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
ctrl "sigs.k8s.io/controller-runtime"
99

1010
codebaseApi "github.com/epam/edp-codebase-operator/v2/api/v1"
11+
"github.com/epam/edp-codebase-operator/v2/controllers/codebasebranch/chain"
1112
"github.com/epam/edp-codebase-operator/v2/pkg/util"
1213
)
1314

@@ -18,7 +19,7 @@ func (*CleanTempDirectory) ServeRequest(ctx context.Context, cb *codebaseApi.Cod
1819

1920
log.Info("Start CleanTempDirectory method")
2021

21-
wd := util.GetWorkDir(cb.Spec.CodebaseName, fmt.Sprintf("%v-%v", cb.Namespace, cb.Spec.BranchName))
22+
wd := chain.GetCodebaseBranchWorkingDirectory(cb)
2223

2324
if err := deleteWorkDirectory(wd); err != nil {
2425
setFailedFields(cb, codebaseApi.CleanData, err.Error())

controllers/codebasebranch/chain/put_branch_in_git/put_branch_in_git.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"sigs.k8s.io/controller-runtime/pkg/client"
1111

1212
codebaseApi "github.com/epam/edp-codebase-operator/v2/api/v1"
13+
"github.com/epam/edp-codebase-operator/v2/controllers/codebasebranch/chain"
1314
"github.com/epam/edp-codebase-operator/v2/controllers/codebasebranch/chain/handler"
1415
"github.com/epam/edp-codebase-operator/v2/controllers/codebasebranch/service"
1516
"github.com/epam/edp-codebase-operator/v2/pkg/git"
@@ -87,7 +88,7 @@ func (h PutBranchInGit) ServeRequest(ctx context.Context, branch *codebaseApi.Co
8788
return err
8889
}
8990

90-
wd := util.GetWorkDir(branch.Spec.CodebaseName, fmt.Sprintf("%v-%v", branch.Namespace, branch.Spec.BranchName))
91+
wd := chain.GetCodebaseBranchWorkingDirectory(branch)
9192
if !checkDirectory(wd) {
9293
repoSshUrl := util.GetSSHUrl(gitServer, codebase.Spec.GetProjectID())
9394

controllers/codebasebranch/chain/put_branch_in_git/put_branch_in_git_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"sigs.k8s.io/controller-runtime/pkg/client/fake"
1818

1919
codebaseApi "github.com/epam/edp-codebase-operator/v2/api/v1"
20+
"github.com/epam/edp-codebase-operator/v2/controllers/codebasebranch/chain"
2021
"github.com/epam/edp-codebase-operator/v2/controllers/codebasebranch/service"
2122
gitServerMocks "github.com/epam/edp-codebase-operator/v2/pkg/git/mocks"
2223
"github.com/epam/edp-codebase-operator/v2/pkg/util"
@@ -454,10 +455,9 @@ func TestPutBranchInGit_ShouldBeExecutedSuccessfullyWithEdpVersioning(t *testing
454455
mGit := gitServerMocks.NewMockGit(t)
455456

456457
port := int32(22)
457-
wd := util.GetWorkDir(fakeName, fmt.Sprintf("%v-%v", fakeNamespace, fakeName))
458+
wd := chain.GetCodebaseBranchWorkingDirectory(cb)
458459

459460
repoSshUrl := util.GetSSHUrl(gs, c.Spec.GetProjectID())
460-
461461
mGit.On("CloneRepositoryBySsh", testifymock.Anything, "", fakeName, repoSshUrl, wd, port).
462462
Return(nil)
463463
mGit.On(

controllers/codebasebranch/chain/put_codebase_image_stream/put_codebase_image_stream.go

Lines changed: 82 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package put_codebase_image_stream
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67
"strings"
78

@@ -14,6 +15,7 @@ import (
1415

1516
codebaseApi "github.com/epam/edp-codebase-operator/v2/api/v1"
1617
"github.com/epam/edp-codebase-operator/v2/controllers/codebasebranch/chain/handler"
18+
"github.com/epam/edp-codebase-operator/v2/pkg/codebaseimagestream"
1719
"github.com/epam/edp-codebase-operator/v2/pkg/model"
1820
"github.com/epam/edp-codebase-operator/v2/pkg/platform"
1921
"github.com/epam/edp-codebase-operator/v2/pkg/util"
@@ -43,23 +45,8 @@ func (h PutCodebaseImageStream) ServeRequest(ctx context.Context, cb *codebaseAp
4345
return fmt.Errorf("failed to fetch Codebase resource: %w", err)
4446
}
4547

46-
registryUrl, err := h.getDockerRegistryUrl(ctx, cb.Namespace)
47-
if err != nil {
48-
err = fmt.Errorf("failed to get container registry url: %w", err)
49-
setFailedFields(cb, codebaseApi.PutCodebaseImageStream, err.Error())
50-
51-
return err
52-
}
53-
54-
cisName := fmt.Sprintf("%v-%v", c.Name, ProcessNameToK8sConvention(cb.Spec.BranchName))
55-
imageName := fmt.Sprintf("%v/%v", registryUrl, cb.Spec.CodebaseName)
56-
57-
if err = h.createCodebaseImageStreamIfNotExists(
48+
if err := h.createCodebaseImageStreamIfNotExists(
5849
ctrl.LoggerInto(ctx, log),
59-
cisName,
60-
imageName,
61-
cb.Spec.CodebaseName,
62-
cb.Namespace,
6350
cb,
6451
); err != nil {
6552
setFailedFields(cb, codebaseApi.PutCodebaseImageStream, err.Error())
@@ -69,14 +56,15 @@ func (h PutCodebaseImageStream) ServeRequest(ctx context.Context, cb *codebaseAp
6956

7057
log.Info("End creating CodebaseImageStream")
7158

72-
err = handler.NextServeOrNil(ctx, h.Next, cb)
73-
if err != nil {
59+
if err := handler.NextServeOrNil(ctx, h.Next, cb); err != nil {
7460
return fmt.Errorf("failed to process next handler in chain: %w", err)
7561
}
7662

7763
return nil
7864
}
7965

66+
// Deprecated: We don't need to make this conversion anymore in the future.
67+
// TODO: Remove this function in the next releases.
8068
func ProcessNameToK8sConvention(name string) string {
8169
r := strings.NewReplacer("/", "-", ".", "-")
8270
return r.Replace(name)
@@ -101,59 +89,102 @@ func (h PutCodebaseImageStream) getDockerRegistryUrl(ctx context.Context, namesp
10189

10290
func (h PutCodebaseImageStream) createCodebaseImageStreamIfNotExists(
10391
ctx context.Context,
104-
name, imageName, codebaseName, namespace string,
10592
codebaseBranch *codebaseApi.CodebaseBranch,
10693
) error {
10794
log := ctrl.LoggerFrom(ctx)
10895

109-
cis := &codebaseApi.CodebaseImageStream{
96+
cis, err := h.getCodebaseImageStream(ctx, codebaseBranch)
97+
if err != nil {
98+
if !k8sErrors.IsNotFound(err) {
99+
return fmt.Errorf("failed to get CodebaseImageStream: %w", err)
100+
}
101+
}
102+
103+
if err == nil {
104+
log.Info("CodebaseImageStream already exists. Skip creating", "CodebaseImageStream", cis.Name)
105+
106+
// For backward compatibility, we need to set branch label for the existing CodebaseImageStream.
107+
// TODO: remove this in the next releases.
108+
if v, ok := cis.GetLabels()[codebaseApi.CodebaseImageStreamCodebaseBranchLabel]; !ok || v != codebaseBranch.Name {
109+
patch := client.MergeFrom(cis.DeepCopy())
110+
111+
if cis.Labels == nil {
112+
cis.Labels = make(map[string]string, 2)
113+
}
114+
115+
cis.Labels[codebaseApi.CodebaseImageStreamCodebaseBranchLabel] = codebaseBranch.Name
116+
cis.Labels[codebaseApi.CodebaseImageStreamCodebaseLabel] = codebaseBranch.Spec.CodebaseName
117+
118+
if err = h.Client.Patch(ctx, cis, patch); err != nil {
119+
return fmt.Errorf("failed to set branch label: %w", err)
120+
}
121+
}
122+
123+
return nil
124+
}
125+
126+
registryUrl, err := h.getDockerRegistryUrl(ctx, codebaseBranch.Namespace)
127+
if err != nil {
128+
return fmt.Errorf("failed to get container registry url: %w", err)
129+
}
130+
131+
cis = &codebaseApi.CodebaseImageStream{
110132
ObjectMeta: metaV1.ObjectMeta{
111-
Name: name,
112-
Namespace: namespace,
133+
Name: codebaseBranch.Name,
134+
Namespace: codebaseBranch.Namespace,
135+
Labels: map[string]string{
136+
codebaseApi.CodebaseImageStreamCodebaseBranchLabel: codebaseBranch.Name,
137+
codebaseApi.CodebaseImageStreamCodebaseLabel: codebaseBranch.Spec.CodebaseName,
138+
},
113139
},
114140
Spec: codebaseApi.CodebaseImageStreamSpec{
115-
Codebase: codebaseName,
116-
ImageName: imageName,
141+
Codebase: codebaseBranch.Spec.CodebaseName,
142+
ImageName: fmt.Sprintf("%v/%v", registryUrl, codebaseBranch.Spec.CodebaseName),
117143
},
118144
}
119145

120-
if err := controllerutil.SetControllerReference(codebaseBranch, cis, h.Client.Scheme()); err != nil {
146+
if err = controllerutil.SetControllerReference(codebaseBranch, cis, h.Client.Scheme()); err != nil {
121147
return fmt.Errorf("failed to set controller reference for CodebaseImageStream: %w", err)
122148
}
123149

124-
if err := h.Client.Create(ctx, cis); err != nil {
125-
if k8sErrors.IsAlreadyExists(err) {
126-
log.Info("CodebaseImageStream already exists. Skip creating", "CodebaseImageStream", cis.Name)
150+
if err = h.Client.Create(ctx, cis); err != nil {
151+
return fmt.Errorf("failed to create CodebaseImageStream: %w", err)
152+
}
127153

128-
// For backward compatibility, we need to update the controller reference for the existing CodebaseImageStream.
129-
// We can remove this in the next releases.
130-
existingCIS := &codebaseApi.CodebaseImageStream{}
131-
if err = h.Client.Get(ctx, types.NamespacedName{
132-
Namespace: namespace,
133-
Name: name,
134-
}, existingCIS); err != nil {
135-
return fmt.Errorf("failed to get CodebaseImageStream: %w", err)
136-
}
154+
return nil
155+
}
137156

138-
if metaV1.GetControllerOf(existingCIS) == nil {
139-
if err = controllerutil.SetControllerReference(codebaseBranch, existingCIS, h.Client.Scheme()); err != nil {
140-
return fmt.Errorf("failed to set controller reference for CodebaseImageStream: %w", err)
141-
}
142-
}
157+
func (h PutCodebaseImageStream) getCodebaseImageStream(
158+
ctx context.Context,
159+
codebaseBranch *codebaseApi.CodebaseBranch,
160+
) (*codebaseApi.CodebaseImageStream, error) {
161+
cis, err := codebaseimagestream.GetCodebaseImageStreamByCodebaseBaseBranchName(
162+
ctx,
163+
h.Client,
164+
codebaseBranch.Name,
165+
codebaseBranch.Namespace,
166+
)
167+
if err == nil {
168+
return cis, nil
169+
}
143170

144-
if err = h.Client.Update(ctx, existingCIS); err != nil {
145-
return fmt.Errorf("failed to update CodebaseImageStream controller reference: %w", err)
146-
}
171+
if !errors.Is(err, codebaseimagestream.ErrCodebaseImageStreamNotFound) {
172+
return nil, fmt.Errorf("failed to get CodebaseImageStream: %w", err)
173+
}
147174

148-
return nil
149-
}
175+
// Get CodebaseImageStream by name old version for backward compatibility.
176+
// TODO: remove this in the next releases.
177+
cis = &codebaseApi.CodebaseImageStream{}
178+
err = h.Client.Get(ctx, types.NamespacedName{
179+
Namespace: codebaseBranch.Namespace,
180+
Name: fmt.Sprintf("%v-%v", codebaseBranch.Spec.CodebaseName, ProcessNameToK8sConvention(codebaseBranch.Spec.BranchName)),
181+
}, cis)
150182

151-
return fmt.Errorf("failed to create CodebaseImageStream %s: %w", name, err)
183+
if err != nil {
184+
return nil, fmt.Errorf("failed to get CodebaseImageStream: %w", err)
152185
}
153186

154-
log.Info("CodebaseImageStream has been created", "CodebaseImageStream", name)
155-
156-
return nil
187+
return cis, nil
157188
}
158189

159190
func setFailedFields(cb *codebaseApi.CodebaseBranch, a codebaseApi.ActionType, message string) {

controllers/codebasebranch/chain/put_codebase_image_stream/put_codebase_image_stream_test.go

Lines changed: 51 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"sigs.k8s.io/controller-runtime/pkg/client/fake"
1515

1616
codebaseApi "github.com/epam/edp-codebase-operator/v2/api/v1"
17+
"github.com/epam/edp-codebase-operator/v2/pkg/codebaseimagestream"
1718
"github.com/epam/edp-codebase-operator/v2/pkg/platform"
1819
)
1920

@@ -59,13 +60,12 @@ func TestPutCodebaseImageStream_ServeRequest(t *testing.T) {
5960
},
6061
wantErr: require.NoError,
6162
want: func(t *testing.T, k8sCl client.Client) {
62-
cis := &codebaseApi.CodebaseImageStream{}
63-
require.NoError(t, k8sCl.Get(context.Background(), client.ObjectKey{
64-
Name: "test-codebase-test-branch-master",
65-
Namespace: "default",
66-
}, cis))
63+
cis, err := codebaseimagestream.GetCodebaseImageStreamByCodebaseBaseBranchName(context.Background(), k8sCl, "test-branch", "default")
64+
require.NoError(t, err)
6765

6866
require.NotNil(t, metav1.GetControllerOf(cis))
67+
require.Contains(t, cis.Labels, codebaseApi.CodebaseImageStreamCodebaseBranchLabel)
68+
require.Equal(t, cis.Labels[codebaseApi.CodebaseImageStreamCodebaseBranchLabel], "test-branch")
6969
},
7070
},
7171
{
@@ -80,6 +80,48 @@ func TestPutCodebaseImageStream_ServeRequest(t *testing.T) {
8080
BranchName: "test-branch-master",
8181
},
8282
},
83+
objects: []client.Object{
84+
&codebaseApi.Codebase{
85+
ObjectMeta: metav1.ObjectMeta{
86+
Name: "test-codebase",
87+
Namespace: "default",
88+
},
89+
},
90+
&codebaseApi.CodebaseImageStream{
91+
ObjectMeta: metav1.ObjectMeta{
92+
Name: "test-cis",
93+
Namespace: "default",
94+
Labels: map[string]string{
95+
codebaseApi.CodebaseImageStreamCodebaseBranchLabel: "test-branch",
96+
},
97+
},
98+
},
99+
&corev1.ConfigMap{
100+
ObjectMeta: metav1.ObjectMeta{
101+
Name: platform.KrciConfigMap,
102+
Namespace: "default",
103+
},
104+
Data: map[string]string{
105+
platform.KrciConfigContainerRegistryHost: "test-registry",
106+
platform.KrciConfigContainerRegistrySpace: "test-space",
107+
},
108+
},
109+
},
110+
wantErr: require.NoError,
111+
want: func(t *testing.T, k8sCl client.Client) {},
112+
},
113+
{
114+
name: "process with deprecated relation to CodebaseBranch",
115+
codebaseBranch: &codebaseApi.CodebaseBranch{
116+
ObjectMeta: metav1.ObjectMeta{
117+
Name: "test-branch",
118+
Namespace: "default",
119+
},
120+
Spec: codebaseApi.CodebaseBranchSpec{
121+
CodebaseName: "test-codebase",
122+
BranchName: "test-branch/master",
123+
},
124+
},
83125
objects: []client.Object{
84126
&codebaseApi.Codebase{
85127
ObjectMeta: metav1.ObjectMeta{
@@ -106,13 +148,11 @@ func TestPutCodebaseImageStream_ServeRequest(t *testing.T) {
106148
},
107149
wantErr: require.NoError,
108150
want: func(t *testing.T, k8sCl client.Client) {
109-
cis := &codebaseApi.CodebaseImageStream{}
110-
require.NoError(t, k8sCl.Get(context.Background(), client.ObjectKey{
111-
Name: "test-codebase-test-branch-master",
112-
Namespace: "default",
113-
}, cis))
151+
cis, err := codebaseimagestream.GetCodebaseImageStreamByCodebaseBaseBranchName(context.Background(), k8sCl, "test-branch", "default")
152+
require.NoError(t, err)
114153

115-
require.NotNil(t, metav1.GetControllerOf(cis))
154+
require.Contains(t, cis.Labels, codebaseApi.CodebaseImageStreamCodebaseBranchLabel)
155+
require.Equal(t, cis.Labels[codebaseApi.CodebaseImageStreamCodebaseBranchLabel], "test-branch")
116156
},
117157
},
118158
{

0 commit comments

Comments
 (0)