mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-08 07:05:12 +00:00
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:
co-authored by
Florian Forster
fabi
Livio Amstutz
Stefan Benz
parent
06281b5ccb
commit
c0878e4509
+15
-1
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 +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
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,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
|
||||
}
|
||||
|
||||
@@ -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 +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
|
||||
|
||||
Reference in New Issue
Block a user