mirror of
https://github.com/arangodb/kube-arangodb.git
synced 2024-12-14 11:57:37 +00:00
[Feature] Add 'crd install' subcommand to new 'ops' binary (#1014)
This commit is contained in:
parent
e09d35e258
commit
24d981cf4e
5 changed files with 141 additions and 65 deletions
|
@ -40,6 +40,7 @@
|
|||
- (Bugfix) Infinite loop fix in ArangoD AsyncClient
|
||||
- (Bugfix) Add Panic Handler
|
||||
- (Bugfix) Unify yaml packages
|
||||
- (Feature) Add 'crd install' subcommand
|
||||
|
||||
## [1.2.13](https://github.com/arangodb/kube-arangodb/tree/1.2.13) (2022-06-07)
|
||||
- (Bugfix) Fix arangosync members state inspection
|
||||
|
|
|
@ -289,7 +289,7 @@ func executeMain(cmd *cobra.Command, args []string) {
|
|||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||
defer cancel()
|
||||
|
||||
crd.EnsureCRD(ctx, client)
|
||||
_ = crd.EnsureCRD(ctx, client, true)
|
||||
}
|
||||
|
||||
secrets := client.Kubernetes().CoreV1().Secrets(namespace)
|
||||
|
|
67
cmd/crd.go
Normal file
67
cmd/crd.go
Normal file
|
@ -0,0 +1,67 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/arangodb/kube-arangodb/pkg/crd"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
|
||||
)
|
||||
|
||||
var (
|
||||
cmdCRD = &cobra.Command{
|
||||
Use: "crd",
|
||||
Run: executeUsage,
|
||||
Short: "CRD operations",
|
||||
}
|
||||
cmdCRDInstall = &cobra.Command{
|
||||
Use: "install",
|
||||
Run: cmdCRDInstallRun,
|
||||
Short: "Install and update all required CRDs",
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
cmdMain.AddCommand(cmdCRD)
|
||||
cmdOps.AddCommand(cmdCRD)
|
||||
|
||||
cmdCRD.AddCommand(cmdCRDInstall)
|
||||
}
|
||||
|
||||
func cmdCRDInstallRun(cmd *cobra.Command, args []string) {
|
||||
client, ok := kclient.GetDefaultFactory().Client()
|
||||
if !ok {
|
||||
logger.Fatal("Failed to get client")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||
defer cancel()
|
||||
|
||||
err := crd.EnsureCRD(ctx, client, false)
|
||||
if err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
134
pkg/crd/apply.go
134
pkg/crd/apply.go
|
@ -37,81 +37,89 @@ import (
|
|||
|
||||
var logger = logging.Global().RegisterAndGetLogger("crd", logging.Info)
|
||||
|
||||
func EnsureCRD(ctx context.Context, client kclient.Client) {
|
||||
func EnsureCRD(ctx context.Context, client kclient.Client, ignoreErrors bool) error {
|
||||
crdsLock.Lock()
|
||||
defer crdsLock.Unlock()
|
||||
|
||||
for crd, spec := range crds {
|
||||
getAccess := verifyCRDAccess(ctx, client, crd, "get")
|
||||
|
||||
if !getAccess.Allowed {
|
||||
logger.Str("crd", crd).Info("Get Operations is not allowed. Continue")
|
||||
continue
|
||||
}
|
||||
|
||||
c, err := client.KubernetesExtensions().ApiextensionsV1().CustomResourceDefinitions().Get(ctx, crd, meta.GetOptions{})
|
||||
if err != nil {
|
||||
if !errors.IsNotFound(err) {
|
||||
logger.Err(err).Str("crd", crd).Warn("Get Operations is not allowed due to error. Continue")
|
||||
continue
|
||||
}
|
||||
|
||||
createAccess := verifyCRDAccess(ctx, client, crd, "create")
|
||||
|
||||
if !createAccess.Allowed {
|
||||
logger.Str("crd", crd).Info("Create Operations is not allowed but CRD is missing. Continue")
|
||||
continue
|
||||
}
|
||||
|
||||
c = &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: crd,
|
||||
Labels: map[string]string{
|
||||
Version: string(spec.version),
|
||||
},
|
||||
},
|
||||
Spec: spec.spec,
|
||||
}
|
||||
|
||||
if _, err := client.KubernetesExtensions().ApiextensionsV1().CustomResourceDefinitions().Create(ctx, c, meta.CreateOptions{}); err != nil {
|
||||
logger.Err(err).Str("crd", crd).Warn("Create Operations is not allowed due to error. Continue")
|
||||
continue
|
||||
}
|
||||
|
||||
logger.Str("crd", crd).Info("CRD Created")
|
||||
continue
|
||||
err := tryApplyCRD(ctx, client, crd, spec)
|
||||
if !ignoreErrors && err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
updateAccess := verifyCRDAccess(ctx, client, crd, "update")
|
||||
|
||||
if !updateAccess.Allowed {
|
||||
logger.Str("crd", crd).Info("Update Operations is not allowed. Continue")
|
||||
continue
|
||||
}
|
||||
|
||||
if c.ObjectMeta.Labels == nil {
|
||||
c.ObjectMeta.Labels = map[string]string{}
|
||||
}
|
||||
|
||||
if v, ok := c.ObjectMeta.Labels[Version]; ok {
|
||||
if v != "" {
|
||||
if !isUpdateRequired(spec.version, driver.Version(v)) {
|
||||
logger.Str("crd", crd).Info("CRD Update not required")
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c.ObjectMeta.Labels[Version] = string(spec.version)
|
||||
|
||||
c.Spec = spec.spec
|
||||
|
||||
if _, err := client.KubernetesExtensions().ApiextensionsV1().CustomResourceDefinitions().Update(ctx, c, meta.UpdateOptions{}); err != nil {
|
||||
logger.Err(err).Str("crd", crd).Warn("Create Operations is not allowed due to error. Continue")
|
||||
continue
|
||||
}
|
||||
logger.Str("crd", crd).Info("CRD Updated")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func tryApplyCRD(ctx context.Context, client kclient.Client, crd string, spec crd) error {
|
||||
crdDefinitions := client.KubernetesExtensions().ApiextensionsV1().CustomResourceDefinitions()
|
||||
|
||||
c, err := crdDefinitions.Get(ctx, crd, meta.GetOptions{})
|
||||
if err != nil {
|
||||
if !errors.IsNotFound(err) {
|
||||
logger.Err(err).Str("crd", crd).Warn("Get Operations is not allowed due to error")
|
||||
return err
|
||||
}
|
||||
|
||||
createAccess := verifyCRDAccess(ctx, client, crd, "create")
|
||||
|
||||
if !createAccess.Allowed {
|
||||
logger.Str("crd", crd).Info("Create Operations is not allowed but CRD is missing. Continue")
|
||||
return nil
|
||||
}
|
||||
|
||||
c = &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: crd,
|
||||
Labels: map[string]string{
|
||||
Version: string(spec.version),
|
||||
},
|
||||
},
|
||||
Spec: spec.spec,
|
||||
}
|
||||
|
||||
if _, err := crdDefinitions.Create(ctx, c, meta.CreateOptions{}); err != nil {
|
||||
logger.Err(err).Str("crd", crd).Warn("Create Operations is not allowed due to error")
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Str("crd", crd).Info("CRD Created")
|
||||
return nil
|
||||
}
|
||||
|
||||
updateAccess := verifyCRDAccess(ctx, client, crd, "update")
|
||||
if !updateAccess.Allowed {
|
||||
logger.Str("crd", crd).Info("Update Operations is not allowed. Continue")
|
||||
return nil
|
||||
}
|
||||
|
||||
if c.ObjectMeta.Labels == nil {
|
||||
c.ObjectMeta.Labels = map[string]string{}
|
||||
}
|
||||
|
||||
if v, ok := c.ObjectMeta.Labels[Version]; ok {
|
||||
if v != "" {
|
||||
if !isUpdateRequired(spec.version, driver.Version(v)) {
|
||||
logger.Str("crd", crd).Info("CRD Update not required")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c.ObjectMeta.Labels[Version] = string(spec.version)
|
||||
c.Spec = spec.spec
|
||||
|
||||
if _, err := crdDefinitions.Update(ctx, c, meta.UpdateOptions{}); err != nil {
|
||||
logger.Err(err).Str("crd", crd).Warn("Create Operations is not allowed due to error")
|
||||
return err
|
||||
}
|
||||
logger.Str("crd", crd).Info("CRD Updated")
|
||||
return nil
|
||||
}
|
||||
|
||||
func verifyCRDAccess(ctx context.Context, client kclient.Client, crd string, verb string) authorization.SubjectAccessReviewStatus {
|
||||
|
|
|
@ -34,6 +34,6 @@ func Test_Apply(t *testing.T) {
|
|||
c, ok := kclient.GetDefaultFactory().Client()
|
||||
require.True(t, ok)
|
||||
|
||||
EnsureCRD(context.Background(), c)
|
||||
_ = EnsureCRD(context.Background(), c, true)
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue