feat(operator): make running ZITADEL easy (#1562)

* docs: describe crd mode

* docs: fix links

* docs: fix commands and crdb resources

* feat: add configure command

* chore: use latest ORBOS

* chore: use latest ORBOS

* docs: start gitops docs

* fix: compile

* chore: fix build script path

* chore: remove redundant prebuild

* chore: add configure.go

* docs: describe gitops mode

* docs: point template links to main branch

* docs: fix versions

* feat: initialize empty keys

* feat: reconfigure running ZITADEL

* docs: describe crd mode

* docs: fix links

* docs: fix commands and crdb resources

* feat: add configure command

* chore: use latest ORBOS

* chore: use latest ORBOS

* docs: start gitops docs

* fix: compile

* chore: fix build script path

* chore: remove redundant prebuild

* chore: add configure.go

* docs: describe gitops mode

* docs: point template links to main branch

* docs: fix versions

* feat: initialize empty keys

* feat: reconfigure running ZITADEL

* test: fix

* docs: keys are generated with configure

* docs: remove keys from template

* chore: pass compile time data

* chore: use latest ORBOS

* fix: when in-cluster, use in-cluster k8s client

* fix: try in-cluster config if kubeconfig is empty

* fix: reduce unneeded side effects for configure command

* docs: boom version

* chore: use latest ORBOS

* chore: use latest ORBOS

* initial commit

* inital changes

* commit WIP Information Architecture

* commit a working state

* add static assets and project

* add org and fix img names

* add plausible

* remove img

* change sidebar to easier mgmt

* add openid oauth and domains

* lint md

* quickstarts

* add auth flow

* identity brokering

* remove site

* fix broken links

* extend footer

* extend readme

* fix: styling

* fix: zitadel logo on index

* styling

* border

* fix: nav

* fix: nav

* fix: index

* fix: corrected zitadelctl examples

* fix: rename architecture to concepts

* fix: introductions

* fix: introductions

* fix: introductions

* docs: cli r/w secrets examples

* docs: finish ZITADEL Enterprise Cloud

* docs: mention ZITADEL Enterprise Cloud tier

* docs: comment configuration options

* docs: fix broken links

* docs: move some introduction texts around

* docs: twilio and email are mandatory

* docs: download latest binaries

Co-authored-by: Florian Forster <[email protected]>
Co-authored-by: fabi <[email protected]>
Co-authored-by: Livio Amstutz <[email protected]>
Co-authored-by: Stefan Benz <[email protected]>
This commit is contained in:
Elio Bischof
2021-04-22 16:43:34 +00:00
committed by GitHub
co-authored by Florian Forster fabi Livio Amstutz Stefan Benz
parent 06281b5ccb
commit c0878e4509
73 changed files with 1015 additions and 536 deletions
+15 -1
View File
@@ -11,12 +11,26 @@ import (
"gopkg.in/yaml.v3"
)
type AdaptFunc func(monitor mntr.Monitor, desired *tree.Tree, current *tree.Tree) (QueryFunc, DestroyFunc, map[string]*secret.Secret, map[string]*secret.Existing, bool, error)
type AdaptFunc func(
monitor mntr.Monitor,
desired *tree.Tree,
current *tree.Tree,
) (
QueryFunc,
DestroyFunc,
ConfigureFunc,
map[string]*secret.Secret,
map[string]*secret.Existing,
bool,
error,
)
type EnsureFunc func(k8sClient kubernetes.ClientInt) error
type DestroyFunc func(k8sClient kubernetes.ClientInt) error
type ConfigureFunc func(k8sClient kubernetes.ClientInt, queried map[string]interface{}, gitops bool) error
type QueryFunc func(k8sClient kubernetes.ClientInt, queried map[string]interface{}) (EnsureFunc, error)
func Parse(gitClient *git.Client, file string) (*tree.Tree, error) {
-83
View File
@@ -1,83 +0,0 @@
package api
import (
"github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/git"
"github.com/caos/orbos/pkg/tree"
"github.com/caos/zitadel/operator/common"
"gopkg.in/yaml.v3"
)
const (
zitadelFile = "zitadel.yml"
databaseFile = "database.yml"
)
type PushDesiredFunc func(monitor mntr.Monitor) error
func ExistsZitadelYml(gitClient *git.Client) (bool, error) {
return existsFileInGit(gitClient, zitadelFile)
}
func ReadZitadelYml(gitClient *git.Client) (*tree.Tree, error) {
return readFileInGit(gitClient, zitadelFile)
}
func PushZitadelYml(monitor mntr.Monitor, msg string, gitClient *git.Client, desired *tree.Tree) (err error) {
return pushFileInGit(monitor, msg, gitClient, desired, zitadelFile)
}
func PushZitadelDesiredFunc(gitClient *git.Client, desired *tree.Tree) PushDesiredFunc {
return func(monitor mntr.Monitor) error {
monitor.Info("Writing zitadel desired state")
return PushZitadelYml(monitor, "Zitadel desired state written", gitClient, desired)
}
}
func ExistsDatabaseYml(gitClient *git.Client) (bool, error) {
return existsFileInGit(gitClient, databaseFile)
}
func ReadDatabaseYml(gitClient *git.Client) (*tree.Tree, error) {
return readFileInGit(gitClient, databaseFile)
}
func PushDatabaseYml(monitor mntr.Monitor, msg string, gitClient *git.Client, desired *tree.Tree) (err error) {
return pushFileInGit(monitor, msg, gitClient, desired, databaseFile)
}
func PushDatabaseDesiredFunc(gitClient *git.Client, desired *tree.Tree) PushDesiredFunc {
return func(monitor mntr.Monitor) error {
monitor.Info("Writing database desired state")
return PushDatabaseYml(monitor, "Database desired state written", gitClient, desired)
}
}
func pushFileInGit(monitor mntr.Monitor, msg string, gitClient *git.Client, desired *tree.Tree, path string) (err error) {
monitor.OnChange = func(_ string, fields map[string]string) {
err = gitClient.UpdateRemote(mntr.SprintCommit(msg, fields), git.File{
Path: path,
Content: common.MarshalYAML(desired),
})
mntr.LogMessage(msg, fields)
}
monitor.Changed(msg)
return err
}
func existsFileInGit(gitClient *git.Client, path string) (bool, error) {
of := gitClient.Read(path)
if of != nil && len(of) > 0 {
return true, nil
}
return false, nil
}
func readFileInGit(gitClient *git.Client, path string) (*tree.Tree, error) {
tree := &tree.Tree{}
if err := yaml.Unmarshal(gitClient.Read(path), tree); err != nil {
return nil, err
}
return tree, nil
}
+4 -1
View File
@@ -42,7 +42,10 @@ func Start(monitor mntr.Monitor, version, metricsAddr string, features ...string
return errors.Wrap(err, "unable to start manager")
}
k8sClient := kubernetes.NewK8sClientWithConfig(monitor, cfg)
k8sClient, err := kubernetes.NewK8sClientWithConfig(monitor, cfg)
if err != nil {
return err
}
for _, feature := range features {
switch feature {
+1 -1
View File
@@ -41,7 +41,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.
return res, err
}
query, _, _, _, _, err := orbdb.AdaptFunc("", &r.Version, false, "database")(internalMonitor, desired, &tree.Tree{})
query, _, _, _, _, _, err := orbdb.AdaptFunc("", &r.Version, false, "database")(internalMonitor, desired, &tree.Tree{})
if err != nil {
internalMonitor.Error(err)
return res, err
+1 -1
View File
@@ -40,7 +40,7 @@ func (r *Reconciler) Reconcile(ctx context.Context, req ctrl.Request) (res ctrl.
return res, err
}
query, _, _, _, _, err := orbz.AdaptFunc(nil, "ensure", &r.Version, false, []string{"operator", "iam"})(internalMonitor, desired, &tree.Tree{})
query, _, _, _, _, _, err := orbz.AdaptFunc(nil, "ensure", &r.Version, false, []string{"operator", "iam"})(internalMonitor, desired, &tree.Tree{})
if err != nil {
internalMonitor.Error(err)
return res, err
+3 -2
View File
@@ -11,7 +11,7 @@ import (
corev1 "k8s.io/api/core/v1"
)
func GetQueryAndDestroyFuncs(
func Adapt(
monitor mntr.Monitor,
desiredTree *tree.Tree,
currentTree *tree.Tree,
@@ -27,6 +27,7 @@ func GetQueryAndDestroyFuncs(
) (
operator.QueryFunc,
operator.DestroyFunc,
operator.ConfigureFunc,
map[string]*secret.Secret,
map[string]*secret.Existing,
bool,
@@ -52,7 +53,7 @@ func GetQueryAndDestroyFuncs(
features,
)(monitor, desiredTree, currentTree)
default:
return nil, nil, nil, nil, false, errors.Errorf("unknown database kind %s", desiredTree.Common.Kind)
return nil, nil, nil, nil, nil, false, errors.Errorf("unknown database kind %s", desiredTree.Common.Kind)
}
}
@@ -2,11 +2,11 @@ package bucket
import (
"github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/helper"
"github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/orbos/pkg/kubernetes/resources/secret"
"github.com/caos/orbos/pkg/labels"
secretpkg "github.com/caos/orbos/pkg/secret"
"github.com/caos/orbos/pkg/secret/read"
"github.com/caos/orbos/pkg/tree"
"github.com/caos/zitadel/operator"
"github.com/caos/zitadel/operator/database/kinds/backups/bucket/backup"
@@ -40,6 +40,7 @@ func AdaptFunc(
) (
operator.QueryFunc,
operator.DestroyFunc,
operator.ConfigureFunc,
map[string]*secretpkg.Secret,
map[string]*secretpkg.Existing,
bool,
@@ -50,7 +51,7 @@ func AdaptFunc(
desiredKind, err := ParseDesiredV0(desired)
if err != nil {
return nil, nil, nil, nil, false, errors.Wrap(err, "parsing desired state failed")
return nil, nil, nil, nil, nil, false, errors.Wrap(err, "parsing desired state failed")
}
desired.Parsed = desiredKind
@@ -62,7 +63,7 @@ func AdaptFunc(
destroyS, err := secret.AdaptFuncToDestroy(namespace, secretName)
if err != nil {
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
_, destroyB, err := backup.AdaptFunc(
@@ -83,7 +84,7 @@ func AdaptFunc(
version,
)
if err != nil {
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
_, destroyR, err := restore.AdaptFunc(
@@ -102,7 +103,7 @@ func AdaptFunc(
version,
)
if err != nil {
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
_, destroyC, err := clean.AdaptFunc(
@@ -119,7 +120,7 @@ func AdaptFunc(
version,
)
if err != nil {
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
destroyers := make([]operator.DestroyFunc, 0)
@@ -157,7 +158,7 @@ func AdaptFunc(
databases = []string{}
}
value, err := helper.GetSecretValue(k8sClient, desiredKind.Spec.ServiceAccountJSON, desiredKind.Spec.ExistingServiceAccountJSON)
value, err := read.GetSecretValue(k8sClient, desiredKind.Spec.ServiceAccountJSON, desiredKind.Spec.ExistingServiceAccountJSON)
if err != nil {
return nil, err
}
@@ -269,6 +270,7 @@ func AdaptFunc(
return operator.QueriersToEnsureFunc(internalMonitor, false, queriers, k8sClient, queried)
},
operator.DestroyersToDestroyFunc(internalMonitor, destroyers),
func(kubernetes.ClientInt, map[string]interface{}, bool) error { return nil },
secrets,
existing,
false,
@@ -61,7 +61,7 @@ func TestBucket_Secrets(t *testing.T) {
"serviceaccountjson": saJson,
}
_, _, secrets, existing, _, err := AdaptFunc(
_, _, _, secrets, existing, _, err := AdaptFunc(
backupName,
namespace,
componentLabels,
@@ -133,7 +133,7 @@ func TestBucket_AdaptBackup(t *testing.T) {
SetBackup(client, namespace, k8sLabels, saJson)
query, _, _, _, _, err := AdaptFunc(
query, _, _, _, _, _, err := AdaptFunc(
backupName,
namespace,
componentLabels,
@@ -207,7 +207,7 @@ func TestBucket_AdaptInstantBackup(t *testing.T) {
SetInstantBackup(client, namespace, backupName, k8sLabels, saJson)
query, _, _, _, _, err := AdaptFunc(
query, _, _, _, _, _, err := AdaptFunc(
backupName,
namespace,
componentLabels,
@@ -282,7 +282,7 @@ func TestBucket_AdaptRestore(t *testing.T) {
SetRestore(client, namespace, backupName, k8sLabels, saJson)
query, _, _, _, _, err := AdaptFunc(
query, _, _, _, _, _, err := AdaptFunc(
backupName,
namespace,
componentLabels,
@@ -357,7 +357,7 @@ func TestBucket_AdaptClean(t *testing.T) {
SetClean(client, namespace, backupName, k8sLabels, saJson)
query, _, _, _, _, err := AdaptFunc(
query, _, _, _, _, _, err := AdaptFunc(
backupName,
namespace,
componentLabels,
@@ -20,7 +20,7 @@ func ComponentSelector() *labels.Selector {
return labels.OpenComponentSelector("ZITADEL", component)
}
func GetQueryAndDestroyFuncs(
func Adapt(
monitor mntr.Monitor,
desiredTree *tree.Tree,
currentTree *tree.Tree,
@@ -34,6 +34,7 @@ func GetQueryAndDestroyFuncs(
) (
query operator.QueryFunc,
destroy operator.DestroyFunc,
configure operator.ConfigureFunc,
secrets map[string]*secret.Secret,
existing map[string]*secret.Existing,
migrate bool,
@@ -44,11 +45,11 @@ func GetQueryAndDestroyFuncs(
switch desiredTree.Common.Kind {
case "databases.caos.ch/CockroachDB":
return managed.AdaptFunc(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features)(internalMonitor, desiredTree, currentTree)
return managed.Adapter(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features)(internalMonitor, desiredTree, currentTree)
case "databases.caos.ch/ProvidedDatabase":
return provided.AdaptFunc()(internalMonitor, desiredTree, currentTree)
return provided.Adapter()(internalMonitor, desiredTree, currentTree)
default:
return nil, nil, nil, nil, false, errors.Errorf("unknown database kind %s", desiredTree.Common.Kind)
return nil, nil, nil, nil, nil, false, errors.Errorf("unknown database kind %s", desiredTree.Common.Kind)
}
}
@@ -36,7 +36,7 @@ const (
image = "cockroachdb/cockroach:v20.2.3"
)
func AdaptFunc(
func Adapter(
componentLabels *labels.Component,
namespace string,
timestamp string,
@@ -44,18 +44,7 @@ func AdaptFunc(
tolerations []corev1.Toleration,
version string,
features []string,
) func(
monitor mntr.Monitor,
desired *tree.Tree,
current *tree.Tree,
) (
operator.QueryFunc,
operator.DestroyFunc,
map[string]*secret.Secret,
map[string]*secret.Existing,
bool,
error,
) {
) operator.AdaptFunc {
return func(
monitor mntr.Monitor,
@@ -64,6 +53,7 @@ func AdaptFunc(
) (
operator.QueryFunc,
operator.DestroyFunc,
operator.ConfigureFunc,
map[string]*secret.Secret,
map[string]*secret.Existing,
bool,
@@ -79,7 +69,7 @@ func AdaptFunc(
desiredKind, err := parseDesiredV0(desired)
if err != nil {
return nil, nil, nil, nil, false, errors.Wrap(err, "parsing desired state failed")
return nil, nil, nil, nil, nil, false, errors.Wrap(err, "parsing desired state failed")
}
desired.Parsed = desiredKind
@@ -102,15 +92,15 @@ func AdaptFunc(
queryCert, destroyCert, addUser, deleteUser, listUsers, err := certificate.AdaptFunc(internalMonitor, namespace, componentLabels, desiredKind.Spec.ClusterDns, isFeatureDatabase)
if err != nil {
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
addRoot, err := addUser("root")
if err != nil {
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
destroyRoot, err := deleteUser("root")
if err != nil {
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
queryRBAC, destroyRBAC, err := rbac.AdaptFunc(internalMonitor, namespace, labels.MustForName(componentLabels, serviceAccountName))
@@ -136,7 +126,7 @@ func AdaptFunc(
desiredKind.Spec.Resources,
)
if err != nil {
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
queryS, destroyS, err := services.AdaptFunc(
@@ -157,12 +147,12 @@ func AdaptFunc(
queryPDB, err := pdb.AdaptFuncToEnsure(namespace, labels.MustForName(componentLabels, pdbName), cockroachSelector, "1")
if err != nil {
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
destroyPDB, err := pdb.AdaptFuncToDestroy(namespace, pdbName)
if err != nil {
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
currentDB := &Current{
@@ -176,7 +166,11 @@ func AdaptFunc(
}
current.Parsed = currentDB
queriers := make([]operator.QueryFunc, 0)
var (
queriers = make([]operator.QueryFunc, 0)
destroyers = make([]operator.DestroyFunc, 0)
configurers = make([]operator.ConfigureFunc, 0)
)
if isFeatureDatabase {
queriers = append(queriers,
queryRBAC,
@@ -189,7 +183,6 @@ func AdaptFunc(
)
}
destroyers := make([]operator.DestroyFunc, 0)
if isFeatureDatabase {
destroyers = append(destroyers,
operator.ResourceDestroyToZitadelDestroy(destroyPDB),
@@ -213,7 +206,7 @@ func AdaptFunc(
for backupName, desiredBackup := range desiredKind.Spec.Backups {
currentBackup := &tree.Tree{}
if timestamp == "" || !oneBackup || (timestamp != "" && strings.HasPrefix(timestamp, backupName)) {
queryB, destroyB, secrets, existing, migrateB, err := backups.GetQueryAndDestroyFuncs(
queryB, destroyB, configureB, secrets, existing, migrateB, err := backups.Adapt(
internalMonitor,
desiredBackup,
currentBackup,
@@ -228,7 +221,7 @@ func AdaptFunc(
features,
)
if err != nil {
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
migrate = migrate || migrateB
@@ -236,6 +229,7 @@ func AdaptFunc(
secret.AppendSecrets(backupName, allSecrets, secrets, allExisting, existing)
destroyers = append(destroyers, destroyB)
queriers = append(queriers, queryB)
configurers = append(configurers, configureB)
}
}
}
@@ -262,6 +256,14 @@ func AdaptFunc(
return ensure, err
},
operator.DestroyersToDestroyFunc(internalMonitor, destroyers),
func(k8sClient kubernetes.ClientInt, queried map[string]interface{}, gitops bool) error {
for i := range configurers {
if err := configurers[i](k8sClient, queried, gitops); err != nil {
return err
}
}
return nil
},
allSecrets,
allExisting,
migrate,
@@ -84,7 +84,7 @@ func TestManaged_AdaptBucketBackup(t *testing.T) {
bucket.SetBackup(k8sClient, namespace, labels, saJson)
k8sClient.EXPECT().WaitUntilStatefulsetIsReady(namespace, SfsName, true, true, 60*time.Second)
query, _, _, _, _, err := AdaptFunc(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features)(monitor, desired, &tree.Tree{})
query, _, _, _, _, _, err := Adapter(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features)(monitor, desired, &tree.Tree{})
assert.NoError(t, err)
databases := []string{"test1", "test2"}
@@ -124,7 +124,7 @@ func TestManaged_AdaptBucketInstantBackup(t *testing.T) {
desired := getTreeWithDBAndBackup(t, masterkey, saJson, backupName)
query, _, _, _, _, err := AdaptFunc(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features)(monitor, desired, &tree.Tree{})
query, _, _, _, _, _, err := Adapter(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features)(monitor, desired, &tree.Tree{})
assert.NoError(t, err)
databases := []string{"test1", "test2"}
@@ -165,7 +165,7 @@ func TestManaged_AdaptBucketCleanAndRestore(t *testing.T) {
desired := getTreeWithDBAndBackup(t, masterkey, saJson, backupName)
query, _, _, _, _, err := AdaptFunc(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features)(monitor, desired, &tree.Tree{})
query, _, _, _, _, _, err := Adapter(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features)(monitor, desired, &tree.Tree{})
assert.NoError(t, err)
databases := []string{"test1", "test2"}
@@ -133,7 +133,7 @@ func TestManaged_Adapt1(t *testing.T) {
dbCurrent.EXPECT().SetCertificateKey(gomock.Any()).MinTimes(1).MaxTimes(1)
k8sClient.EXPECT().ApplySecret(gomock.Any()).MinTimes(1).MaxTimes(1)
query, _, _, _, _, err := AdaptFunc(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features)(monitor, desired, &tree.Tree{})
query, _, _, _, _, _, err := Adapter(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features)(monitor, desired, &tree.Tree{})
assert.NoError(t, err)
ensure, err := query(k8sClient, queried)
@@ -245,7 +245,7 @@ func TestManaged_Adapt2(t *testing.T) {
dbCurrent.EXPECT().SetCertificateKey(gomock.Any()).MinTimes(1).MaxTimes(1)
k8sClient.EXPECT().ApplySecret(gomock.Any()).MinTimes(1).MaxTimes(1)
query, _, _, _, _, err := AdaptFunc(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features)(monitor, desired, &tree.Tree{})
query, _, _, _, _, _, err := Adapter(componentLabels, namespace, timestamp, nodeselector, tolerations, version, features)(monitor, desired, &tree.Tree{})
assert.NoError(t, err)
ensure, err := query(k8sClient, queried)
@@ -9,18 +9,7 @@ import (
"github.com/pkg/errors"
)
func AdaptFunc() func(
monitor mntr.Monitor,
desired *tree.Tree,
current *tree.Tree,
) (
operator.QueryFunc,
operator.DestroyFunc,
map[string]*secret.Secret,
map[string]*secret.Existing,
bool,
error,
) {
func Adapter() operator.AdaptFunc {
return func(
monitor mntr.Monitor,
desired *tree.Tree,
@@ -28,6 +17,7 @@ func AdaptFunc() func(
) (
operator.QueryFunc,
operator.DestroyFunc,
operator.ConfigureFunc,
map[string]*secret.Secret,
map[string]*secret.Existing,
bool,
@@ -35,7 +25,7 @@ func AdaptFunc() func(
) {
desiredKind, err := parseDesiredV0(desired)
if err != nil {
return nil, nil, nil, nil, false, errors.Wrap(err, "parsing desired state failed")
return nil, nil, nil, nil, nil, false, errors.Wrap(err, "parsing desired state failed")
}
desired.Parsed = desiredKind
@@ -57,6 +47,7 @@ func AdaptFunc() func(
}, func(k8sClient kubernetes.ClientInt) error {
return nil
},
func(kubernetes.ClientInt, map[string]interface{}, bool) error { return nil },
make(map[string]*secret.Secret),
make(map[string]*secret.Existing),
false,
+14 -5
View File
@@ -24,7 +24,12 @@ func OperatorSelector() *labels.Selector {
return labels.OpenOperatorSelector("ZITADEL", "database.caos.ch")
}
func AdaptFunc(timestamp string, binaryVersion *string, gitops bool, features ...string) operator.AdaptFunc {
func AdaptFunc(
timestamp string,
binaryVersion *string,
gitops bool,
features ...string,
) operator.AdaptFunc {
return func(
monitor mntr.Monitor,
@@ -33,6 +38,7 @@ func AdaptFunc(timestamp string, binaryVersion *string, gitops bool, features ..
) (
queryFunc operator.QueryFunc,
destroyFunc operator.DestroyFunc,
configureFunc operator.ConfigureFunc,
secrets map[string]*secret.Secret,
existing map[string]*secret.Existing,
migrate bool,
@@ -46,7 +52,7 @@ func AdaptFunc(timestamp string, binaryVersion *string, gitops bool, features ..
desiredKind, err := ParseDesiredV0(orbDesiredTree)
if err != nil {
return nil, nil, nil, nil, migrate, errors.Wrap(err, "parsing desired state failed")
return nil, nil, nil, nil, nil, migrate, errors.Wrap(err, "parsing desired state failed")
}
orbDesiredTree.Parsed = desiredKind
currentTree = &tree.Tree{}
@@ -57,7 +63,7 @@ func AdaptFunc(timestamp string, binaryVersion *string, gitops bool, features ..
queryNS, err := namespace.AdaptFuncToEnsure(NamespaceStr)
if err != nil {
return nil, nil, nil, nil, migrate, err
return nil, nil, nil, nil, nil, migrate, err
}
/*destroyNS, err := namespace.AdaptFuncToDestroy(NamespaceStr)
if err != nil {
@@ -68,7 +74,7 @@ func AdaptFunc(timestamp string, binaryVersion *string, gitops bool, features ..
operatorLabels := mustDatabaseOperator(binaryVersion)
queryDB, destroyDB, secrets, existing, migrate, err := databases.GetQueryAndDestroyFuncs(
queryDB, destroyDB, configureDB, secrets, existing, migrate, err := databases.Adapt(
orbMonitor,
desiredKind.Database,
databaseCurrent,
@@ -81,7 +87,7 @@ func AdaptFunc(timestamp string, binaryVersion *string, gitops bool, features ..
features,
)
if err != nil {
return nil, nil, nil, nil, migrate, err
return nil, nil, nil, nil, nil, migrate, err
}
destroyers := make([]operator.DestroyFunc, 0)
@@ -123,6 +129,9 @@ func AdaptFunc(timestamp string, binaryVersion *string, gitops bool, features ..
monitor.WithField("destroyers", len(queriers)).Info("Destroy")
return operator.DestroyersToDestroyFunc(monitor, destroyers)(k8sClient)
},
func(k8sClient kubernetes.ClientInt, queried map[string]interface{}, gitops bool) error {
return configureDB(k8sClient, queried, gitops)
},
secrets,
existing,
migrate,
+1 -8
View File
@@ -1,8 +1,6 @@
package database
import (
"errors"
"github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/git"
"github.com/caos/orbos/pkg/kubernetes"
@@ -21,12 +19,7 @@ func Takeoff(monitor mntr.Monitor, gitClient *git.Client, adapt operator.AdaptFu
}
treeCurrent := &tree.Tree{}
if !k8sClient.Available() {
internalMonitor.Error(errors.New("kubeclient is not available"))
return
}
query, _, _, _, _, err := adapt(internalMonitor, treeDesired, treeCurrent)
query, _, _, _, _, _, err := adapt(internalMonitor, treeDesired, treeCurrent)
if err != nil {
internalMonitor.Error(err)
return
+12 -22
View File
@@ -17,7 +17,6 @@ import (
"github.com/caos/orbos/pkg/orb"
"github.com/caos/orbos/pkg/secret"
"github.com/caos/orbos/pkg/tree"
"github.com/caos/zitadel/operator/api"
)
const (
@@ -69,15 +68,14 @@ func getAllSecrets(
monitor,
printLogs,
gitops,
gitClient,
git.ZitadelFile,
allTrees,
allSecrets,
allExisting,
zitadel,
func() (bool, error) { return api.ExistsZitadelYml(gitClient) },
func() (t *tree.Tree, err error) { return api.ReadZitadelYml(gitClient) },
func() (t *tree.Tree, err error) { return crdzit.ReadCrd(k8sClient) },
func(t *tree.Tree) (map[string]*secret.Secret, map[string]*secret.Existing, bool, error) {
_, _, secrets, existing, migrate, err := orbzit.AdaptFunc(orb, "secret", nil, gitops, []string{})(monitor, t, &tree.Tree{})
_, _, _, secrets, existing, migrate, err := orbzit.AdaptFunc(orb, "secret", nil, gitops, []string{})(monitor, t, &tree.Tree{})
return secrets, existing, migrate, err
},
); err != nil {
@@ -88,15 +86,14 @@ func getAllSecrets(
monitor,
printLogs,
gitops,
gitClient,
git.DatabaseFile,
allTrees,
allSecrets,
allExisting,
database,
func() (bool, error) { return api.ExistsDatabaseYml(gitClient) },
func() (t *tree.Tree, err error) { return api.ReadDatabaseYml(gitClient) },
func() (t *tree.Tree, err error) { return crddb.ReadCrd(k8sClient) },
func(t *tree.Tree) (map[string]*secret.Secret, map[string]*secret.Existing, bool, error) {
_, _, secrets, existing, migrate, err := orbdb.AdaptFunc("", nil, gitops, "database", "backup")(monitor, t, nil)
_, _, _, secrets, existing, migrate, err := orbdb.AdaptFunc("", nil, gitops, "database", "backup")(monitor, t, nil)
return secrets, existing, migrate, err
},
); err != nil {
@@ -141,24 +138,17 @@ func push(
) error {
var (
pushGitFunc func(*tree.Tree) error
applyCRDFunc func(*tree.Tree) error
operator string
desiredFile git.DesiredFile
)
if strings.HasPrefix(path, zitadel) {
operator = zitadel
pushGitFunc = func(desired *tree.Tree) error {
return api.PushZitadelDesiredFunc(gitClient, desired)(monitor)
}
desiredFile = git.ZitadelFile
applyCRDFunc = func(t *tree.Tree) error {
return crdzit.WriteCrd(k8sClient, t)
}
} else if strings.HasPrefix(path, database) {
operator = database
pushGitFunc = func(desired *tree.Tree) error {
return api.PushDatabaseDesiredFunc(gitClient, desired)(monitor)
}
desiredFile = git.DatabaseFile
applyCRDFunc = func(t *tree.Tree) error {
return crddb.WriteCrd(k8sClient, t)
}
@@ -166,13 +156,13 @@ func push(
return errors.New("operator unknown")
}
desired, found := trees[operator]
desired, found := trees[desiredFile.WOExtension()]
if !found {
return fmt.Errorf("desired state for %s not found", operator)
return fmt.Errorf("desired state not found for %s", desiredFile.WOExtension())
}
if gitops {
return pushGitFunc(desired)
return gitClient.PushDesiredFunc(desiredFile, desired)(monitor)
}
return applyCRDFunc(desired)
}
+3 -2
View File
@@ -15,7 +15,7 @@ import (
core "k8s.io/api/core/v1"
)
func GetQueryAndDestroyFuncs(
func Adapt(
monitor mntr.Monitor,
operatorLabels *labels.Operator,
desiredTree *tree.Tree,
@@ -30,6 +30,7 @@ func GetQueryAndDestroyFuncs(
) (
query operator.QueryFunc,
destroy operator.DestroyFunc,
configure operator.ConfigureFunc,
secrets map[string]*secret.Secret,
existing map[string]*secret.Existing,
migrate bool,
@@ -47,6 +48,6 @@ func GetQueryAndDestroyFuncs(
apiLabels := labels.MustForAPI(operatorLabels, "ZITADEL", desiredTree.Common.Version)
return zitadel.AdaptFunc(apiLabels, nodeselector, tolerations, dbClient, namespace, action, version, features)(monitor, desiredTree, currentTree)
default:
return nil, nil, nil, nil, false, errors.Errorf("unknown iam kind %s", desiredTree.Common.Kind)
return nil, nil, nil, nil, nil, false, errors.Errorf("unknown iam kind %s", desiredTree.Common.Kind)
}
}
+122 -23
View File
@@ -3,6 +3,10 @@ package zitadel
import (
"strconv"
"github.com/caos/orbos/pkg/helper"
"gopkg.in/yaml.v3"
"github.com/caos/orbos/pkg/labels"
"github.com/caos/orbos/pkg/secret"
"github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/database"
@@ -39,6 +43,7 @@ func AdaptFunc(
) (
operator.QueryFunc,
operator.DestroyFunc,
operator.ConfigureFunc,
map[string]*secret.Secret,
map[string]*secret.Existing,
bool,
@@ -49,7 +54,7 @@ func AdaptFunc(
desiredKind, err := parseDesiredV0(desired)
if err != nil {
return nil, nil, nil, nil, false, errors.Wrap(err, "parsing desired state failed")
return nil, nil, nil, nil, nil, false, errors.Wrap(err, "parsing desired state failed")
}
desired.Parsed = desiredKind
@@ -92,7 +97,7 @@ func AdaptFunc(
uiServiceName,
uint16(uiPort))
if err != nil {
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
getQueryC, destroyC, getConfigurationHashes, err := configuration.AdaptFunc(
@@ -111,7 +116,7 @@ func AdaptFunc(
services.GetClientIDFunc(namespace, httpServiceName, httpPort),
)
if err != nil {
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
queryDB, err := database.AdaptFunc(
@@ -119,7 +124,7 @@ func AdaptFunc(
dbClient,
)
if err != nil {
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
queryM, destroyM, err := migration.AdaptFunc(
@@ -134,7 +139,7 @@ func AdaptFunc(
tolerations,
)
if err != nil {
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
getQuerySetup, destroySetup, err := setup.AdaptFunc(
@@ -155,7 +160,7 @@ func AdaptFunc(
secretPasswordName,
)
if err != nil {
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
queryD, destroyD, err := deployment.AdaptFunc(
@@ -182,7 +187,7 @@ func AdaptFunc(
setup.GetDoneFunc(monitor, namespace, action),
)
if err != nil {
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
queryAmbassador, destroyAmbassador, err := ambassador.AdaptFunc(
@@ -195,7 +200,7 @@ func AdaptFunc(
desiredKind.Spec.Configuration.DNS,
)
if err != nil {
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
destroyers := make([]operator.DestroyFunc, 0)
@@ -217,33 +222,58 @@ func AdaptFunc(
}
}
concatQueriers := func(queriers ...operator.QueryFunc) operator.QueryFunc {
return func(k8sClient kubernetes.ClientInt, queried map[string]interface{}) (ensureFunc operator.EnsureFunc, err error) {
return operator.QueriersToEnsureFunc(
monitor,
true,
queriers,
k8sClient,
queried,
)
}
}
queryCfg := func(k8sClient kubernetes.ClientInt, queried map[string]interface{}) (ensureFunc operator.EnsureFunc, err error) {
users, err := getAllUsers(k8sClient, desiredKind)
if err != nil {
return nil, err
}
return concatQueriers(
queryDB,
getQueryC(users),
operator.EnsureFuncToQueryFunc(configuration.GetReadyFunc(
monitor,
namespace,
secretName,
secretVarsName,
secretPasswordName,
cmName,
consoleCMName,
)),
)(k8sClient, queried)
}
queryReadyD := operator.EnsureFuncToQueryFunc(deployment.GetReadyFunc(monitor, namespace, zitadelDeploymentName))
return func(k8sClient kubernetes.ClientInt, queried map[string]interface{}) (operator.EnsureFunc, error) {
users, err := getAllUsers(k8sClient, desiredKind)
if err != nil {
return nil, err
}
allZitadelUsers, err := getZitadelUserList(k8sClient, desiredKind)
if err != nil {
return nil, err
}
queryReadyM := operator.EnsureFuncToQueryFunc(migration.GetDoneFunc(monitor, namespace, action))
queryC := getQueryC(users)
queryReadyC := operator.EnsureFuncToQueryFunc(configuration.GetReadyFunc(monitor, namespace, secretName, secretVarsName, secretPasswordName, cmName, consoleCMName))
querySetup := getQuerySetup(allZitadelUsers, getConfigurationHashes)
queryReadySetup := operator.EnsureFuncToQueryFunc(setup.GetDoneFunc(monitor, namespace, action))
queryD := queryD(allZitadelUsers, getConfigurationHashes)
queryReadyD := operator.EnsureFuncToQueryFunc(deployment.GetReadyFunc(monitor, namespace, zitadelDeploymentName))
queriers := make([]operator.QueryFunc, 0)
for _, feature := range features {
switch feature {
case "migration":
queriers = append(queriers,
queryDB,
//configuration
queryC,
queryReadyC,
queryCfg,
//migration
queryM,
queryReadyM,
@@ -251,10 +281,8 @@ func AdaptFunc(
)
case "iam":
queriers = append(queriers,
queryDB,
//configuration
queryC,
queryReadyC,
queryCfg,
//migration
queryM,
queryReadyM,
@@ -267,8 +295,7 @@ func AdaptFunc(
queryD,
queryReadyD,
//handle change if necessary for clientID
queryC,
queryReadyC,
queryCfg,
//again apply deployment if config changed
queryD,
queryReadyD,
@@ -289,6 +316,78 @@ func AdaptFunc(
return operator.QueriersToEnsureFunc(internalMonitor, true, queriers, k8sClient, queried)
},
operator.DestroyersToDestroyFunc(monitor, destroyers),
func(k8sClient kubernetes.ClientInt, queried map[string]interface{}, gitops bool) error {
if desiredKind.Spec == nil {
desiredKind.Spec = &Spec{}
}
if desiredKind.Spec.Configuration == nil {
desiredKind.Spec.Configuration = &configuration.Configuration{}
}
if desiredKind.Spec.Configuration.Secrets == nil {
desiredKind.Spec.Configuration.Secrets = &configuration.Secrets{}
}
if desiredKind.Spec.Configuration.Secrets.CookieID == "" {
desiredKind.Spec.Configuration.Secrets.CookieID = "cookiekey_1"
}
if desiredKind.Spec.Configuration.Secrets.OTPVerificationID == "" {
desiredKind.Spec.Configuration.Secrets.OTPVerificationID = "otpverificationkey_1"
}
if desiredKind.Spec.Configuration.Secrets.DomainVerificationID == "" {
desiredKind.Spec.Configuration.Secrets.DomainVerificationID = "domainverificationkey_1"
}
if desiredKind.Spec.Configuration.Secrets.IDPConfigVerificationID == "" {
desiredKind.Spec.Configuration.Secrets.IDPConfigVerificationID = "idpconfigverificationkey_1"
}
if desiredKind.Spec.Configuration.Secrets.OIDCKeysID == "" {
desiredKind.Spec.Configuration.Secrets.OIDCKeysID = "oidckey_1"
}
if desiredKind.Spec.Configuration.Secrets.UserVerificationID == "" {
desiredKind.Spec.Configuration.Secrets.UserVerificationID = "userverificationkey_1"
}
if gitops && desiredKind.Spec.Configuration.Secrets.Keys == nil {
desiredKind.Spec.Configuration.Secrets.Keys = &secret.Secret{}
}
if !gitops && desiredKind.Spec.Configuration.Secrets.ExistingKeys == nil {
desiredKind.Spec.Configuration.Secrets.ExistingKeys = &secret.Existing{}
}
keys := make(map[string]string)
if gitops {
if err := yaml.Unmarshal([]byte(desiredKind.Spec.Configuration.Secrets.Keys.Value), keys); err != nil {
return err
}
} else {
return errors.New("configure is not yet implemented for CRD mode")
}
if _, ok := keys[desiredKind.Spec.Configuration.Secrets.CookieID]; !ok {
keys[desiredKind.Spec.Configuration.Secrets.CookieID] = helper.RandStringBytes(32)
}
if _, ok := keys[desiredKind.Spec.Configuration.Secrets.OTPVerificationID]; !ok {
keys[desiredKind.Spec.Configuration.Secrets.OTPVerificationID] = helper.RandStringBytes(32)
}
if _, ok := keys[desiredKind.Spec.Configuration.Secrets.DomainVerificationID]; !ok {
keys[desiredKind.Spec.Configuration.Secrets.DomainVerificationID] = helper.RandStringBytes(32)
}
if _, ok := keys[desiredKind.Spec.Configuration.Secrets.IDPConfigVerificationID]; !ok {
keys[desiredKind.Spec.Configuration.Secrets.IDPConfigVerificationID] = helper.RandStringBytes(32)
}
if _, ok := keys[desiredKind.Spec.Configuration.Secrets.OIDCKeysID]; !ok {
keys[desiredKind.Spec.Configuration.Secrets.OIDCKeysID] = helper.RandStringBytes(32)
}
if _, ok := keys[desiredKind.Spec.Configuration.Secrets.UserVerificationID]; !ok {
keys[desiredKind.Spec.Configuration.Secrets.UserVerificationID] = helper.RandStringBytes(32)
}
newKeys, err := yaml.Marshal(keys)
if err != nil {
return err
}
desiredKind.Spec.Configuration.Secrets.Keys.Value = string(newKeys)
return nil
},
allSecrets,
allExisting,
false,
@@ -5,7 +5,8 @@ import (
"strconv"
"strings"
"github.com/caos/orbos/pkg/helper"
"github.com/caos/orbos/pkg/secret/read"
"github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/database"
)
@@ -113,14 +114,14 @@ func literalsSecret(k8sClient kubernetes.ClientInt, desired *Configuration, goog
literalsSecret := map[string]string{}
if desired != nil {
if desired.Tracing != nil && (desired.Tracing.ServiceAccountJSON != nil || desired.Tracing.ExistingServiceAccountJSON != nil) {
value, err := helper.GetSecretValue(k8sClient, desired.Tracing.ServiceAccountJSON, desired.Tracing.ExistingServiceAccountJSON)
value, err := read.GetSecretValue(k8sClient, desired.Tracing.ServiceAccountJSON, desired.Tracing.ExistingServiceAccountJSON)
if err != nil {
return nil, err
}
literalsSecret[googleServiceAccountJSONPath] = value
}
if desired.Secrets != nil && (desired.Secrets.Keys != nil || desired.Secrets.ExistingKeys != nil) {
value, err := helper.GetSecretValue(k8sClient, desired.Secrets.Keys, desired.Secrets.ExistingKeys)
value, err := read.GetSecretValue(k8sClient, desired.Secrets.Keys, desired.Secrets.ExistingKeys)
if err != nil {
return nil, err
}
@@ -135,28 +136,28 @@ func literalsSecretVars(k8sClient kubernetes.ClientInt, desired *Configuration)
if desired != nil {
if desired.Notifications != nil {
if desired.Notifications.Email.AppKey != nil || desired.Notifications.Email.ExistingAppKey != nil {
value, err := helper.GetSecretValue(k8sClient, desired.Notifications.Email.AppKey, desired.Notifications.Email.ExistingAppKey)
value, err := read.GetSecretValue(k8sClient, desired.Notifications.Email.AppKey, desired.Notifications.Email.ExistingAppKey)
if err != nil {
return nil, err
}
literalsSecretVars["ZITADEL_EMAILAPPKEY"] = value
}
if desired.Notifications.GoogleChatURL != nil || desired.Notifications.ExistingGoogleChatURL != nil {
value, err := helper.GetSecretValue(k8sClient, desired.Notifications.GoogleChatURL, desired.Notifications.ExistingGoogleChatURL)
value, err := read.GetSecretValue(k8sClient, desired.Notifications.GoogleChatURL, desired.Notifications.ExistingGoogleChatURL)
if err != nil {
return nil, err
}
literalsSecretVars["ZITADEL_GOOGLE_CHAT_URL"] = value
}
if desired.Notifications.Twilio.AuthToken != nil || desired.Notifications.Twilio.ExistingAuthToken != nil {
value, err := helper.GetSecretValue(k8sClient, desired.Notifications.Twilio.AuthToken, desired.Notifications.Twilio.ExistingAuthToken)
value, err := read.GetSecretValue(k8sClient, desired.Notifications.Twilio.AuthToken, desired.Notifications.Twilio.ExistingAuthToken)
if err != nil {
return nil, err
}
literalsSecretVars["ZITADEL_TWILIO_AUTH_TOKEN"] = value
}
if desired.Notifications.Twilio.SID != nil || desired.Notifications.Twilio.ExistingSID != nil {
value, err := helper.GetSecretValue(k8sClient, desired.Notifications.Twilio.SID, desired.Notifications.Twilio.ExistingSID)
value, err := read.GetSecretValue(k8sClient, desired.Notifications.Twilio.SID, desired.Notifications.Twilio.ExistingSID)
if err != nil {
return nil, err
}
+3 -2
View File
@@ -3,7 +3,8 @@ package zitadel
import (
"sort"
"github.com/caos/orbos/pkg/helper"
"github.com/caos/orbos/pkg/secret/read"
"github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/orbos/pkg/secret"
@@ -81,7 +82,7 @@ func fillInUserPassword(
return nil
}
pw, err := helper.GetSecretValue(k8sClient, secret, existing)
pw, err := read.GetSecretValue(k8sClient, secret, existing)
if err != nil {
return err
}
+9 -5
View File
@@ -31,6 +31,7 @@ func AdaptFunc(
) (
queryFunc operator.QueryFunc,
destroyFunc operator.DestroyFunc,
configureFunc operator.ConfigureFunc,
allSecrets map[string]*secret.Secret,
allExisting map[string]*secret.Existing,
migrate bool,
@@ -47,7 +48,7 @@ func AdaptFunc(
desiredKind, err := ParseDesiredV0(desiredTree)
if err != nil {
return nil, nil, nil, nil, false, errors.Wrap(err, "parsing desired state failed")
return nil, nil, nil, nil, nil, false, errors.Wrap(err, "parsing desired state failed")
}
desiredTree.Parsed = desiredKind
currentTree = &tree.Tree{}
@@ -61,7 +62,7 @@ func AdaptFunc(
dbClientT, err := zitadeldb.NewGitOpsClient(monitor, orbconfig.URL, orbconfig.Repokey)
if err != nil {
monitor.Error(err)
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
dbClient = dbClientT
} else {
@@ -72,7 +73,7 @@ func AdaptFunc(
queryNS, err := namespace.AdaptFuncToEnsure(namespaceName)
if err != nil {
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
/*destroyNS, err := namespace.AdaptFuncToDestroy(namespaceName)
if err != nil {
@@ -80,7 +81,7 @@ func AdaptFunc(
}*/
iamCurrent := &tree.Tree{}
queryIAM, destroyIAM, zitadelSecrets, zitadelExisting, migrateIAM, err := iam.GetQueryAndDestroyFuncs(
queryIAM, destroyIAM, configureIAM, zitadelSecrets, zitadelExisting, migrateIAM, err := iam.Adapt(
orbMonitor,
operatorLabels,
desiredKind.IAM,
@@ -94,7 +95,7 @@ func AdaptFunc(
features,
)
if err != nil {
return nil, nil, nil, nil, false, err
return nil, nil, nil, nil, nil, false, err
}
migrate = migrate || migrateIAM
secret.AppendSecrets("", allSecrets, zitadelSecrets, allExisting, zitadelExisting)
@@ -134,6 +135,9 @@ func AdaptFunc(
monitor.WithField("destroyers", len(queriers)).Info("Destroy")
return operator.DestroyersToDestroyFunc(monitor, destroyers)(k8sClient)
},
func(k8sClient kubernetes.ClientInt, queried map[string]interface{}, gitops bool) error {
return configureIAM(k8sClient, queried, gitops)
},
allSecrets,
allExisting,
migrate,
+1 -8
View File
@@ -1,8 +1,6 @@
package zitadel
import (
"errors"
"github.com/caos/zitadel/operator"
"github.com/caos/orbos/mntr"
@@ -27,12 +25,7 @@ func Takeoff(
}
treeCurrent := &tree.Tree{}
if !k8sClient.Available() {
internalMonitor.Error(errors.New("kubeclient is not available"))
return err
}
query, _, _, _, _, err := adapt(internalMonitor, treeDesired, treeCurrent)
query, _, _, _, _, _, err := adapt(internalMonitor, treeDesired, treeCurrent)
if err != nil {
internalMonitor.Error(err)
return err