fix: operator reconciling (#1478)

* fix(operator): align backup and restore commands (#1465)

* fix: crd mode broke backup and restore commands

* fix: remove obscure gitops-per-operator flags

(cherry picked from commit 041cacc4af8aeb89723a049bc4dbfcbc33cd987f)

* fix: gitops backup and restore need a kubernetes client too (#1475)

(cherry picked from commit 50bc317d2797b819124cdb1119db76bb00ab0df6)

Co-authored-by: Elio Bischof <eliobischof@gmail.com>
This commit is contained in:
Livio Amstutz 2021-03-25 16:39:19 +01:00 committed by GitHub
parent ae66e40ace
commit c9b3839f3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 73 additions and 104 deletions

View File

@ -1,9 +1,10 @@
package cmds package cmds
import ( import (
"io/ioutil" "errors"
"github.com/caos/orbos/pkg/kubernetes/cli"
"github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/zitadel/operator/api" "github.com/caos/zitadel/operator/api"
"github.com/caos/zitadel/operator/crtlgitops" "github.com/caos/zitadel/operator/crtlgitops"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -11,9 +12,8 @@ import (
func BackupCommand(getRv GetRootValues) *cobra.Command { func BackupCommand(getRv GetRootValues) *cobra.Command {
var ( var (
kubeconfig string backup string
backup string cmd = &cobra.Command{
cmd = &cobra.Command{
Use: "backup", Use: "backup",
Short: "Instant backup", Short: "Instant backup",
Long: "Instant backup", Long: "Instant backup",
@ -21,7 +21,6 @@ func BackupCommand(getRv GetRootValues) *cobra.Command {
) )
flags := cmd.Flags() flags := cmd.Flags()
flags.StringVar(&kubeconfig, "kubeconfig", "~/.kube/config", "Kubeconfig of cluster where the backup should be done")
flags.StringVar(&backup, "backup", "", "Name used for backup folder") flags.StringVar(&backup, "backup", "", "Name used for backup folder")
cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { cmd.RunE = func(cmd *cobra.Command, args []string) (err error) {
@ -38,11 +37,12 @@ func BackupCommand(getRv GetRootValues) *cobra.Command {
gitClient := rv.GitClient gitClient := rv.GitClient
version := rv.Version version := rv.Version
if err := gitClient.Configure(orbConfig.URL, []byte(orbConfig.Repokey)); err != nil { if !rv.Gitops {
return err return errors.New("backup command is only supported with the --gitops flag yet")
} }
if err := gitClient.Clone(); err != nil { k8sClient, _, err := cli.Client(monitor, orbConfig, gitClient, rv.Kubeconfig, rv.Gitops)
if err != nil {
return err return err
} }
@ -52,26 +52,15 @@ func BackupCommand(getRv GetRootValues) *cobra.Command {
} }
if found { if found {
value, err := ioutil.ReadFile(kubeconfig) if err := crtlgitops.Backup(
if err != nil { monitor,
monitor.Error(err) orbConfig.Path,
return nil k8sClient,
backup,
&version,
); err != nil {
return err
} }
kubeconfigStr := string(value)
k8sClient := kubernetes.NewK8sClient(monitor, &kubeconfigStr)
if k8sClient.Available() {
if err := crtlgitops.Backup(
monitor,
orbConfig.Path,
k8sClient,
backup,
&version,
); err != nil {
return err
}
}
} }
return nil return nil
} }

View File

@ -1,6 +1,7 @@
package cmds package cmds
import ( import (
"errors"
"fmt" "fmt"
"sort" "sort"
@ -30,6 +31,10 @@ func BackupListCommand(getRv GetRootValues) *cobra.Command {
orbConfig := rv.OrbConfig orbConfig := rv.OrbConfig
gitClient := rv.GitClient gitClient := rv.GitClient
if !rv.Gitops {
return errors.New("backuplist command is only supported with the --gitops flag yet")
}
if err := gitClient.Configure(orbConfig.URL, []byte(orbConfig.Repokey)); err != nil { if err := gitClient.Configure(orbConfig.URL, []byte(orbConfig.Repokey)); err != nil {
monitor.Error(err) monitor.Error(err)
return nil return nil

View File

@ -2,12 +2,10 @@ package cmds
import ( import (
"errors" "errors"
"io/ioutil"
"github.com/caos/orbos/pkg/kubernetes/cli"
"github.com/caos/zitadel/operator/crtlgitops" "github.com/caos/zitadel/operator/crtlgitops"
"github.com/caos/zitadel/operator/helpers"
"github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/zitadel/pkg/databases" "github.com/caos/zitadel/pkg/databases"
"github.com/manifoldco/promptui" "github.com/manifoldco/promptui"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -15,10 +13,8 @@ import (
func RestoreCommand(getRv GetRootValues) *cobra.Command { func RestoreCommand(getRv GetRootValues) *cobra.Command {
var ( var (
backup string backup string
kubeconfig string cmd = &cobra.Command{
gitOpsMode bool
cmd = &cobra.Command{
Use: "restore", Use: "restore",
Short: "Restore from backup", Short: "Restore from backup",
Long: "Restore from backup", Long: "Restore from backup",
@ -27,8 +23,6 @@ func RestoreCommand(getRv GetRootValues) *cobra.Command {
flags := cmd.Flags() flags := cmd.Flags()
flags.StringVar(&backup, "backup", "", "Backup used for db restore") flags.StringVar(&backup, "backup", "", "Backup used for db restore")
flags.StringVar(&kubeconfig, "kubeconfig", "~/.kube/config", "Kubeconfig for ZITADEL operator deployment")
flags.BoolVar(&gitOpsMode, "gitops", false, "defines if the operator should run in gitops mode")
cmd.RunE = func(cmd *cobra.Command, args []string) error { cmd.RunE = func(cmd *cobra.Command, args []string) error {
rv, err := getRv() rv, err := getRv()
@ -39,68 +33,55 @@ func RestoreCommand(getRv GetRootValues) *cobra.Command {
err = rv.ErrFunc(err) err = rv.ErrFunc(err)
}() }()
// TODO: Why?
monitor := rv.Monitor monitor := rv.Monitor
orbConfig := rv.OrbConfig orbConfig := rv.OrbConfig
gitClient := rv.GitClient gitClient := rv.GitClient
version := rv.Version version := rv.Version
kubeconfig = helpers.PruneHome(kubeconfig) if !rv.Gitops {
return errors.New("restore command is only supported with the --gitops flag yet")
if err := gitClient.Configure(orbConfig.URL, []byte(orbConfig.Repokey)); err != nil {
monitor.Error(err)
return nil
} }
if err := gitClient.Clone(); err != nil { k8sClient, _, err := cli.Client(monitor, orbConfig, gitClient, rv.Kubeconfig, rv.Gitops)
monitor.Error(err) if err != nil {
return nil return err
} }
value, err := ioutil.ReadFile(kubeconfig) list, err := databases.ListBackups(monitor, gitClient)
if err != nil { if err != nil {
monitor.Error(err) monitor.Error(err)
return nil return nil
} }
kubeconfigStr := string(value)
k8sClient := kubernetes.NewK8sClient(monitor, &kubeconfigStr) if backup == "" {
if k8sClient.Available() { prompt := promptui.Select{
list, err := databases.ListBackups(monitor, gitClient) Label: "Select backup to restore",
Items: list,
}
_, result, err := prompt.Run()
if err != nil { if err != nil {
monitor.Error(err) monitor.Error(err)
return nil return nil
} }
backup = result
if backup == "" { }
prompt := promptui.Select{ existing := false
Label: "Select backup to restore", for _, listedBackup := range list {
Items: list, if listedBackup == backup {
} existing = true
_, result, err := prompt.Run()
if err != nil {
monitor.Error(err)
return nil
}
backup = result
}
existing := false
for _, listedBackup := range list {
if listedBackup == backup {
existing = true
}
} }
}
if !existing { if !existing {
monitor.Error(errors.New("chosen backup is not existing")) monitor.Error(errors.New("chosen backup is not existing"))
return nil
}
if err := crtlgitops.Restore(monitor, gitClient, orbConfig, k8sClient, backup, gitOpsMode, &version); err != nil {
monitor.Error(err)
}
return nil return nil
} }
if err := crtlgitops.Restore(monitor, gitClient, orbConfig, k8sClient, backup, rv.Gitops, &version); err != nil {
monitor.Error(err)
}
return nil return nil
} }
return cmd return cmd

View File

@ -2,7 +2,7 @@ package cmds
import ( import (
"github.com/caos/orbos/pkg/kubernetes/cli" "github.com/caos/orbos/pkg/kubernetes/cli"
"github.com/ghodss/yaml" "gopkg.in/yaml.v3"
orbdb "github.com/caos/zitadel/operator/database/kinds/orb" orbdb "github.com/caos/zitadel/operator/database/kinds/orb"
@ -17,19 +17,13 @@ import (
func TakeoffCommand(getRv GetRootValues) *cobra.Command { func TakeoffCommand(getRv GetRootValues) *cobra.Command {
var ( var (
gitOpsZitadel bool cmd = &cobra.Command{
gitOpsDatabase bool
cmd = &cobra.Command{
Use: "takeoff", Use: "takeoff",
Short: "Launch a ZITADEL operator on the orb", Short: "Launch a ZITADEL operator on the orb",
Long: "Ensures a desired state of the resources on the orb", Long: "Ensures a desired state of the resources on the orb",
} }
) )
flags := cmd.Flags()
flags.BoolVar(&gitOpsZitadel, "gitops-zitadel", false, "defines if the zitadel operator should run in gitops mode")
flags.BoolVar(&gitOpsDatabase, "gitops-database", false, "defines if the database operator should run in gitops mode")
cmd.RunE = func(cmd *cobra.Command, args []string) error { cmd.RunE = func(cmd *cobra.Command, args []string) error {
rv, err := getRv() rv, err := getRv()
if err != nil { if err != nil {
@ -48,7 +42,7 @@ func TakeoffCommand(getRv GetRootValues) *cobra.Command {
orbConfig, orbConfig,
gitClient, gitClient,
rv.Kubeconfig, rv.Kubeconfig,
gitOpsZitadel || gitOpsDatabase, rv.Gitops,
) )
if err != nil { if err != nil {
return err return err
@ -59,7 +53,7 @@ func TakeoffCommand(getRv GetRootValues) *cobra.Command {
return err return err
} }
if gitOpsZitadel || gitOpsDatabase { if rv.Gitops {
orbConfigBytes, err := yaml.Marshal(orbConfig) orbConfigBytes, err := yaml.Marshal(orbConfig)
if err != nil { if err != nil {
@ -77,7 +71,7 @@ func TakeoffCommand(getRv GetRootValues) *cobra.Command {
gitClient, gitClient,
k8sClient, k8sClient,
rv.Version, rv.Version,
rv.Gitops || gitOpsZitadel, rv.Gitops,
); err != nil { ); err != nil {
monitor.Error(err) monitor.Error(err)
} }
@ -87,7 +81,7 @@ func TakeoffCommand(getRv GetRootValues) *cobra.Command {
gitClient, gitClient,
k8sClient, k8sClient,
rv.Version, rv.Version,
rv.Gitops || gitOpsDatabase, rv.Gitops,
); err != nil { ); err != nil {
monitor.Error(err) monitor.Error(err)
} }
@ -113,11 +107,10 @@ func deployOperator(monitor mntr.Monitor, gitClient *git.Client, k8sClient kuber
return err return err
} }
spec := desired.Spec spec := desired.Spec
spec.GitOps = gitops
// at takeoff the artifacts have to be applied // at takeoff the artifacts have to be applied
spec.SelfReconciling = true spec.SelfReconciling = true
if err := orbzit.Reconcile(monitor, spec)(k8sClient); err != nil { if err := orbzit.Reconcile(monitor, spec, gitops)(k8sClient); err != nil {
return err return err
} }
} }
@ -126,10 +119,9 @@ func deployOperator(monitor mntr.Monitor, gitClient *git.Client, k8sClient kuber
spec := &orbzit.Spec{ spec := &orbzit.Spec{
Version: version, Version: version,
SelfReconciling: true, SelfReconciling: true,
GitOps: gitops,
} }
if err := orbzit.Reconcile(monitor, spec)(k8sClient); err != nil { if err := orbzit.Reconcile(monitor, spec, gitops)(k8sClient); err != nil {
return err return err
} }
} }
@ -153,13 +145,14 @@ func deployDatabase(monitor mntr.Monitor, gitClient *git.Client, k8sClient kuber
return err return err
} }
spec := desired.Spec spec := desired.Spec
spec.GitOps = gitops
// at takeoff the artifacts have to be applied // at takeoff the artifacts have to be applied
spec.SelfReconciling = true spec.SelfReconciling = true
if err := orbdb.Reconcile( if err := orbdb.Reconcile(
monitor, monitor,
spec)(k8sClient); err != nil { spec,
gitops,
)(k8sClient); err != nil {
return err return err
} }
} }
@ -168,12 +161,13 @@ func deployDatabase(monitor mntr.Monitor, gitClient *git.Client, k8sClient kuber
spec := &orbdb.Spec{ spec := &orbdb.Spec{
Version: version, Version: version,
SelfReconciling: true, SelfReconciling: true,
GitOps: gitops,
} }
if err := orbdb.Reconcile( if err := orbdb.Reconcile(
monitor, monitor,
spec)(k8sClient); err != nil { spec,
gitops,
)(k8sClient); err != nil {
return err return err
} }
} }

View File

@ -99,7 +99,7 @@ func AdaptFunc(timestamp string, binaryVersion *string, gitops bool, features ..
case "operator": case "operator":
queriers = append(queriers, queriers = append(queriers,
operator.ResourceQueryToZitadelQuery(queryNS), operator.ResourceQueryToZitadelQuery(queryNS),
operator.EnsureFuncToQueryFunc(Reconcile(monitor, desiredKind.Spec)), operator.EnsureFuncToQueryFunc(Reconcile(monitor, desiredKind.Spec, gitops)),
) )
} }
} }

View File

@ -19,7 +19,6 @@ type Spec struct {
Tolerations []corev1.Toleration `json:"tolerations,omitempty" yaml:"tolerations,omitempty"` Tolerations []corev1.Toleration `json:"tolerations,omitempty" yaml:"tolerations,omitempty"`
Version string `json:"version,omitempty" yaml:"version,omitempty"` Version string `json:"version,omitempty" yaml:"version,omitempty"`
SelfReconciling bool `json:"selfReconciling" yaml:"selfReconciling"` SelfReconciling bool `json:"selfReconciling" yaml:"selfReconciling"`
GitOps bool `json:"gitOps,omitempty" yaml:"gitOps,omitempty"`
//Use this registry to pull the Database operator image from //Use this registry to pull the Database operator image from
//@default: ghcr.io //@default: ghcr.io
CustomImageRegistry string `json:"customImageRegistry,omitempty" yaml:"customImageRegistry,omitempty"` CustomImageRegistry string `json:"customImageRegistry,omitempty" yaml:"customImageRegistry,omitempty"`

View File

@ -13,6 +13,7 @@ import (
func Reconcile( func Reconcile(
monitor mntr.Monitor, monitor mntr.Monitor,
spec *Spec, spec *Spec,
gitops bool,
) operator.EnsureFunc { ) operator.EnsureFunc {
return func(k8sClient kubernetes.ClientInt) (err error) { return func(k8sClient kubernetes.ClientInt) (err error) {
recMonitor := monitor.WithField("version", spec.Version) recMonitor := monitor.WithField("version", spec.Version)
@ -36,7 +37,7 @@ func Reconcile(
}, },
} }
if err := zitadelKubernetes.EnsureDatabaseArtifacts(monitor, treelabels.MustForAPI(desiredTree, mustDatabaseOperator(&spec.Version)), k8sClient, spec.Version, spec.NodeSelector, spec.Tolerations, imageRegistry, spec.GitOps); err != nil { if err := zitadelKubernetes.EnsureDatabaseArtifacts(monitor, treelabels.MustForAPI(desiredTree, mustDatabaseOperator(&spec.Version)), k8sClient, spec.Version, spec.NodeSelector, spec.Tolerations, imageRegistry, gitops); err != nil {
recMonitor.Error(errors.Wrap(err, "Failed to deploy database-operator into k8s-cluster")) recMonitor.Error(errors.Wrap(err, "Failed to deploy database-operator into k8s-cluster"))
return err return err
} }

View File

@ -112,7 +112,7 @@ func AdaptFunc(
case "operator": case "operator":
queriers = append(queriers, queriers = append(queriers,
operator.ResourceQueryToZitadelQuery(queryNS), operator.ResourceQueryToZitadelQuery(queryNS),
operator.EnsureFuncToQueryFunc(Reconcile(monitor, desiredKind.Spec)), operator.EnsureFuncToQueryFunc(Reconcile(monitor, desiredKind.Spec, gitops)),
) )
} }
} }

View File

@ -19,7 +19,6 @@ type Spec struct {
Tolerations []corev1.Toleration `json:"tolerations,omitempty" yaml:"tolerations,omitempty"` Tolerations []corev1.Toleration `json:"tolerations,omitempty" yaml:"tolerations,omitempty"`
Version string `json:"version,omitempty" yaml:"version,omitempty"` Version string `json:"version,omitempty" yaml:"version,omitempty"`
SelfReconciling bool `json:"selfReconciling" yaml:"selfReconciling"` SelfReconciling bool `json:"selfReconciling" yaml:"selfReconciling"`
GitOps bool `json:"gitops,omitempty" yaml:"gitops,omitempty"`
//Use this registry to pull the zitadel operator image from //Use this registry to pull the zitadel operator image from
//@default: ghcr.io //@default: ghcr.io
CustomImageRegistry string `json:"customImageRegistry,omitempty" yaml:"customImageRegistry,omitempty"` CustomImageRegistry string `json:"customImageRegistry,omitempty" yaml:"customImageRegistry,omitempty"`

View File

@ -13,6 +13,7 @@ import (
func Reconcile( func Reconcile(
monitor mntr.Monitor, monitor mntr.Monitor,
spec *Spec, spec *Spec,
gitops bool,
) operator.EnsureFunc { ) operator.EnsureFunc {
return func(k8sClient kubernetes2.ClientInt) (err error) { return func(k8sClient kubernetes2.ClientInt) (err error) {
recMonitor := monitor.WithField("version", spec.Version) recMonitor := monitor.WithField("version", spec.Version)
@ -36,7 +37,7 @@ func Reconcile(
}, },
} }
if err := kubernetes.EnsureZitadelOperatorArtifacts(monitor, treelabels.MustForAPI(desiredTree, mustZITADELOperator(&spec.Version)), k8sClient, spec.Version, spec.NodeSelector, spec.Tolerations, imageRegistry, spec.GitOps); err != nil { if err := kubernetes.EnsureZitadelOperatorArtifacts(monitor, treelabels.MustForAPI(desiredTree, mustZITADELOperator(&spec.Version)), k8sClient, spec.Version, spec.NodeSelector, spec.Tolerations, imageRegistry, gitops); err != nil {
recMonitor.Error(errors.Wrap(err, "Failed to deploy zitadel-operator into k8s-cluster")) recMonitor.Error(errors.Wrap(err, "Failed to deploy zitadel-operator into k8s-cluster"))
return err return err
} }