Skip to content

Commit 24d981c

Browse files
[Feature] Add 'crd install' subcommand to new 'ops' binary (#1014)
1 parent e09d35e commit 24d981c

File tree

5 files changed

+128
-52
lines changed

5 files changed

+128
-52
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
- (Bugfix) Infinite loop fix in ArangoD AsyncClient
4141
- (Bugfix) Add Panic Handler
4242
- (Bugfix) Unify yaml packages
43+
- (Feature) Add 'crd install' subcommand
4344

4445
## [1.2.13](https://github.com/arangodb/kube-arangodb/tree/1.2.13) (2022-06-07)
4546
- (Bugfix) Fix arangosync members state inspection

cmd/cmd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ func executeMain(cmd *cobra.Command, args []string) {
289289
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
290290
defer cancel()
291291

292-
crd.EnsureCRD(ctx, client)
292+
_ = crd.EnsureCRD(ctx, client, true)
293293
}
294294

295295
secrets := client.Kubernetes().CoreV1().Secrets(namespace)

cmd/crd.go

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package cmd
22+
23+
import (
24+
"context"
25+
"os"
26+
"time"
27+
28+
"github.com/spf13/cobra"
29+
30+
"github.com/arangodb/kube-arangodb/pkg/crd"
31+
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
32+
)
33+
34+
var (
35+
cmdCRD = &cobra.Command{
36+
Use: "crd",
37+
Run: executeUsage,
38+
Short: "CRD operations",
39+
}
40+
cmdCRDInstall = &cobra.Command{
41+
Use: "install",
42+
Run: cmdCRDInstallRun,
43+
Short: "Install and update all required CRDs",
44+
}
45+
)
46+
47+
func init() {
48+
cmdMain.AddCommand(cmdCRD)
49+
cmdOps.AddCommand(cmdCRD)
50+
51+
cmdCRD.AddCommand(cmdCRDInstall)
52+
}
53+
54+
func cmdCRDInstallRun(cmd *cobra.Command, args []string) {
55+
client, ok := kclient.GetDefaultFactory().Client()
56+
if !ok {
57+
logger.Fatal("Failed to get client")
58+
}
59+
60+
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
61+
defer cancel()
62+
63+
err := crd.EnsureCRD(ctx, client, false)
64+
if err != nil {
65+
os.Exit(1)
66+
}
67+
}

pkg/crd/apply.go

Lines changed: 58 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -37,81 +37,89 @@ import (
3737

3838
var logger = logging.Global().RegisterAndGetLogger("crd", logging.Info)
3939

40-
func EnsureCRD(ctx context.Context, client kclient.Client) {
40+
func EnsureCRD(ctx context.Context, client kclient.Client, ignoreErrors bool) error {
4141
crdsLock.Lock()
4242
defer crdsLock.Unlock()
4343

4444
for crd, spec := range crds {
4545
getAccess := verifyCRDAccess(ctx, client, crd, "get")
46-
4746
if !getAccess.Allowed {
4847
logger.Str("crd", crd).Info("Get Operations is not allowed. Continue")
4948
continue
5049
}
5150

52-
c, err := client.KubernetesExtensions().ApiextensionsV1().CustomResourceDefinitions().Get(ctx, crd, meta.GetOptions{})
53-
if err != nil {
54-
if !errors.IsNotFound(err) {
55-
logger.Err(err).Str("crd", crd).Warn("Get Operations is not allowed due to error. Continue")
56-
continue
57-
}
58-
59-
createAccess := verifyCRDAccess(ctx, client, crd, "create")
60-
61-
if !createAccess.Allowed {
62-
logger.Str("crd", crd).Info("Create Operations is not allowed but CRD is missing. Continue")
63-
continue
64-
}
65-
66-
c = &apiextensions.CustomResourceDefinition{
67-
ObjectMeta: meta.ObjectMeta{
68-
Name: crd,
69-
Labels: map[string]string{
70-
Version: string(spec.version),
71-
},
72-
},
73-
Spec: spec.spec,
74-
}
51+
err := tryApplyCRD(ctx, client, crd, spec)
52+
if !ignoreErrors && err != nil {
53+
return err
54+
}
55+
}
56+
return nil
57+
}
7558

76-
if _, err := client.KubernetesExtensions().ApiextensionsV1().CustomResourceDefinitions().Create(ctx, c, meta.CreateOptions{}); err != nil {
77-
logger.Err(err).Str("crd", crd).Warn("Create Operations is not allowed due to error. Continue")
78-
continue
79-
}
59+
func tryApplyCRD(ctx context.Context, client kclient.Client, crd string, spec crd) error {
60+
crdDefinitions := client.KubernetesExtensions().ApiextensionsV1().CustomResourceDefinitions()
8061

81-
logger.Str("crd", crd).Info("CRD Created")
82-
continue
62+
c, err := crdDefinitions.Get(ctx, crd, meta.GetOptions{})
63+
if err != nil {
64+
if !errors.IsNotFound(err) {
65+
logger.Err(err).Str("crd", crd).Warn("Get Operations is not allowed due to error")
66+
return err
8367
}
8468

85-
updateAccess := verifyCRDAccess(ctx, client, crd, "update")
69+
createAccess := verifyCRDAccess(ctx, client, crd, "create")
8670

87-
if !updateAccess.Allowed {
88-
logger.Str("crd", crd).Info("Update Operations is not allowed. Continue")
89-
continue
71+
if !createAccess.Allowed {
72+
logger.Str("crd", crd).Info("Create Operations is not allowed but CRD is missing. Continue")
73+
return nil
9074
}
9175

92-
if c.ObjectMeta.Labels == nil {
93-
c.ObjectMeta.Labels = map[string]string{}
76+
c = &apiextensions.CustomResourceDefinition{
77+
ObjectMeta: meta.ObjectMeta{
78+
Name: crd,
79+
Labels: map[string]string{
80+
Version: string(spec.version),
81+
},
82+
},
83+
Spec: spec.spec,
9484
}
9585

96-
if v, ok := c.ObjectMeta.Labels[Version]; ok {
97-
if v != "" {
98-
if !isUpdateRequired(spec.version, driver.Version(v)) {
99-
logger.Str("crd", crd).Info("CRD Update not required")
100-
continue
101-
}
102-
}
86+
if _, err := crdDefinitions.Create(ctx, c, meta.CreateOptions{}); err != nil {
87+
logger.Err(err).Str("crd", crd).Warn("Create Operations is not allowed due to error")
88+
return err
10389
}
10490

105-
c.ObjectMeta.Labels[Version] = string(spec.version)
91+
logger.Str("crd", crd).Info("CRD Created")
92+
return nil
93+
}
10694

107-
c.Spec = spec.spec
95+
updateAccess := verifyCRDAccess(ctx, client, crd, "update")
96+
if !updateAccess.Allowed {
97+
logger.Str("crd", crd).Info("Update Operations is not allowed. Continue")
98+
return nil
99+
}
108100

109-
if _, err := client.KubernetesExtensions().ApiextensionsV1().CustomResourceDefinitions().Update(ctx, c, meta.UpdateOptions{}); err != nil {
110-
logger.Err(err).Str("crd", crd).Warn("Create Operations is not allowed due to error. Continue")
111-
continue
101+
if c.ObjectMeta.Labels == nil {
102+
c.ObjectMeta.Labels = map[string]string{}
103+
}
104+
105+
if v, ok := c.ObjectMeta.Labels[Version]; ok {
106+
if v != "" {
107+
if !isUpdateRequired(spec.version, driver.Version(v)) {
108+
logger.Str("crd", crd).Info("CRD Update not required")
109+
return nil
110+
}
112111
}
113-
logger.Str("crd", crd).Info("CRD Updated")
114112
}
113+
114+
c.ObjectMeta.Labels[Version] = string(spec.version)
115+
c.Spec = spec.spec
116+
117+
if _, err := crdDefinitions.Update(ctx, c, meta.UpdateOptions{}); err != nil {
118+
logger.Err(err).Str("crd", crd).Warn("Create Operations is not allowed due to error")
119+
return err
120+
}
121+
logger.Str("crd", crd).Info("CRD Updated")
122+
return nil
115123
}
116124

117125
func verifyCRDAccess(ctx context.Context, client kclient.Client, crd string, verb string) authorization.SubjectAccessReviewStatus {

pkg/crd/apply_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,6 @@ func Test_Apply(t *testing.T) {
3434
c, ok := kclient.GetDefaultFactory().Client()
3535
require.True(t, ok)
3636

37-
EnsureCRD(context.Background(), c)
37+
_ = EnsureCRD(context.Background(), c, true)
3838
})
3939
}

0 commit comments

Comments
 (0)