feat: comprehensive sentry instrumentation (#2023)

* feat: comprehensive sentry instrumentation

* test: pass

* fix: only fetch zitadel dsn in zitadel-operator

* chore: use dns for sentry environment as soon as parsed

* fix: trust ca certs

* ci: update orbos

* docs: add usage data explanation

* fix: dont send validation errors

* docs: improve ingestion data explanation

* style: rename flag --disable-ingestion to --disable-analytics

* fix: pass --disable-analytics flag to self deployments

* fix: destroy command for sentry

* fix: update orbos

* fix: only switch environment if analytics is enabled

* fix: ensure SENTRY_DSN is always set

* test: test empty sentry dsn

* ci: invalidate build caches

* chore: use zitadel-dev if no version is passed

* chore: combine dev releases in sentry

* refactor: only check for semrel if sentry is enabled
This commit is contained in:
Elio Bischof
2021-07-30 11:52:08 +02:00
committed by GitHub
parent e1a3cc732d
commit fbe0f311f2
67 changed files with 490 additions and 470 deletions

View File

@@ -75,6 +75,8 @@ jobs:
# cache-from: type=gha,scope=${{ github.workflow }} (https://github.com/caos/zitadel/issues/2102) # cache-from: type=gha,scope=${{ github.workflow }} (https://github.com/caos/zitadel/issues/2102)
cache-to: type=gha,scope=${{ github.workflow }},mode=max cache-to: type=gha,scope=${{ github.workflow }},mode=max
outputs: type=local,dest=/tmp/zitadel outputs: type=local,dest=/tmp/zitadel
build-args: |
VERSION=${{ needs.refs.outputs.version }}
- uses: actions/upload-artifact@v2 - uses: actions/upload-artifact@v2
with: with:
name: zitadel name: zitadel
@@ -424,4 +426,5 @@ jobs:
SENTRY_ORG: ${{ secrets.SENTRY_ORG }} SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }} SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}
with: with:
version: ${{ steps.semantic.outputs.new_release_version }} version: zitadel-${{ needs.refs.outputs.version }}
projects: "console database-operator zitadel zitadel-operator zitadelctl"

View File

@@ -111,6 +111,15 @@ See the policy [here](./SECURITY.md)
* [**OIDC for GO**](https://github.com/caos/oidc) - OpenID Connect SDK (client and server) for Go * [**OIDC for GO**](https://github.com/caos/oidc) - OpenID Connect SDK (client and server) for Go
* [**ZITADEL Tools**](https://github.com/caos/zitadel-tools) - Go tool to convert key file to privately signed JWT * [**ZITADEL Tools**](https://github.com/caos/zitadel-tools) - Go tool to convert key file to privately signed JWT
## Usage Data
ZITADEL components send errors and usage data to CAOS Ltd., so that we are able to identify code improvement potential. If you don't want to send this data or don't have an internet connection, pass the global flag `--disable-analytics` when using zitadelctl. For disabling ingestion for already-running components, execute the takeoff command again with the `--disable-analytics` flag.
We try to distinguishing the environments from which events come from. As environment identifier, we enrich the events by the domain you have configured in zitadel.yml, as soon as it's available. When it's not available and you passed the --gitops flag, we defer the environment identifier from your git repository URL.
Besides from errors that don't clearly come from misconfiguration or cli misuage, we send an inital event when any binary is started. This is a "<component> invoked" event along with the flags that are passed to it, except secret values of course.
We only ingest operational data. Your ZITADEL workload data from the IAM application itself is never sent anywhere unless you chose to integrate other systems yourself.
## License ## License
See the exact licensing terms [here](./LICENSE) See the exact licensing terms [here](./LICENSE)

View File

@@ -49,11 +49,15 @@ RUN adduser -D zitadel
ARG ARCH=amd64 ARG ARCH=amd64
ARG OS=linux ARG OS=linux
RUN apk add -U --no-cache ca-certificates
COPY --from=prod-go-build /go/src/github.com/caos/zitadel/zitadelctl /app/zitadelctl COPY --from=prod-go-build /go/src/github.com/caos/zitadel/zitadelctl /app/zitadelctl
RUN chmod a+x /app/zitadelctl RUN chmod a+x /app/zitadelctl
## Scratch Image ## Scratch Image
FROM scratch as final FROM scratch as final
COPY --from=artifact /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=artifact /etc/passwd /etc/passwd COPY --from=artifact /etc/passwd /etc/passwd
COPY --from=artifact /app / COPY --from=artifact /app /
USER zitadel USER zitadel

View File

@@ -142,8 +142,9 @@ COPY --from=go-test /go/src/github.com/caos/zitadel/profile.cov profile.cov
####################### #######################
FROM go-test as prod-go-build FROM go-test as prod-go-build
ARG BUILDARCH ARG BUILDARCH
ARG VERSION=""
RUN CGO_ENABLED=0 GOOS=linux GOARCH=${BUILDARCH} go build -a -installsuffix cgo -ldflags '-extldflags "-static"' -o zitadel-linux-${BUILDARCH} cmd/zitadel/main.go RUN CGO_ENABLED=0 GOOS=linux GOARCH=${BUILDARCH} go build -a -installsuffix cgo -ldflags "-X main.version=${VERSION:-'dev'} -extldflags \"-static\"" -o zitadel-linux-${BUILDARCH} cmd/zitadel/main.go
####################### #######################
## Go dev build ## Go dev build

View File

@@ -3,7 +3,9 @@ package main
import ( import (
"context" "context"
"flag" "flag"
"fmt"
"os" "os"
"regexp"
"strconv" "strconv"
"time" "time"
@@ -41,6 +43,9 @@ import (
"github.com/caos/zitadel/openapi" "github.com/caos/zitadel/openapi"
) )
// build argument
var version = "dev"
type Config struct { type Config struct {
Log logging.Config Log logging.Config
Tracing tracing.TracingConfig Tracing tracing.TracingConfig
@@ -94,8 +99,16 @@ const (
func main() { func main() {
enableSentry, _ := strconv.ParseBool(os.Getenv("SENTRY_USAGE")) enableSentry, _ := strconv.ParseBool(os.Getenv("SENTRY_USAGE"))
if enableSentry { if enableSentry {
err := sentry.Init(sentry.ClientOptions{}) sentryVersion := version
if !regexp.MustCompile("^v?[0-9]+.[0-9]+.[0-9]$").Match([]byte(version)) {
sentryVersion = "dev"
}
err := sentry.Init(sentry.ClientOptions{
Environment: os.Getenv("SENTRY_ENVIRONMENT"),
Release: fmt.Sprintf("zitadel-%s", sentryVersion),
})
if err != nil { if err != nil {
logging.Log("MAIN-Gnzjw").WithError(err).Fatal("sentry init failed") logging.Log("MAIN-Gnzjw").WithError(err).Fatal("sentry init failed")
} }

View File

@@ -21,10 +21,7 @@ func BackupCommand(getRv GetRootValues) *cobra.Command {
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) {
rv, err := getRv() rv := getRv("backup", map[string]interface{}{"backup": backup}, "")
if err != nil {
return err
}
defer func() { defer func() {
err = rv.ErrFunc(err) err = rv.ErrFunc(err)
}() }()

View File

@@ -4,10 +4,11 @@ import (
"fmt" "fmt"
"sort" "sort"
"github.com/spf13/cobra"
"github.com/caos/orbos/pkg/kubernetes/cli" "github.com/caos/orbos/pkg/kubernetes/cli"
"github.com/caos/zitadel/pkg/databases" "github.com/caos/zitadel/pkg/databases"
"github.com/spf13/cobra"
) )
func BackupListCommand(getRv GetRootValues) *cobra.Command { func BackupListCommand(getRv GetRootValues) *cobra.Command {
@@ -19,11 +20,8 @@ func BackupListCommand(getRv GetRootValues) *cobra.Command {
} }
) )
cmd.RunE = func(cmd *cobra.Command, args []string) error { cmd.RunE = func(cmd *cobra.Command, args []string) (err error) {
rv, err := getRv() rv := getRv("backuplist", nil, "")
if err != nil {
return err
}
defer func() { defer func() {
err = rv.ErrFunc(err) err = rv.ErrFunc(err)
}() }()
@@ -41,15 +39,13 @@ func BackupListCommand(getRv GetRootValues) *cobra.Command {
if rv.Gitops { if rv.Gitops {
backupsT, err := databases.GitOpsListBackups(monitor, gitClient, k8sClient) backupsT, err := databases.GitOpsListBackups(monitor, gitClient, k8sClient)
if err != nil { if err != nil {
monitor.Error(err) return err
return nil
} }
backups = backupsT backups = backupsT
} else { } else {
backupsT, err := databases.CrdListBackups(monitor, k8sClient) backupsT, err := databases.CrdListBackups(monitor, k8sClient)
if err != nil { if err != nil {
monitor.Error(err) return err
return nil
} }
backups = backupsT backups = backupsT
} }

View File

@@ -3,6 +3,8 @@ package cmds
import ( import (
"errors" "errors"
"github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/caos/orbos/pkg/cfg" "github.com/caos/orbos/pkg/cfg"
@@ -35,13 +37,13 @@ func ConfigCommand(getRv GetRootValues, ghClientID, ghClientSecret string) *cobr
cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { cmd.RunE = func(cmd *cobra.Command, args []string) (err error) {
rv, _ := getRv() rv := getRv("configure", map[string]interface{}{"masterkey": newMasterKey != "", "newRepoURL": newRepoURL}, "")
defer func() { defer func() {
err = rv.ErrFunc(err) err = rv.ErrFunc(err)
}() }()
if !rv.Gitops { if !rv.Gitops {
return errors.New("configure command is only supported with the --gitops flag") return mntr.ToUserError(errors.New("configure command is only supported with the --gitops flag"))
} }
if err := orb.Reconfigure(rv.Ctx, rv.Monitor, rv.OrbConfig, newRepoURL, newMasterKey, rv.GitClient, ghClientID, ghClientSecret); err != nil { if err := orb.Reconfigure(rv.Ctx, rv.Monitor, rv.OrbConfig, newRepoURL, newMasterKey, rv.GitClient, ghClientID, ghClientSecret); err != nil {

View File

@@ -46,10 +46,7 @@ func TeardownCommand(getRv GetRootValues) *cobra.Command {
cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { cmd.RunE = func(cmd *cobra.Command, args []string) (err error) {
rv, err := getRv() rv := getRv("destroy", nil, "")
if err != nil {
return err
}
defer func() { defer func() {
err = rv.ErrFunc(err) err = rv.ErrFunc(err)
}() }()

View File

@@ -18,11 +18,14 @@ func ReadSecretCommand(getRv GetRootValues) *cobra.Command {
Long: "Print a secrets decrypted value to stdout.\nIf no path is provided, a secret can interactively be chosen from a list of all possible secrets", Long: "Print a secrets decrypted value to stdout.\nIf no path is provided, a secret can interactively be chosen from a list of all possible secrets",
Args: cobra.MaximumNArgs(1), Args: cobra.MaximumNArgs(1),
Example: `zitadelctl readsecret database.bucket.serviceaccountjson.encrypted > ~/googlecloudstoragesa.json`, Example: `zitadelctl readsecret database.bucket.serviceaccountjson.encrypted > ~/googlecloudstoragesa.json`,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) (err error) {
rv, err := getRv()
if err != nil { path := ""
return err if len(args) > 0 {
path = args[0]
} }
rv := getRv("readsecret", map[string]interface{}{"path": path}, "")
defer func() { defer func() {
err = rv.ErrFunc(err) err = rv.ErrFunc(err)
}() }()
@@ -31,11 +34,6 @@ func ReadSecretCommand(getRv GetRootValues) *cobra.Command {
orbConfig := rv.OrbConfig orbConfig := rv.OrbConfig
gitClient := rv.GitClient gitClient := rv.GitClient
path := ""
if len(args) > 0 {
path = args[0]
}
k8sClient, err := cli.Client(monitor, orbConfig, gitClient, rv.Kubeconfig, rv.Gitops, true) k8sClient, err := cli.Client(monitor, orbConfig, gitClient, rv.Kubeconfig, rv.Gitops, true)
if err != nil && !rv.Gitops { if err != nil && !rv.Gitops {
return err return err
@@ -47,13 +45,11 @@ func ReadSecretCommand(getRv GetRootValues) *cobra.Command {
secrets.GetAllSecretsFunc(monitor, path == "", rv.Gitops, gitClient, k8sClient, orbConfig), secrets.GetAllSecretsFunc(monitor, path == "", rv.Gitops, gitClient, k8sClient, orbConfig),
) )
if err != nil { if err != nil {
monitor.Error(err) return err
return nil
} }
if _, err := os.Stdout.Write([]byte(value)); err != nil { if _, err := os.Stdout.Write([]byte(value)); err != nil {
monitor.Error(err) return err
return nil
} }
return nil return nil
}, },

View File

@@ -2,8 +2,11 @@ package cmds
import ( import (
"errors" "errors"
"github.com/caos/zitadel/pkg/zitadel" "github.com/caos/zitadel/pkg/zitadel"
"github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes/cli" "github.com/caos/orbos/pkg/kubernetes/cli"
"github.com/caos/zitadel/pkg/databases" "github.com/caos/zitadel/pkg/databases"
@@ -24,11 +27,8 @@ 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")
cmd.RunE = func(cmd *cobra.Command, args []string) error { cmd.RunE = func(cmd *cobra.Command, args []string) (err error) {
rv, err := getRv() rv := getRv("restore", map[string]interface{}{"backup": backup}, "")
if err != nil {
return err
}
defer func() { defer func() {
err = rv.ErrFunc(err) err = rv.ErrFunc(err)
}() }()
@@ -48,15 +48,13 @@ func RestoreCommand(getRv GetRootValues) *cobra.Command {
if rv.Gitops { if rv.Gitops {
listT, err := databases.GitOpsListBackups(monitor, gitClient, k8sClient) listT, err := databases.GitOpsListBackups(monitor, gitClient, k8sClient)
if err != nil { if err != nil {
monitor.Error(err) return err
return nil
} }
list = listT list = listT
} else { } else {
listT, err := databases.CrdListBackups(monitor, k8sClient) listT, err := databases.CrdListBackups(monitor, k8sClient)
if err != nil { if err != nil {
monitor.Error(err) return err
return nil
} }
list = listT list = listT
} }
@@ -69,8 +67,7 @@ func RestoreCommand(getRv GetRootValues) *cobra.Command {
_, result, err := prompt.Run() _, result, err := prompt.Run()
if err != nil { if err != nil {
monitor.Error(err) return err
return nil
} }
backup = result backup = result
} }
@@ -82,18 +79,15 @@ func RestoreCommand(getRv GetRootValues) *cobra.Command {
} }
if !existing { if !existing {
monitor.Error(errors.New("chosen backup is not existing")) return mntr.ToUserError(errors.New("chosen backup is not existing"))
return nil
} }
if rv.Gitops { if rv.Gitops {
if err := zitadel.GitOpsClearMigrateRestore(monitor, gitClient, orbConfig, k8sClient, backup, &version); err != nil { if err := zitadel.GitOpsClearMigrateRestore(monitor, gitClient, orbConfig, k8sClient, backup, &version); err != nil {
monitor.Error(err)
return err return err
} }
} else { } else {
if err := zitadel.CrdClearMigrateRestore(monitor, k8sClient, backup, &version); err != nil { if err := zitadel.CrdClearMigrateRestore(monitor, k8sClient, backup, &version); err != nil {
monitor.Error(err)
return err return err
} }

View File

@@ -22,19 +22,14 @@ type RootValues struct {
ErrFunc errFunc ErrFunc errFunc
} }
type GetRootValues func() (*RootValues, error) type GetRootValues func(command string, tags map[string]interface{}, component string, moreComponents ...string) *RootValues
type errFunc func(err error) error type errFunc func(err error) error
func RootCommand(version string) (*cobra.Command, GetRootValues) { func RootCommand(version string, monitor mntr.Monitor) (*cobra.Command, GetRootValues) {
var ( var (
ctx = context.Background() ctx = context.Background()
monitor = mntr.Monitor{
OnInfo: mntr.LogMessage,
OnChange: mntr.LogMessage,
OnError: mntr.LogError,
}
rv = &RootValues{ rv = &RootValues{
Ctx: ctx, Ctx: ctx,
Version: version, Version: version,
@@ -48,6 +43,7 @@ func RootCommand(version string) (*cobra.Command, GetRootValues) {
} }
orbConfigPath string orbConfigPath string
verbose bool verbose bool
disableAnalytics bool
) )
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "zitadelctl [flags]", Use: "zitadelctl [flags]",
@@ -77,8 +73,9 @@ $ zitadelctl --gitops -f ~/.orb/myorb [command]
flags.StringVarP(&orbConfigPath, "orbconfig", "f", "~/.orb/config", "Path to the file containing the orbs git repo URL, deploy key and the master key for encrypting and decrypting secrets") flags.StringVarP(&orbConfigPath, "orbconfig", "f", "~/.orb/config", "Path to the file containing the orbs git repo URL, deploy key and the master key for encrypting and decrypting secrets")
flags.StringVarP(&rv.Kubeconfig, "kubeconfig", "k", "~/.kube/config", "Path to the kubeconfig file to the cluster zitadelctl should target") flags.StringVarP(&rv.Kubeconfig, "kubeconfig", "k", "~/.kube/config", "Path to the kubeconfig file to the cluster zitadelctl should target")
flags.BoolVar(&verbose, "verbose", false, "Print debug levelled logs") flags.BoolVar(&verbose, "verbose", false, "Print debug levelled logs")
flags.BoolVar(&disableAnalytics, "disable-analytics", false, "Don't help CAOS AG to improve ZITADEL by sending them errors and usage data")
return cmd, func() (*RootValues, error) { return cmd, func(command string, tags map[string]interface{}, component string, moreComponents ...string) *RootValues {
if verbose { if verbose {
monitor = monitor.Verbose() monitor = monitor.Verbose()
@@ -88,15 +85,31 @@ $ zitadelctl --gitops -f ~/.orb/myorb [command]
rv.Kubeconfig = helpers.PruneHome(rv.Kubeconfig) rv.Kubeconfig = helpers.PruneHome(rv.Kubeconfig)
rv.GitClient = git.New(ctx, monitor, "zitadel", "orbos@caos.ch") rv.GitClient = git.New(ctx, monitor, "zitadel", "orbos@caos.ch")
var err error
if rv.Gitops { if rv.Gitops {
prunedPath := helpers.PruneHome(orbConfigPath) prunedPath := helpers.PruneHome(orbConfigPath)
rv.OrbConfig, err = orb.ParseOrbConfig(prunedPath) rv.OrbConfig, _ = orb.ParseOrbConfig(prunedPath)
if rv.OrbConfig == nil { if rv.OrbConfig == nil {
rv.OrbConfig = &orb.Orb{Path: prunedPath} rv.OrbConfig = &orb.Orb{Path: prunedPath}
} }
} }
return rv, err env := "unknown"
if orbID, err := rv.OrbConfig.ID(); err == nil {
env = orbID
}
if component == "" {
component = "zitadelctl"
}
if !disableAnalytics {
if err := mntr.Ingest(rv.Monitor, "zitadel", version, env, component, moreComponents...); err != nil {
panic(err)
}
}
rv.Monitor.WithFields(map[string]interface{}{"command": command, "gitops": rv.Gitops}).WithFields(tags).CaptureMessage("zitadelctl invoked")
return rv
} }
} }

View File

@@ -19,11 +19,8 @@ func StartOperator(getRv GetRootValues) *cobra.Command {
flags := cmd.Flags() flags := cmd.Flags()
flags.StringVar(&metricsAddr, "metrics-addr", "", "The address the metric endpoint binds to.") flags.StringVar(&metricsAddr, "metrics-addr", "", "The address the metric endpoint binds to.")
cmd.RunE = func(cmd *cobra.Command, args []string) error { cmd.RunE = func(cmd *cobra.Command, args []string) (err error) {
rv, err := getRv() rv := getRv("operator", nil, "zitadel-operator", "zitadel")
if err != nil {
return err
}
defer func() { defer func() {
err = rv.ErrFunc(err) err = rv.ErrFunc(err)
}() }()
@@ -63,10 +60,7 @@ func StartDatabase(getRv GetRootValues) *cobra.Command {
flags.StringVar(&metricsAddr, "metrics-addr", "", "The address the metric endpoint binds to.") flags.StringVar(&metricsAddr, "metrics-addr", "", "The address the metric endpoint binds to.")
cmd.RunE = func(cmd *cobra.Command, args []string) (err error) { cmd.RunE = func(cmd *cobra.Command, args []string) (err error) {
rv, err := getRv() rv := getRv("database", nil, "database-operator")
if err != nil {
return err
}
defer func() { defer func() {
err = rv.ErrFunc(err) err = rv.ErrFunc(err)
}() }()

View File

@@ -23,11 +23,8 @@ func TakeoffCommand(getRv GetRootValues) *cobra.Command {
} }
) )
cmd.RunE = func(cmd *cobra.Command, args []string) error { cmd.RunE = func(cmd *cobra.Command, args []string) (err error) {
rv, err := getRv() rv := getRv("takeoff", nil, "")
if err != nil {
return err
}
defer func() { defer func() {
err = rv.ErrFunc(err) err = rv.ErrFunc(err)
}() }()
@@ -49,7 +46,6 @@ func TakeoffCommand(getRv GetRootValues) *cobra.Command {
} }
if err := kubernetes.EnsureCaosSystemNamespace(monitor, k8sClient); err != nil { if err := kubernetes.EnsureCaosSystemNamespace(monitor, k8sClient); err != nil {
monitor.Info("failed to apply common resources into k8s-cluster")
return err return err
} }
@@ -61,7 +57,6 @@ func TakeoffCommand(getRv GetRootValues) *cobra.Command {
} }
if err := kubernetes.EnsureOrbconfigSecret(monitor, k8sClient, orbConfigBytes); err != nil { if err := kubernetes.EnsureOrbconfigSecret(monitor, k8sClient, orbConfigBytes); err != nil {
monitor.Info("failed to apply configuration resources into k8s-cluster")
return err return err
} }
} }
@@ -73,26 +68,37 @@ func TakeoffCommand(getRv GetRootValues) *cobra.Command {
rv.Version, rv.Version,
rv.Gitops, rv.Gitops,
); err != nil { ); err != nil {
monitor.Error(err) return err
} }
if err := deployDatabase( return deployDatabase(
monitor, monitor,
gitClient, gitClient,
k8sClient, k8sClient,
rv.Version, rv.Version,
rv.Gitops, rv.Gitops,
); err != nil { )
monitor.Error(err)
}
return nil
} }
return cmd return cmd
} }
func deployOperator(monitor mntr.Monitor, gitClient *git.Client, k8sClient kubernetes.ClientInt, version string, gitops bool) error { func deployOperator(monitor mntr.Monitor, gitClient *git.Client, k8sClient kubernetes.ClientInt, version string, gitops bool) error {
if gitops { if !gitops {
if gitClient.Exists(git.ZitadelFile) {
// at takeoff the artifacts have to be applied
spec := &orbzit.Spec{
Version: version,
SelfReconciling: true,
}
rec, _ := orbzit.Reconcile(monitor, spec, gitops)
return rec(k8sClient)
}
if !gitClient.Exists(git.ZitadelFile) {
monitor.WithField("file", git.ZitadelFile).Info("File not found in git, skipping deployment")
return nil
}
desiredTree, err := gitClient.ReadTree(git.ZitadelFile) desiredTree, err := gitClient.ReadTree(git.ZitadelFile)
if err != nil { if err != nil {
@@ -107,29 +113,26 @@ func deployOperator(monitor mntr.Monitor, gitClient *git.Client, k8sClient kuber
// at takeoff the artifacts have to be applied // at takeoff the artifacts have to be applied
spec.SelfReconciling = true spec.SelfReconciling = true
rec, _ := orbzit.Reconcile(monitor, spec, gitops) rec, _ := orbzit.Reconcile(monitor, spec, gitops)
if err := rec(k8sClient); err != nil { return rec(k8sClient)
return err
} }
}
} else { func deployDatabase(monitor mntr.Monitor, gitClient *git.Client, k8sClient kubernetes.ClientInt, version string, gitops bool) error {
if !gitops {
// at takeoff the artifacts have to be applied // at takeoff the artifacts have to be applied
spec := &orbzit.Spec{ spec := &orbdb.Spec{
Version: version, Version: version,
SelfReconciling: true, SelfReconciling: true,
} }
rec, _ := orbzit.Reconcile(monitor, spec, gitops) rec, _ := orbdb.Reconcile(monitor, spec, gitops)
if err := rec(k8sClient); err != nil { return rec(k8sClient)
return err
}
} }
if !gitClient.Exists(git.DatabaseFile) {
monitor.WithField("file", git.DatabaseFile).Info("File not found in git, skipping deployment")
return nil return nil
} }
func deployDatabase(monitor mntr.Monitor, gitClient *git.Client, k8sClient kubernetes.ClientInt, version string, gitops bool) error {
if gitops {
if gitClient.Exists(git.DatabaseFile) {
desiredTree, err := gitClient.ReadTree(git.DatabaseFile) desiredTree, err := gitClient.ReadTree(git.DatabaseFile)
if err != nil { if err != nil {
return err return err
@@ -142,22 +145,6 @@ func deployDatabase(monitor mntr.Monitor, gitClient *git.Client, k8sClient kuber
// at takeoff the artifacts have to be applied // at takeoff the artifacts have to be applied
spec.SelfReconciling = true spec.SelfReconciling = true
rec, _ := orbdb.Reconcile(monitor, desired.Spec, gitops)
if err := rec(k8sClient); err != nil {
return err
}
}
} else {
// at takeoff the artifacts have to be applied
spec := &orbdb.Spec{
Version: version,
SelfReconciling: true,
}
rec, _ := orbdb.Reconcile(monitor, spec, gitops) rec, _ := orbdb.Reconcile(monitor, spec, gitops)
if err := rec(k8sClient); err != nil { return rec(k8sClient)
return err
}
}
return nil
} }

View File

@@ -35,11 +35,14 @@ cat ~/googlecloudstoragesa.json | zitadelctl writesecret database.bucket.service
flags.StringVarP(&file, "file", "s", "", "File containing the value to encrypt") flags.StringVarP(&file, "file", "s", "", "File containing the value to encrypt")
flags.BoolVar(&stdin, "stdin", false, "Value to encrypt is read from standard input") flags.BoolVar(&stdin, "stdin", false, "Value to encrypt is read from standard input")
cmd.RunE = func(cmd *cobra.Command, args []string) error { cmd.RunE = func(cmd *cobra.Command, args []string) (err error) {
rv, err := getRv()
if err != nil { path := ""
return err if len(args) > 0 {
path = args[0]
} }
rv := getRv("writesecret", map[string]interface{}{"path": path, "value": value != "", "file": file, "stdin": stdin}, "")
defer func() { defer func() {
err = rv.ErrFunc(err) err = rv.ErrFunc(err)
}() }()
@@ -50,13 +53,7 @@ cat ~/googlecloudstoragesa.json | zitadelctl writesecret database.bucket.service
s, err := key(value, file, stdin) s, err := key(value, file, stdin)
if err != nil { if err != nil {
monitor.Error(err) return err
return nil
}
path := ""
if len(args) > 0 {
path = args[0]
} }
k8sClient, err := cli.Client(monitor, orbConfig, gitClient, rv.Kubeconfig, rv.Gitops, true) k8sClient, err := cli.Client(monitor, orbConfig, gitClient, rv.Kubeconfig, rv.Gitops, true)
@@ -64,7 +61,7 @@ cat ~/googlecloudstoragesa.json | zitadelctl writesecret database.bucket.service
return err return err
} }
if err := secret.Write( return secret.Write(
monitor, monitor,
k8sClient, k8sClient,
path, path,
@@ -73,10 +70,7 @@ cat ~/googlecloudstoragesa.json | zitadelctl writesecret database.bucket.service
fmt.Sprintf(rv.Version), fmt.Sprintf(rv.Version),
secrets.GetAllSecretsFunc(monitor, path != "", rv.Gitops, gitClient, k8sClient, orbConfig), secrets.GetAllSecretsFunc(monitor, path != "", rv.Gitops, gitClient, k8sClient, orbConfig),
secrets.PushFunc(monitor, rv.Gitops, gitClient, k8sClient), secrets.PushFunc(monitor, rv.Gitops, gitClient, k8sClient),
); err != nil { )
monitor.Error(err)
}
return nil
} }
return cmd return cmd
} }

View File

@@ -4,6 +4,8 @@ import (
"fmt" "fmt"
"os" "os"
"github.com/caos/orbos/mntr"
"github.com/caos/zitadel/cmd/zitadelctl/cmds" "github.com/caos/zitadel/cmd/zitadelctl/cmds"
) )
@@ -14,7 +16,16 @@ var (
) )
func main() { func main() {
rootCmd, rootValues := cmds.RootCommand(Version) monitor := mntr.Monitor{
OnInfo: mntr.LogMessage,
OnChange: mntr.LogMessage,
OnError: mntr.LogError,
OnRecoverPanic: mntr.LogPanic,
}
defer func() { monitor.RecoverPanic(recover()) }()
rootCmd, rootValues := cmds.RootCommand(Version, monitor)
rootCmd.Version = fmt.Sprintf("%s\n", Version) rootCmd.Version = fmt.Sprintf("%s\n", Version)
rootCmd.AddCommand( rootCmd.AddCommand(

7
go.mod
View File

@@ -17,8 +17,9 @@ require (
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc
github.com/caos/logging v0.0.2 github.com/caos/logging v0.0.2
github.com/caos/oidc v0.15.7 github.com/caos/oidc v0.15.7
github.com/caos/orbos v1.5.14-0.20210428081839-983ffc569980 github.com/caos/orbos v1.5.14-0.20210727080455-c90c315021f5
github.com/cockroachdb/cockroach-go/v2 v2.1.0 github.com/cockroachdb/cockroach-go/v2 v2.1.0
github.com/docker/go-metrics v0.0.1 // indirect
github.com/duo-labs/webauthn v0.0.0-20200714211715-1daaee874e43 github.com/duo-labs/webauthn v0.0.0-20200714211715-1daaee874e43
github.com/envoyproxy/protoc-gen-validate v0.6.1 github.com/envoyproxy/protoc-gen-validate v0.6.1
github.com/getsentry/sentry-go v0.11.0 github.com/getsentry/sentry-go v0.11.0
@@ -44,12 +45,14 @@ require (
github.com/kevinburke/twilio-go v0.0.0-20200810163702-320748330fac github.com/kevinburke/twilio-go v0.0.0-20200810163702-320748330fac
github.com/lib/pq v1.9.0 github.com/lib/pq v1.9.0
github.com/lucasb-eyer/go-colorful v1.2.0 github.com/lucasb-eyer/go-colorful v1.2.0
github.com/magefile/mage v1.10.0 // indirect
github.com/manifoldco/promptui v0.7.0 github.com/manifoldco/promptui v0.7.0
github.com/mattn/go-colorable v0.1.8 // indirect; indirect github.com/mitchellh/copystructure v1.0.0 // indirect github.com/mattn/go-colorable v0.1.8 // indirect; indirect github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/minio/minio-go/v7 v7.0.10 github.com/minio/minio-go/v7 v7.0.10
github.com/mitchellh/copystructure v1.1.2 // indirect github.com/mitchellh/copystructure v1.1.2 // indirect
github.com/muesli/gamut v0.2.0 github.com/muesli/gamut v0.2.0
github.com/nicksnyder/go-i18n/v2 v2.1.2 github.com/nicksnyder/go-i18n/v2 v2.1.2
github.com/opencontainers/image-spec v1.0.1 // indirect
github.com/pkg/errors v0.9.1 github.com/pkg/errors v0.9.1
github.com/pquerna/otp v1.2.0 github.com/pquerna/otp v1.2.0
github.com/prometheus/client_golang v1.8.0 // indirect github.com/prometheus/client_golang v1.8.0 // indirect
@@ -79,7 +82,7 @@ require (
google.golang.org/grpc v1.36.1 google.golang.org/grpc v1.36.1
google.golang.org/protobuf v1.26.0 google.golang.org/protobuf v1.26.0
gopkg.in/square/go-jose.v2 v2.6.0 gopkg.in/square/go-jose.v2 v2.6.0
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
gotest.tools v2.2.0+incompatible gotest.tools v2.2.0+incompatible
k8s.io/api v0.19.2 k8s.io/api v0.19.2
k8s.io/apiextensions-apiserver v0.19.2 k8s.io/apiextensions-apiserver v0.19.2

22
go.sum
View File

@@ -149,6 +149,26 @@ github.com/caos/oidc v0.15.7 h1:jC7ugbQG1WJbGZgCXy1fE0B1VwWKvtKXLXY/pGDybhA=
github.com/caos/oidc v0.15.7/go.mod h1:doQ1B/mGnQWbgS+UOANIQCPJe1+KACyxQ8wjV2d11h0= github.com/caos/oidc v0.15.7/go.mod h1:doQ1B/mGnQWbgS+UOANIQCPJe1+KACyxQ8wjV2d11h0=
github.com/caos/orbos v1.5.14-0.20210428081839-983ffc569980 h1:Fz0aYUwGMA2tsu5w7SryqFGjqGClJVHbyhBMT5SXtPU= github.com/caos/orbos v1.5.14-0.20210428081839-983ffc569980 h1:Fz0aYUwGMA2tsu5w7SryqFGjqGClJVHbyhBMT5SXtPU=
github.com/caos/orbos v1.5.14-0.20210428081839-983ffc569980/go.mod h1:2I8oiZb5SMRm/qTLvwpSmdV0M6ex8J/UKyxUGfKaqJo= github.com/caos/orbos v1.5.14-0.20210428081839-983ffc569980/go.mod h1:2I8oiZb5SMRm/qTLvwpSmdV0M6ex8J/UKyxUGfKaqJo=
github.com/caos/orbos v1.5.14-0.20210714083228-b93d9fe7ffce h1:jon2Hu49yRj/Ud9yadHtq69Y0NbEe3ZrS6GGY6WSQ4w=
github.com/caos/orbos v1.5.14-0.20210714083228-b93d9fe7ffce/go.mod h1:HUMpCHr14uizCNAQ9lRQTDYBKSMw9QECTmr3h+Yrfzk=
github.com/caos/orbos v1.5.14-0.20210714084047-e8098b5c4425 h1:dWtZjqPZI+/+MN8PKq41WLxhETqbSOMe7LmsHzdGB9U=
github.com/caos/orbos v1.5.14-0.20210714084047-e8098b5c4425/go.mod h1:HUMpCHr14uizCNAQ9lRQTDYBKSMw9QECTmr3h+Yrfzk=
github.com/caos/orbos v1.5.14-0.20210714085518-c85d8aaa50a1 h1:foIqYwvIphQJxaNDsXcdQMJbrVaTWr06u30FMn+k38s=
github.com/caos/orbos v1.5.14-0.20210714085518-c85d8aaa50a1/go.mod h1:HUMpCHr14uizCNAQ9lRQTDYBKSMw9QECTmr3h+Yrfzk=
github.com/caos/orbos v1.5.14-0.20210714100409-551272c93db9 h1:UYz1WY8n8EJdUsZf6YHIhYJCiysbuCGrfuFcHtldeLE=
github.com/caos/orbos v1.5.14-0.20210714100409-551272c93db9/go.mod h1:HUMpCHr14uizCNAQ9lRQTDYBKSMw9QECTmr3h+Yrfzk=
github.com/caos/orbos v1.5.14-0.20210714140657-75d67d651032 h1:bspWDMtNxouegqibzlu2GnpNBOc5H4AjiZpQF4Zy5xk=
github.com/caos/orbos v1.5.14-0.20210714140657-75d67d651032/go.mod h1:HUMpCHr14uizCNAQ9lRQTDYBKSMw9QECTmr3h+Yrfzk=
github.com/caos/orbos v1.5.14-0.20210715071410-693c13f08917 h1:RQcvd7CZf321Chj9/qZPgA43JL5atW0pog3Q2LV9jWc=
github.com/caos/orbos v1.5.14-0.20210715071410-693c13f08917/go.mod h1:HUMpCHr14uizCNAQ9lRQTDYBKSMw9QECTmr3h+Yrfzk=
github.com/caos/orbos v1.5.14-0.20210720104010-5755dc25b89a h1:NPTYKauqeZEtkSjN0F06zjvn6bmqZXUGZ6YuITVwXUY=
github.com/caos/orbos v1.5.14-0.20210720104010-5755dc25b89a/go.mod h1:HUMpCHr14uizCNAQ9lRQTDYBKSMw9QECTmr3h+Yrfzk=
github.com/caos/orbos v1.5.14-0.20210721092606-ce76d1dca404 h1:BFivUFFntVfvKwB9k+o616KomTu6d1Rx6r0q+wfTAv8=
github.com/caos/orbos v1.5.14-0.20210721092606-ce76d1dca404/go.mod h1:HUMpCHr14uizCNAQ9lRQTDYBKSMw9QECTmr3h+Yrfzk=
github.com/caos/orbos v1.5.14-0.20210721123151-e8d9c5c2df11 h1:mQoO0LSUrY9KvepOkks8BrDfBAsiJ1P9qtZ9SO/QsPc=
github.com/caos/orbos v1.5.14-0.20210721123151-e8d9c5c2df11/go.mod h1:wLL07uotPKdNb7KPri3uTtGd2tFHZ3g7Y7wOt86+lqA=
github.com/caos/orbos v1.5.14-0.20210727080455-c90c315021f5 h1:Q/Rfq/9vZ9fNcg6YftROufGDyRJeNxmubLi0jwGJF8I=
github.com/caos/orbos v1.5.14-0.20210727080455-c90c315021f5/go.mod h1:wLL07uotPKdNb7KPri3uTtGd2tFHZ3g7Y7wOt86+lqA=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
@@ -1510,6 +1530,8 @@ gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gorm.io/driver/postgres v1.0.5/go.mod h1:qrD92UurYzNctBMVCJ8C3VQEjffEuphycXtxOudXNCA= gorm.io/driver/postgres v1.0.5/go.mod h1:qrD92UurYzNctBMVCJ8C3VQEjffEuphycXtxOudXNCA=
gorm.io/gorm v1.20.4/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.20.4/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=
gorm.io/gorm v1.20.6/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.20.6/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw=

View File

@@ -1,14 +1,16 @@
package operator package operator
import ( import (
"fmt"
"gopkg.in/yaml.v3"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/git" "github.com/caos/orbos/pkg/git"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/orbos/pkg/kubernetes/resources" "github.com/caos/orbos/pkg/kubernetes/resources"
"github.com/caos/orbos/pkg/secret" "github.com/caos/orbos/pkg/secret"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/pkg/errors"
"gopkg.in/yaml.v3"
) )
type AdaptFunc func( type AdaptFunc func(
@@ -84,7 +86,7 @@ func QueriersToEnsureFunc(monitor mntr.Monitor, infoLogs bool, queriers []QueryF
for _, querier := range queriers { for _, querier := range queriers {
ensurer, err := querier(k8sClient, queried) ensurer, err := querier(k8sClient, queried)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "error while querying") return nil, fmt.Errorf("error while querying: %w", err)
} }
ensurers = append(ensurers, ensurer) ensurers = append(ensurers, ensurer)
} }
@@ -101,7 +103,7 @@ func QueriersToEnsureFunc(monitor mntr.Monitor, infoLogs bool, queriers []QueryF
} }
for _, ensurer := range ensurers { for _, ensurer := range ensurers {
if err := ensurer(k8sClient); err != nil { if err := ensurer(k8sClient); err != nil {
return errors.Wrap(err, "error while ensuring") return fmt.Errorf("error while ensuring: %w", err)
} }
} }
if infoLogs { if infoLogs {
@@ -118,7 +120,7 @@ func DestroyersToDestroyFunc(monitor mntr.Monitor, destroyers []DestroyFunc) Des
monitor.Info("destroying...") monitor.Info("destroying...")
for _, destroyer := range destroyers { for _, destroyer := range destroyers {
if err := destroyer(k8sClient); err != nil { if err := destroyer(k8sClient); err != nil {
return errors.Wrap(err, "error while destroying") return fmt.Errorf("error while destroying: %w", err)
} }
} }
monitor.Info("destroyed") monitor.Info("destroyed")

View File

@@ -1,16 +1,19 @@
package crtlcrd package crtlcrd
import ( import (
"fmt"
"k8s.io/apimachinery/pkg/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
databasev1 "github.com/caos/zitadel/operator/api/database/v1" databasev1 "github.com/caos/zitadel/operator/api/database/v1"
zitadelv1 "github.com/caos/zitadel/operator/api/zitadel/v1" zitadelv1 "github.com/caos/zitadel/operator/api/zitadel/v1"
"github.com/caos/zitadel/operator/crtlcrd/database" "github.com/caos/zitadel/operator/crtlcrd/database"
"github.com/caos/zitadel/operator/crtlcrd/zitadel" "github.com/caos/zitadel/operator/crtlcrd/zitadel"
"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
) )
const ( const (
@@ -39,7 +42,7 @@ func Start(monitor mntr.Monitor, version, metricsAddr string, features ...string
LeaderElectionID: "9adsd12l.caos.ch", LeaderElectionID: "9adsd12l.caos.ch",
}) })
if err != nil { if err != nil {
return errors.Wrap(err, "unable to start manager") return fmt.Errorf("unable to start manager: %w", err)
} }
k8sClient, err := kubernetes.NewK8sClientWithConfig(monitor, cfg) k8sClient, err := kubernetes.NewK8sClientWithConfig(monitor, cfg)
@@ -56,7 +59,7 @@ func Start(monitor mntr.Monitor, version, metricsAddr string, features ...string
Scheme: mgr.GetScheme(), Scheme: mgr.GetScheme(),
Version: version, Version: version,
}).SetupWithManager(mgr); err != nil { }).SetupWithManager(mgr); err != nil {
return errors.Wrap(err, "unable to create controller") return fmt.Errorf("unable to create controller: %w", err)
} }
case Zitadel: case Zitadel:
if err = (&zitadel.Reconciler{ if err = (&zitadel.Reconciler{
@@ -65,13 +68,13 @@ func Start(monitor mntr.Monitor, version, metricsAddr string, features ...string
Scheme: mgr.GetScheme(), Scheme: mgr.GetScheme(),
Version: version, Version: version,
}).SetupWithManager(mgr); err != nil { }).SetupWithManager(mgr); err != nil {
return errors.Wrap(err, "unable to create controller") return fmt.Errorf("unable to create controller: %w", err)
} }
} }
} }
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
return errors.Wrap(err, "problem running manager") return fmt.Errorf("problem running manager: %w", err)
} }
return nil return nil
} }

View File

@@ -1,6 +1,10 @@
package backups package backups
import ( import (
"fmt"
corev1 "k8s.io/api/core/v1"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/orbos/pkg/labels" "github.com/caos/orbos/pkg/labels"
@@ -8,8 +12,6 @@ import (
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/caos/zitadel/operator" "github.com/caos/zitadel/operator"
"github.com/caos/zitadel/operator/database/kinds/backups/bucket" "github.com/caos/zitadel/operator/database/kinds/backups/bucket"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
) )
func Adapt( func Adapt(
@@ -44,7 +46,7 @@ func Adapt(
labels.MustReplaceAPI( labels.MustReplaceAPI(
labels.GetAPIFromComponent(componentLabels), labels.GetAPIFromComponent(componentLabels),
"BucketBackup", "BucketBackup",
desiredTree.Common.Version, desiredTree.Common.Version(),
), ),
"backup"), "backup"),
checkDBReady, checkDBReady,
@@ -56,7 +58,7 @@ func Adapt(
customImageRegistry, customImageRegistry,
)(monitor, desiredTree, currentTree) )(monitor, desiredTree, currentTree)
default: default:
return nil, nil, nil, nil, nil, false, errors.Errorf("unknown database kind %s", desiredTree.Common.Kind) return nil, nil, nil, nil, nil, false, mntr.ToUserError(fmt.Errorf("unknown database kind %s", desiredTree.Common.Kind))
} }
} }
@@ -73,6 +75,6 @@ func GetBackupList(
case "databases.caos.ch/BucketBackup": case "databases.caos.ch/BucketBackup":
return bucket.BackupList()(monitor, k8sClient, name, desiredTree) return bucket.BackupList()(monitor, k8sClient, name, desiredTree)
default: default:
return nil, errors.Errorf("unknown database kind %s", desiredTree.Common.Kind) return nil, mntr.ToUserError(fmt.Errorf("unknown database kind %s", desiredTree.Common.Kind))
} }
} }

View File

@@ -1,6 +1,10 @@
package bucket package bucket
import ( import (
"fmt"
corev1 "k8s.io/api/core/v1"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/orbos/pkg/kubernetes/resources/secret" "github.com/caos/orbos/pkg/kubernetes/resources/secret"
@@ -8,14 +12,13 @@ import (
secretpkg "github.com/caos/orbos/pkg/secret" secretpkg "github.com/caos/orbos/pkg/secret"
"github.com/caos/orbos/pkg/secret/read" "github.com/caos/orbos/pkg/secret/read"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
coreDB "github.com/caos/zitadel/operator/database/kinds/databases/core"
"github.com/caos/zitadel/operator" "github.com/caos/zitadel/operator"
"github.com/caos/zitadel/operator/common" "github.com/caos/zitadel/operator/common"
"github.com/caos/zitadel/operator/database/kinds/backups/bucket/backup" "github.com/caos/zitadel/operator/database/kinds/backups/bucket/backup"
"github.com/caos/zitadel/operator/database/kinds/backups/bucket/clean" "github.com/caos/zitadel/operator/database/kinds/backups/bucket/clean"
"github.com/caos/zitadel/operator/database/kinds/backups/bucket/restore" "github.com/caos/zitadel/operator/database/kinds/backups/bucket/restore"
coreDB "github.com/caos/zitadel/operator/database/kinds/databases/core"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
) )
const ( const (
@@ -53,7 +56,7 @@ func AdaptFunc(
desiredKind, err := ParseDesiredV0(desired) desiredKind, err := ParseDesiredV0(desired)
if err != nil { if err != nil {
return nil, nil, nil, nil, nil, false, errors.Wrap(err, "parsing desired state failed") return nil, nil, nil, nil, nil, false, fmt.Errorf("parsing desired state failed: %w", err)
} }
desired.Parsed = desiredKind desired.Parsed = desiredKind

View File

@@ -39,10 +39,7 @@ func TestBucket_Secrets(t *testing.T) {
version := "testVersion2" version := "testVersion2"
desired := getDesiredTree(t, masterkey, &DesiredV0{ desired := getDesiredTree(t, masterkey, &DesiredV0{
Common: &tree.Common{ Common: tree.NewCommon("databases.caos.ch/"+kind, kindVersion, false),
Kind: "databases.caos.ch/" + kind,
Version: kindVersion,
},
Spec: &Spec{ Spec: &Spec{
Verbose: true, Verbose: true,
Cron: cron, Cron: cron,
@@ -114,10 +111,7 @@ func TestBucket_AdaptBackup(t *testing.T) {
version := "testVersion2" version := "testVersion2"
desired := getDesiredTree(t, masterkey, &DesiredV0{ desired := getDesiredTree(t, masterkey, &DesiredV0{
Common: &tree.Common{ Common: tree.NewCommon("databases.caos.ch/BucketBackup", "v0", false),
Kind: "databases.caos.ch/BucketBackup",
Version: "v0",
},
Spec: &Spec{ Spec: &Spec{
Verbose: true, Verbose: true,
Cron: cron, Cron: cron,
@@ -189,10 +183,7 @@ func TestBucket_AdaptInstantBackup(t *testing.T) {
saJson := "testSA" saJson := "testSA"
desired := getDesiredTree(t, masterkey, &DesiredV0{ desired := getDesiredTree(t, masterkey, &DesiredV0{
Common: &tree.Common{ Common: tree.NewCommon("databases.caos.ch/BucketBackup", "v0", false),
Kind: "databases.caos.ch/BucketBackup",
Version: "v0",
},
Spec: &Spec{ Spec: &Spec{
Verbose: true, Verbose: true,
Cron: cron, Cron: cron,
@@ -265,10 +256,7 @@ func TestBucket_AdaptRestore(t *testing.T) {
saJson := "testSA" saJson := "testSA"
desired := getDesiredTree(t, masterkey, &DesiredV0{ desired := getDesiredTree(t, masterkey, &DesiredV0{
Common: &tree.Common{ Common: tree.NewCommon("databases.caos.ch/BucketBackup", "v0", false),
Kind: "databases.caos.ch/BucketBackup",
Version: "v0",
},
Spec: &Spec{ Spec: &Spec{
Verbose: true, Verbose: true,
Cron: cron, Cron: cron,
@@ -341,10 +329,7 @@ func TestBucket_AdaptClean(t *testing.T) {
saJson := "testSA" saJson := "testSA"
desired := getDesiredTree(t, masterkey, &DesiredV0{ desired := getDesiredTree(t, masterkey, &DesiredV0{
Common: &tree.Common{ Common: tree.NewCommon("databases.caos.ch/BucketBackup", "v0", false),
Kind: "databases.caos.ch/BucketBackup",
Version: "v0",
},
Spec: &Spec{ Spec: &Spec{
Verbose: true, Verbose: true,
Cron: cron, Cron: cron,

View File

@@ -1,10 +1,12 @@
package backup package backup
import ( import (
"fmt"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/zitadel/operator" "github.com/caos/zitadel/operator"
"github.com/pkg/errors"
) )
func GetCleanupFunc( func GetCleanupFunc(
@@ -15,13 +17,11 @@ func GetCleanupFunc(
return func(k8sClient kubernetes.ClientInt) error { return func(k8sClient kubernetes.ClientInt) error {
monitor.Info("waiting for backup to be completed") monitor.Info("waiting for backup to be completed")
if err := k8sClient.WaitUntilJobCompleted(namespace, GetJobName(backupName), timeout); err != nil { if err := k8sClient.WaitUntilJobCompleted(namespace, GetJobName(backupName), timeout); err != nil {
monitor.Error(errors.Wrap(err, "error while waiting for backup to be completed")) return fmt.Errorf("error while waiting for backup to be completed: %w", err)
return err
} }
monitor.Info("backup is completed, cleanup") monitor.Info("backup is completed, cleanup")
if err := k8sClient.DeleteJob(namespace, GetJobName(backupName)); err != nil { if err := k8sClient.DeleteJob(namespace, GetJobName(backupName)); err != nil {
monitor.Error(errors.Wrap(err, "error while trying to cleanup backup")) return fmt.Errorf("error while trying to cleanup backup: %w", err)
return err
} }
monitor.Info("restore backup is completed") monitor.Info("restore backup is completed")
return nil return nil

View File

@@ -1,13 +1,14 @@
package backup package backup
import ( import (
"errors"
"testing" "testing"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
kubernetesmock "github.com/caos/orbos/pkg/kubernetes/mock" kubernetesmock "github.com/caos/orbos/pkg/kubernetes/mock"
"github.com/golang/mock/gomock"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
) )
func TestBackup_Cleanup1(t *testing.T) { func TestBackup_Cleanup1(t *testing.T) {

View File

@@ -1,10 +1,12 @@
package clean package clean
import ( import (
"fmt"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/zitadel/operator" "github.com/caos/zitadel/operator"
"github.com/pkg/errors"
) )
func GetCleanupFunc( func GetCleanupFunc(
@@ -15,13 +17,11 @@ func GetCleanupFunc(
return func(k8sClient kubernetes.ClientInt) error { return func(k8sClient kubernetes.ClientInt) error {
monitor.Info("waiting for clean to be completed") monitor.Info("waiting for clean to be completed")
if err := k8sClient.WaitUntilJobCompleted(namespace, GetJobName(backupName), timeout); err != nil { if err := k8sClient.WaitUntilJobCompleted(namespace, GetJobName(backupName), timeout); err != nil {
monitor.Error(errors.Wrap(err, "error while waiting for clean to be completed")) return fmt.Errorf("error while waiting for clean to be completed: %w", err)
return err
} }
monitor.Info("clean is completed, cleanup") monitor.Info("clean is completed, cleanup")
if err := k8sClient.DeleteJob(namespace, GetJobName(backupName)); err != nil { if err := k8sClient.DeleteJob(namespace, GetJobName(backupName)); err != nil {
monitor.Error(errors.Wrap(err, "error while trying to cleanup clean")) return fmt.Errorf("error while trying to cleanup clean: %w", err)
return err
} }
monitor.Info("clean cleanup is completed") monitor.Info("clean cleanup is completed")
return nil return nil

View File

@@ -1,12 +1,14 @@
package clean package clean
import ( import (
"errors"
"testing"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
kubernetesmock "github.com/caos/orbos/pkg/kubernetes/mock" kubernetesmock "github.com/caos/orbos/pkg/kubernetes/mock"
"github.com/golang/mock/gomock"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"testing"
) )
func TestBackup_Cleanup1(t *testing.T) { func TestBackup_Cleanup1(t *testing.T) {

View File

@@ -3,9 +3,9 @@ package bucket
import ( import (
"fmt" "fmt"
"github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/secret" "github.com/caos/orbos/pkg/secret"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/pkg/errors"
) )
type DesiredV0 struct { type DesiredV0 struct {
@@ -38,7 +38,7 @@ func ParseDesiredV0(desiredTree *tree.Tree) (*DesiredV0, error) {
} }
if err := desiredTree.Original.Decode(desiredKind); err != nil { if err := desiredTree.Original.Decode(desiredKind); err != nil {
return nil, errors.Wrap(err, "parsing desired state failed") return nil, mntr.ToUserError(fmt.Errorf("parsing desired state failed: %w", err))
} }
return desiredKind, nil return desiredKind, nil

View File

@@ -1,11 +1,12 @@
package bucket package bucket
import ( import (
"testing"
"github.com/caos/orbos/pkg/secret" "github.com/caos/orbos/pkg/secret"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"gopkg.in/yaml.v3" "gopkg.in/yaml.v3"
"testing"
) )
const ( const (
@@ -38,10 +39,7 @@ version: v0`
var ( var (
desired = DesiredV0{ desired = DesiredV0{
Common: &tree.Common{ Common: tree.NewCommon("databases.caos.ch/BucketBackup", "v0", false),
Kind: "databases.caos.ch/BucketBackup",
Version: "v0",
},
Spec: &Spec{ Spec: &Spec{
Verbose: true, Verbose: true,
Cron: cron, Cron: cron,
@@ -54,10 +52,7 @@ var (
}, },
} }
desiredWithoutSecret = DesiredV0{ desiredWithoutSecret = DesiredV0{
Common: &tree.Common{ Common: tree.NewCommon("databases.caos.ch/BucketBackup", "v0", false),
Kind: "databases.caos.ch/BucketBackup",
Version: "v0",
},
Spec: &Spec{ Spec: &Spec{
Verbose: true, Verbose: true,
Cron: cron, Cron: cron,
@@ -65,10 +60,7 @@ var (
}, },
} }
desiredEmpty = DesiredV0{ desiredEmpty = DesiredV0{
Common: &tree.Common{ Common: tree.NewCommon("databases.caos.ch/BucketBackup", "v0", false),
Kind: "databases.caos.ch/BucketBackup",
Version: "v0",
},
Spec: &Spec{ Spec: &Spec{
Verbose: false, Verbose: false,
Cron: "", Cron: "",
@@ -80,10 +72,7 @@ var (
} }
desiredNil = DesiredV0{ desiredNil = DesiredV0{
Common: &tree.Common{ Common: tree.NewCommon("databases.caos.ch/BucketBackup", "v0", false),
Kind: "databases.caos.ch/BucketBackup",
Version: "v0",
},
} }
) )
@@ -106,7 +95,9 @@ func getDesiredTree(t *testing.T, masterkey string, desired *DesiredV0) *tree.Tr
} }
func TestBucket_DesiredParse(t *testing.T) { func TestBucket_DesiredParse(t *testing.T) {
assert.Equal(t, yamlFileWithoutSecret, string(marshalYaml(t, masterkey, &desiredWithoutSecret)))
result := string(marshalYaml(t, masterkey, &desiredWithoutSecret))
assert.Equal(t, yamlFileWithoutSecret, result)
desiredTree := unmarshalYaml(t, masterkey, []byte(yamlFile)) desiredTree := unmarshalYaml(t, masterkey, []byte(yamlFile))
desiredKind, err := ParseDesiredV0(desiredTree) desiredKind, err := ParseDesiredV0(desiredTree)

View File

@@ -1,24 +1,27 @@
package bucket package bucket
import ( import (
"cloud.google.com/go/storage"
"context" "context"
"fmt"
"strings"
"cloud.google.com/go/storage"
"google.golang.org/api/iterator"
"google.golang.org/api/option"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/orbos/pkg/secret/read" "github.com/caos/orbos/pkg/secret/read"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/caos/zitadel/operator/database/kinds/backups/core" "github.com/caos/zitadel/operator/database/kinds/backups/core"
"github.com/pkg/errors"
"google.golang.org/api/iterator"
"google.golang.org/api/option"
"strings"
) )
func BackupList() core.BackupListFunc { func BackupList() core.BackupListFunc {
return func(monitor mntr.Monitor, k8sClient kubernetes.ClientInt, name string, desired *tree.Tree) ([]string, error) { return func(monitor mntr.Monitor, k8sClient kubernetes.ClientInt, name string, desired *tree.Tree) ([]string, error) {
desiredKind, err := ParseDesiredV0(desired) desiredKind, err := ParseDesiredV0(desired)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "parsing desired state failed") return nil, fmt.Errorf("parsing desired state failed: %w", err)
} }
desired.Parsed = desiredKind desired.Parsed = desiredKind

View File

@@ -1,10 +1,11 @@
package restore package restore
import ( import (
"fmt"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/zitadel/operator" "github.com/caos/zitadel/operator"
"github.com/pkg/errors"
) )
func GetCleanupFunc( func GetCleanupFunc(
@@ -15,13 +16,11 @@ func GetCleanupFunc(
return func(k8sClient kubernetes.ClientInt) error { return func(k8sClient kubernetes.ClientInt) error {
monitor.Info("waiting for restore to be completed") monitor.Info("waiting for restore to be completed")
if err := k8sClient.WaitUntilJobCompleted(namespace, GetJobName(backupName), timeout); err != nil { if err := k8sClient.WaitUntilJobCompleted(namespace, GetJobName(backupName), timeout); err != nil {
monitor.Error(errors.Wrap(err, "error while waiting for restore to be completed")) return fmt.Errorf("error while waiting for restore to be completed: %w", err)
return err
} }
monitor.Info("restore is completed, cleanup") monitor.Info("restore is completed, cleanup")
if err := k8sClient.DeleteJob(namespace, GetJobName(backupName)); err != nil { if err := k8sClient.DeleteJob(namespace, GetJobName(backupName)); err != nil {
monitor.Error(errors.Wrap(err, "error while trying to cleanup restore")) return fmt.Errorf("error while trying to cleanup restore: %w", err)
return err
} }
monitor.Info("restore cleanup is completed") monitor.Info("restore cleanup is completed")
return nil return nil

View File

@@ -3,6 +3,7 @@ package core
import ( import (
"crypto/rsa" "crypto/rsa"
"errors" "errors"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/caos/zitadel/operator" "github.com/caos/zitadel/operator"
@@ -49,13 +50,13 @@ func SetQueriedForDatabaseDBList(queried map[string]interface{}, databases, user
currentDBList := &CurrentDBList{ currentDBList := &CurrentDBList{
Common: &tree.Common{ Common: &tree.Common{
Kind: "DBList", Kind: "DBList",
Version: "V0",
}, },
Current: &DatabaseCurrentDBList{ Current: &DatabaseCurrentDBList{
Databases: databases, Databases: databases,
Users: users, Users: users,
}, },
} }
currentDBList.Common.OverwriteVersion("V0")
currentDB := &tree.Tree{ currentDB := &tree.Tree{
Parsed: currentDBList, Parsed: currentDBList,

View File

@@ -1,16 +1,19 @@
package databases package databases
import ( import (
"fmt"
core "k8s.io/api/core/v1"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/orbos/pkg/labels" "github.com/caos/orbos/pkg/labels"
"github.com/caos/orbos/pkg/secret" "github.com/caos/orbos/pkg/secret"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/caos/zitadel/operator" "github.com/caos/zitadel/operator"
"github.com/caos/zitadel/operator/database/kinds/databases/managed" "github.com/caos/zitadel/operator/database/kinds/databases/managed"
"github.com/caos/zitadel/operator/database/kinds/databases/provided" "github.com/caos/zitadel/operator/database/kinds/databases/provided"
"github.com/pkg/errors"
core "k8s.io/api/core/v1"
) )
const ( const (
@@ -60,7 +63,7 @@ func Adapt(
case "databases.caos.ch/ProvidedDatabase": case "databases.caos.ch/ProvidedDatabase":
return provided.Adapter()(internalMonitor, desiredTree, currentTree) return provided.Adapter()(internalMonitor, desiredTree, currentTree)
default: default:
return nil, nil, nil, nil, nil, false, errors.Errorf("unknown database kind %s", desiredTree.Common.Kind) return nil, nil, nil, nil, nil, false, mntr.ToUserError(fmt.Errorf("unknown database kind %s: %w", desiredTree.Common.Kind, err))
} }
} }
@@ -76,8 +79,8 @@ func GetBackupList(
case "databases.caos.ch/CockroachDB": case "databases.caos.ch/CockroachDB":
return managed.BackupList()(monitor, k8sClient, desiredTree) return managed.BackupList()(monitor, k8sClient, desiredTree)
case "databases.caos.ch/ProvidedDatabse": case "databases.caos.ch/ProvidedDatabse":
return nil, errors.Errorf("no backups supported for database kind %s", desiredTree.Common.Kind) return nil, mntr.ToUserError(fmt.Errorf("no backups supported for database kind %s", desiredTree.Common.Kind))
default: default:
return nil, errors.Errorf("unknown database kind %s", desiredTree.Common.Kind) return nil, mntr.ToUserError(fmt.Errorf("unknown database kind %s", desiredTree.Common.Kind))
} }
} }

View File

@@ -1,30 +1,28 @@
package managed package managed
import ( import (
"fmt"
"strconv" "strconv"
"strings" "strings"
"github.com/caos/zitadel/operator/common"
"github.com/caos/zitadel/operator"
"github.com/caos/orbos/pkg/labels"
"github.com/caos/orbos/pkg/secret"
"github.com/caos/zitadel/operator/database/kinds/databases/managed/certificate"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/orbos/pkg/kubernetes/resources/pdb" "github.com/caos/orbos/pkg/kubernetes/resources/pdb"
"github.com/caos/orbos/pkg/labels"
"github.com/caos/orbos/pkg/secret"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/caos/zitadel/operator"
"github.com/caos/zitadel/operator/common"
"github.com/caos/zitadel/operator/database/kinds/backups" "github.com/caos/zitadel/operator/database/kinds/backups"
"github.com/caos/zitadel/operator/database/kinds/databases/core" "github.com/caos/zitadel/operator/database/kinds/databases/core"
"github.com/caos/zitadel/operator/database/kinds/databases/managed/certificate"
"github.com/caos/zitadel/operator/database/kinds/databases/managed/rbac" "github.com/caos/zitadel/operator/database/kinds/databases/managed/rbac"
"github.com/caos/zitadel/operator/database/kinds/databases/managed/services" "github.com/caos/zitadel/operator/database/kinds/databases/managed/services"
"github.com/caos/zitadel/operator/database/kinds/databases/managed/statefulset" "github.com/caos/zitadel/operator/database/kinds/databases/managed/statefulset"
"github.com/pkg/errors"
) )
const ( const (
@@ -35,7 +33,6 @@ const (
privateServiceName = SfsName privateServiceName = SfsName
cockroachPort = int32(26257) cockroachPort = int32(26257)
cockroachHTTPPort = int32(8080) cockroachHTTPPort = int32(8080)
image = "cockroachdb/cockroach:v20.2.3"
) )
func Adapter( func Adapter(
@@ -54,28 +51,38 @@ func Adapter(
desired *tree.Tree, desired *tree.Tree,
current *tree.Tree, current *tree.Tree,
) ( ) (
operator.QueryFunc, _ operator.QueryFunc,
operator.DestroyFunc, _ operator.DestroyFunc,
operator.ConfigureFunc, _ operator.ConfigureFunc,
map[string]*secret.Secret, _ map[string]*secret.Secret,
map[string]*secret.Existing, _ map[string]*secret.Existing,
bool, migrate bool,
error, err error,
) { ) {
defer func() {
if err != nil {
err = fmt.Errorf("adapting managed database failed: %w", err)
}
}()
var ( var (
internalMonitor = monitor.WithField("kind", "cockroachdb") internalMonitor = monitor.WithField("kind", "cockroachdb")
allSecrets = make(map[string]*secret.Secret) allSecrets = make(map[string]*secret.Secret)
allExisting = make(map[string]*secret.Existing) allExisting = make(map[string]*secret.Existing)
migrate bool
) )
desiredKind, err := parseDesiredV0(desired) desiredKind, err := parseDesiredV0(desired)
if err != nil { if err != nil {
return nil, nil, nil, nil, nil, false, errors.Wrap(err, "parsing desired state failed") return nil, nil, nil, nil, nil, false, fmt.Errorf("parsing desired state failed: %w", err)
} }
desired.Parsed = desiredKind desired.Parsed = desiredKind
storageCapacity, err := resource.ParseQuantity(desiredKind.Spec.StorageCapacity)
if err != nil {
return nil, nil, nil, nil, nil, false, mntr.ToUserError(fmt.Errorf("parsing storage capacity format failed: %w", err))
}
if !monitor.IsVerbose() && desiredKind.Spec.Verbose { if !monitor.IsVerbose() && desiredKind.Spec.Verbose {
internalMonitor.Verbose() internalMonitor.Verbose()
} }
@@ -120,7 +127,7 @@ func Adapter(
common.CockroachImage.Reference(customImageRegistry), common.CockroachImage.Reference(customImageRegistry),
serviceAccountName, serviceAccountName,
desiredKind.Spec.ReplicaCount, desiredKind.Spec.ReplicaCount,
desiredKind.Spec.StorageCapacity, storageCapacity,
cockroachPort, cockroachPort,
cockroachHTTPPort, cockroachHTTPPort,
desiredKind.Spec.StorageClass, desiredKind.Spec.StorageClass,
@@ -148,10 +155,7 @@ func Adapter(
} }
currentDB := &Current{ currentDB := &Current{
Common: &tree.Common{ Common: tree.NewCommon("databases.caos.ch/CockroachDB", "v0", false),
Kind: "databases.caos.ch/CockroachDB",
Version: "v0",
},
Current: &CurrentDB{ Current: &CurrentDB{
CA: &certificate.Current{}, CA: &certificate.Current{},
}, },

View File

@@ -21,10 +21,7 @@ import (
func getTreeWithDBAndBackup(t *testing.T, masterkey string, saJson string, backupName string) *tree.Tree { func getTreeWithDBAndBackup(t *testing.T, masterkey string, saJson string, backupName string) *tree.Tree {
bucketDesired := getDesiredTree(t, masterkey, &bucket.DesiredV0{ bucketDesired := getDesiredTree(t, masterkey, &bucket.DesiredV0{
Common: &tree.Common{ Common: tree.NewCommon("databases.caos.ch/BucketBackup", "v0", false),
Kind: "databases.caos.ch/BucketBackup",
Version: "v0",
},
Spec: &bucket.Spec{ Spec: &bucket.Spec{
Verbose: true, Verbose: true,
Cron: "testCron", Cron: "testCron",
@@ -39,10 +36,7 @@ func getTreeWithDBAndBackup(t *testing.T, masterkey string, saJson string, backu
bucketDesired.Parsed = bucketDesiredKind bucketDesired.Parsed = bucketDesiredKind
return getDesiredTree(t, masterkey, &DesiredV0{ return getDesiredTree(t, masterkey, &DesiredV0{
Common: &tree.Common{ Common: tree.NewCommon("databases.caos.ch/CockroachDB", "v0", false),
Kind: "databases.caos.ch/CockroachDB",
Version: "v0",
},
Spec: Spec{ Spec: Spec{
Verbose: false, Verbose: false,
ReplicaCount: 1, ReplicaCount: 1,

View File

@@ -74,10 +74,7 @@ func TestManaged_Adapt1(t *testing.T) {
queried := map[string]interface{}{} queried := map[string]interface{}{}
desired := getDesiredTree(t, masterkey, &DesiredV0{ desired := getDesiredTree(t, masterkey, &DesiredV0{
Common: &tree.Common{ Common: tree.NewCommon("databases.caos.ch/CockroachDB", "v0", false),
Kind: "databases.caos.ch/CockroachDB",
Version: "v0",
},
Spec: Spec{ Spec: Spec{
Verbose: false, Verbose: false,
ReplicaCount: 1, ReplicaCount: 1,
@@ -195,10 +192,7 @@ func TestManaged_Adapt2(t *testing.T) {
queried := map[string]interface{}{} queried := map[string]interface{}{}
desired := getDesiredTree(t, masterkey, &DesiredV0{ desired := getDesiredTree(t, masterkey, &DesiredV0{
Common: &tree.Common{ Common: tree.NewCommon("databases.caos.ch/CockroachDB", "v0", false),
Kind: "databases.caos.ch/CockroachDB",
Version: "v0",
},
Spec: Spec{ Spec: Spec{
Verbose: false, Verbose: false,
ReplicaCount: 1, ReplicaCount: 1,

View File

@@ -1,10 +1,13 @@
package managed package managed
import ( import (
"fmt"
corev1 "k8s.io/api/core/v1"
"github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes/k8s" "github.com/caos/orbos/pkg/kubernetes/k8s"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
) )
type DesiredV0 struct { type DesiredV0 struct {
@@ -32,7 +35,7 @@ func parseDesiredV0(desiredTree *tree.Tree) (*DesiredV0, error) {
} }
if err := desiredTree.Original.Decode(desiredKind); err != nil { if err := desiredTree.Original.Decode(desiredKind); err != nil {
return nil, errors.Wrap(err, "parsing desired state failed") return nil, mntr.ToUserError(fmt.Errorf("parsing desired state failed"))
} }
return desiredKind, nil return desiredKind, nil

View File

@@ -1,18 +1,20 @@
package managed package managed
import ( import (
"fmt"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/caos/zitadel/operator/database/kinds/backups" "github.com/caos/zitadel/operator/database/kinds/backups"
"github.com/pkg/errors"
) )
func BackupList() func(monitor mntr.Monitor, k8sClient kubernetes.ClientInt, desired *tree.Tree) ([]string, error) { func BackupList() func(monitor mntr.Monitor, k8sClient kubernetes.ClientInt, desired *tree.Tree) ([]string, error) {
return func(monitor mntr.Monitor, k8sClient kubernetes.ClientInt, desired *tree.Tree) ([]string, error) { return func(monitor mntr.Monitor, k8sClient kubernetes.ClientInt, desired *tree.Tree) ([]string, error) {
desiredKind, err := parseDesiredV0(desired) desiredKind, err := parseDesiredV0(desired)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "parsing desired state failed") return nil, fmt.Errorf("parsing desired state failed: %w", err)
} }
desired.Parsed = desiredKind desired.Parsed = desiredKind

View File

@@ -1,14 +1,16 @@
package statefulset package statefulset
import ( import (
"errors"
"fmt" "fmt"
"sort" "sort"
"strings" "strings"
"time" "time"
"github.com/caos/orbos/pkg/labels" appsv1 "k8s.io/api/apps/v1"
"github.com/caos/zitadel/operator" corev1 "k8s.io/api/core/v1"
"github.com/caos/zitadel/operator/helpers" "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/intstr"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
@@ -16,11 +18,10 @@ import (
"github.com/caos/orbos/pkg/kubernetes/k8s" "github.com/caos/orbos/pkg/kubernetes/k8s"
"github.com/caos/orbos/pkg/kubernetes/resources" "github.com/caos/orbos/pkg/kubernetes/resources"
"github.com/caos/orbos/pkg/kubernetes/resources/statefulset" "github.com/caos/orbos/pkg/kubernetes/resources/statefulset"
"github.com/pkg/errors" "github.com/caos/orbos/pkg/labels"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1" "github.com/caos/zitadel/operator"
"k8s.io/apimachinery/pkg/api/resource" "github.com/caos/zitadel/operator/helpers"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
) )
const ( const (
@@ -55,7 +56,7 @@ func AdaptFunc(
image string, image string,
serviceAccountName string, serviceAccountName string,
replicaCount int, replicaCount int,
storageCapacity string, storageCapacity resource.Quantity,
dbPort int32, dbPort int32,
httpPort int32, httpPort int32,
storageClass string, storageClass string,
@@ -72,11 +73,6 @@ func AdaptFunc(
) { ) {
internalMonitor := monitor.WithField("component", "statefulset") internalMonitor := monitor.WithField("component", "statefulset")
quantity, err := resource.ParseQuantity(storageCapacity)
if err != nil {
return nil, nil, nil, nil, nil, err
}
name := sfsSelectable.Name() name := sfsSelectable.Name()
k8sSelectable := labels.MustK8sMap(sfsSelectable) k8sSelectable := labels.MustK8sMap(sfsSelectable)
statefulsetDef := &appsv1.StatefulSet{ statefulsetDef := &appsv1.StatefulSet{
@@ -197,7 +193,7 @@ func AdaptFunc(
}, },
Resources: corev1.ResourceRequirements{ Resources: corev1.ResourceRequirements{
Requests: corev1.ResourceList{ Requests: corev1.ResourceList{
"storage": quantity, "storage": storageCapacity,
}, },
}, },
StorageClassName: &storageClass, StorageClassName: &storageClass,
@@ -219,8 +215,7 @@ func AdaptFunc(
checkDBRunning := func(k8sClient kubernetes.ClientInt) error { checkDBRunning := func(k8sClient kubernetes.ClientInt) error {
internalMonitor.Info("waiting for statefulset to be running") internalMonitor.Info("waiting for statefulset to be running")
if err := k8sClient.WaitUntilStatefulsetIsReady(namespace, name, true, false, 60*time.Second); err != nil { if err := k8sClient.WaitUntilStatefulsetIsReady(namespace, name, true, false, 60*time.Second); err != nil {
internalMonitor.Error(errors.Wrap(err, "error while waiting for statefulset to be running")) return fmt.Errorf("error while waiting for statefulset to be running: %w", err)
return err
} }
internalMonitor.Info("statefulset is running") internalMonitor.Info("statefulset is running")
return nil return nil
@@ -232,7 +227,6 @@ func AdaptFunc(
internalMonitor.Info("statefulset is not ready") internalMonitor.Info("statefulset is not ready")
return nil return nil
} }
internalMonitor.Info("statefulset is ready")
return errors.New("statefulset is ready") return errors.New("statefulset is ready")
} }
@@ -256,8 +250,7 @@ func AdaptFunc(
checkDBReady := func(k8sClient kubernetes.ClientInt) error { checkDBReady := func(k8sClient kubernetes.ClientInt) error {
internalMonitor.Info("waiting for statefulset to be ready") internalMonitor.Info("waiting for statefulset to be ready")
if err := k8sClient.WaitUntilStatefulsetIsReady(namespace, name, true, true, 60*time.Second); err != nil { if err := k8sClient.WaitUntilStatefulsetIsReady(namespace, name, true, true, 60*time.Second); err != nil {
internalMonitor.Error(errors.Wrap(err, "error while waiting for statefulset to be ready")) return fmt.Errorf("error while waiting for statefulset to be ready: %w", err)
return err
} }
internalMonitor.Info("statefulset is ready") internalMonitor.Info("statefulset is ready")
return nil return nil

View File

@@ -1,6 +1,8 @@
package statefulset package statefulset
import ( import (
"testing"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes/k8s" "github.com/caos/orbos/pkg/kubernetes/k8s"
kubernetesmock "github.com/caos/orbos/pkg/kubernetes/mock" kubernetesmock "github.com/caos/orbos/pkg/kubernetes/mock"
@@ -13,7 +15,6 @@ import (
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/intstr"
"testing"
) )
func TestStatefulset_JoinExec0(t *testing.T) { func TestStatefulset_JoinExec0(t *testing.T) {
@@ -291,7 +292,7 @@ func TestStatefulset_Adapt1(t *testing.T) {
image, image,
serviceAccountName, serviceAccountName,
replicaCount, replicaCount,
storageCapacity, resource.MustParse(storageCapacity),
dbPort, dbPort,
httpPort, httpPort,
storageClass, storageClass,
@@ -487,7 +488,7 @@ func TestStatefulset_Adapt2(t *testing.T) {
image, image,
serviceAccountName, serviceAccountName,
replicaCount, replicaCount,
storageCapacity, resource.MustParse(storageCapacity),
dbPort, dbPort,
httpPort, httpPort,
storageClass, storageClass,

View File

@@ -1,12 +1,14 @@
package provided package provided
import ( import (
"fmt"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/orbos/pkg/secret" "github.com/caos/orbos/pkg/secret"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/caos/zitadel/operator" "github.com/caos/zitadel/operator"
"github.com/pkg/errors"
) )
func Adapter() operator.AdaptFunc { func Adapter() operator.AdaptFunc {
@@ -25,15 +27,12 @@ func Adapter() operator.AdaptFunc {
) { ) {
desiredKind, err := parseDesiredV0(desired) desiredKind, err := parseDesiredV0(desired)
if err != nil { if err != nil {
return nil, nil, nil, nil, nil, false, errors.Wrap(err, "parsing desired state failed") return nil, nil, nil, nil, nil, false, fmt.Errorf("parsing desired state failed: %w", err)
} }
desired.Parsed = desiredKind desired.Parsed = desiredKind
currentDB := &Current{ currentDB := &Current{
Common: &tree.Common{ Common: tree.NewCommon("databases.caos.ch/ProvidedDatabase", "v0", false),
Kind: "databases.caos.ch/ProvidedDatabase",
Version: "v0",
},
} }
current.Parsed = currentDB current.Parsed = currentDB

View File

@@ -1,8 +1,10 @@
package provided package provided
import ( import (
"fmt"
"github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/pkg/errors"
) )
type DesiredV0 struct { type DesiredV0 struct {
@@ -25,7 +27,7 @@ func parseDesiredV0(desiredTree *tree.Tree) (*DesiredV0, error) {
} }
if err := desiredTree.Original.Decode(desiredKind); err != nil { if err := desiredTree.Original.Decode(desiredKind); err != nil {
return nil, errors.Wrap(err, "parsing desired state failed") return nil, mntr.ToUserError(fmt.Errorf("parsing desired state failed: %w", err))
} }
return desiredKind, nil return desiredKind, nil

View File

@@ -1,6 +1,8 @@
package orb package orb
import ( import (
"fmt"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/orbos/pkg/kubernetes/resources/namespace" "github.com/caos/orbos/pkg/kubernetes/resources/namespace"
@@ -8,12 +10,12 @@ import (
"github.com/caos/orbos/pkg/secret" "github.com/caos/orbos/pkg/secret"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/caos/orbos/pkg/treelabels" "github.com/caos/orbos/pkg/treelabels"
"github.com/caos/zitadel/operator" "github.com/caos/zitadel/operator"
"github.com/caos/zitadel/operator/database/kinds/backups/bucket/backup" "github.com/caos/zitadel/operator/database/kinds/backups/bucket/backup"
"github.com/caos/zitadel/operator/database/kinds/backups/bucket/clean" "github.com/caos/zitadel/operator/database/kinds/backups/bucket/clean"
"github.com/caos/zitadel/operator/database/kinds/backups/bucket/restore" "github.com/caos/zitadel/operator/database/kinds/backups/bucket/restore"
"github.com/caos/zitadel/operator/database/kinds/databases" "github.com/caos/zitadel/operator/database/kinds/databases"
"github.com/pkg/errors"
) )
const ( const (
@@ -45,14 +47,16 @@ func AdaptFunc(
err error, err error,
) { ) {
defer func() { defer func() {
err = errors.Wrapf(err, "building %s failed", orbDesiredTree.Common.Kind) if err != nil {
err = fmt.Errorf("building %s failed: %w", orbDesiredTree.Common.Kind, err)
}
}() }()
orbMonitor := monitor.WithField("kind", "orb") orbMonitor := monitor.WithField("kind", "orb")
desiredKind, err := ParseDesiredV0(orbDesiredTree) desiredKind, err := ParseDesiredV0(orbDesiredTree)
if err != nil { if err != nil {
return nil, nil, nil, nil, nil, migrate, errors.Wrap(err, "parsing desired state failed") return nil, nil, nil, nil, nil, migrate, fmt.Errorf("parsing desired state failed: %w", err)
} }
orbDesiredTree.Parsed = desiredKind orbDesiredTree.Parsed = desiredKind
currentTree = &tree.Tree{} currentTree = &tree.Tree{}
@@ -118,10 +122,7 @@ func AdaptFunc(
} }
currentTree.Parsed = &DesiredV0{ currentTree.Parsed = &DesiredV0{
Common: &tree.Common{ Common: tree.NewCommon("databases.caos.ch/Orb", "v0", false),
Kind: "databases.caos.ch/Orb",
Version: "v0",
},
Database: databaseCurrent, Database: databaseCurrent,
} }

View File

@@ -1,18 +1,20 @@
package orb package orb
import ( import (
"fmt"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/caos/zitadel/operator/database/kinds/databases" "github.com/caos/zitadel/operator/database/kinds/databases"
"github.com/pkg/errors"
) )
func BackupListFunc() func(monitor mntr.Monitor, k8sClient kubernetes.ClientInt, desiredTree *tree.Tree) (strings []string, err error) { func BackupListFunc() func(monitor mntr.Monitor, k8sClient kubernetes.ClientInt, desiredTree *tree.Tree) (strings []string, err error) {
return func(monitor mntr.Monitor, k8sClient kubernetes.ClientInt, desiredTree *tree.Tree) (strings []string, err error) { return func(monitor mntr.Monitor, k8sClient kubernetes.ClientInt, desiredTree *tree.Tree) (strings []string, err error) {
desiredKind, err := ParseDesiredV0(desiredTree) desiredKind, err := ParseDesiredV0(desiredTree)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "parsing desired state failed") return nil, fmt.Errorf("parsing desired state failed: %w", err)
} }
desiredTree.Parsed = desiredKind desiredTree.Parsed = desiredKind

View File

@@ -1,8 +1,10 @@
package orb package orb
import ( import (
"fmt"
"github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
) )
@@ -28,9 +30,9 @@ func ParseDesiredV0(desiredTree *tree.Tree) (*DesiredV0, error) {
desiredKind := &DesiredV0{Common: desiredTree.Common} desiredKind := &DesiredV0{Common: desiredTree.Common}
if err := desiredTree.Original.Decode(desiredKind); err != nil { if err := desiredTree.Original.Decode(desiredKind); err != nil {
return nil, errors.Wrap(err, "parsing desired state failed") return nil, mntr.ToUserError(fmt.Errorf("parsing desired state failed: %w", err))
} }
desiredKind.Common.Version = "v0" desiredKind.Common.OverwriteVersion("v0")
return desiredKind, nil return desiredKind, nil
} }

View File

@@ -1,14 +1,17 @@
package orb package orb
import ( import (
"errors"
"fmt"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/orbos/pkg/labels" "github.com/caos/orbos/pkg/labels"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/caos/orbos/pkg/treelabels" "github.com/caos/orbos/pkg/treelabels"
"github.com/caos/zitadel/operator" "github.com/caos/zitadel/operator"
zitadelKubernetes "github.com/caos/zitadel/pkg/kubernetes" zitadelKubernetes "github.com/caos/zitadel/pkg/kubernetes"
"github.com/pkg/errors"
) )
func Reconcile( func Reconcile(
@@ -23,29 +26,23 @@ func Reconcile(
recMonitor := monitor.WithField("version", spec.Version) recMonitor := monitor.WithField("version", spec.Version)
if spec.Version == "" { if spec.Version == "" {
err := errors.New("No version provided for self-reconciling") return errors.New("no version provided for self-reconciling")
return err
} }
if spec.SelfReconciling { if spec.SelfReconciling {
desiredTree := &tree.Tree{ desiredTree := &tree.Tree{
Common: &tree.Common{ Common: tree.NewCommon("databases.caos.ch/Orb", "v0", false),
Kind: "databases.caos.ch/Orb",
Version: "v0",
},
} }
if err := zitadelKubernetes.EnsureDatabaseArtifacts(monitor, treelabels.MustForAPI(desiredTree, mustDatabaseOperator(&spec.Version)), k8sClient, spec.Version, spec.NodeSelector, spec.Tolerations, spec.CustomImageRegistry, gitops); err != nil { if err := zitadelKubernetes.EnsureDatabaseArtifacts(monitor, treelabels.MustForAPI(desiredTree, mustDatabaseOperator(&spec.Version)), k8sClient, spec.Version, spec.NodeSelector, spec.Tolerations, spec.CustomImageRegistry, gitops); err != nil {
recMonitor.Error(errors.Wrap(err, "Failed to deploy database-operator into k8s-cluster")) return fmt.Errorf("failed to deploy database-operator into k8s-cluster: %w", err)
return err
} }
recMonitor.Info("Applied database-operator") recMonitor.Info("Applied database-operator")
} }
return nil return nil
}, func(k8sClient kubernetes.ClientInt) error { }, func(k8sClient kubernetes.ClientInt) error {
if err := zitadelKubernetes.DestroyDatabaseOperator(monitor, labels.MustForAPI(labels.NoopOperator("database-operator"), "database", "v0"), k8sClient, gitops); err != nil { if err := zitadelKubernetes.DestroyDatabaseOperator(monitor, labels.MustForAPI(labels.NoopOperator("database-operator"), "database", "v0"), k8sClient, gitops); err != nil {
monitor.Error(errors.Wrap(err, "Failed to destroy database-operator in k8s-cluster")) return fmt.Errorf("failed to destroy database-operator in k8s-cluster: %w", err)
return err
} }
monitor.Info("Destroyed database-operator") monitor.Info("Destroyed database-operator")
return nil return nil

View File

@@ -105,7 +105,7 @@ func getAllSecrets(
} }
if len(allSecrets) == 0 && len(allExisting) == 0 { if len(allSecrets) == 0 && len(allExisting) == 0 {
return nil, nil, nil, errors.New("couldn't find any secrets") return nil, nil, nil, mntr.ToUserError(errors.New("couldn't find any secrets"))
} }
return allSecrets, allExisting, allTrees, nil return allSecrets, allExisting, allTrees, nil
@@ -158,7 +158,7 @@ func push(
desired, found := trees[desiredFile.WOExtension()] desired, found := trees[desiredFile.WOExtension()]
if !found { if !found {
return fmt.Errorf("desired state not found for %s", desiredFile.WOExtension()) return mntr.ToUserError(fmt.Errorf("desired state not found for %s", desiredFile.WOExtension()))
} }
if gitops { if gitops {

View File

@@ -3,16 +3,16 @@ package iam
import ( import (
"fmt" "fmt"
"github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/database" core "k8s.io/api/core/v1"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/labels" "github.com/caos/orbos/pkg/labels"
"github.com/caos/orbos/pkg/secret" "github.com/caos/orbos/pkg/secret"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/caos/zitadel/operator" "github.com/caos/zitadel/operator"
"github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel" "github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel"
"github.com/pkg/errors" "github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/database"
core "k8s.io/api/core/v1"
) )
func Adapt( func Adapt(
@@ -46,7 +46,7 @@ func Adapt(
switch desiredTree.Common.Kind { switch desiredTree.Common.Kind {
case "zitadel.caos.ch/ZITADEL": case "zitadel.caos.ch/ZITADEL":
apiLabels := labels.MustForAPI(operatorLabels, "ZITADEL", desiredTree.Common.Version) apiLabels := labels.MustForAPI(operatorLabels, "ZITADEL", desiredTree.Common.Version())
return zitadel.AdaptFunc( return zitadel.AdaptFunc(
apiLabels, apiLabels,
nodeselector, nodeselector,
@@ -59,6 +59,6 @@ func Adapt(
customImageRegistry, customImageRegistry,
)(monitor, desiredTree, currentTree) )(monitor, desiredTree, currentTree)
default: default:
return nil, nil, nil, nil, nil, false, errors.Errorf("unknown iam kind %s", desiredTree.Common.Kind) return nil, nil, nil, nil, nil, false, mntr.ToUserError(fmt.Errorf("unknown iam kind %s", desiredTree.Common.Kind))
} }
} }

View File

@@ -1,29 +1,29 @@
package zitadel package zitadel
import ( import (
"errors"
"fmt"
"strconv" "strconv"
"strings"
"github.com/caos/orbos/pkg/helper"
"gopkg.in/yaml.v3" "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"
"github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/setup"
core "k8s.io/api/core/v1" core "k8s.io/api/core/v1"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/helper"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/orbos/pkg/labels"
"github.com/caos/orbos/pkg/secret"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/caos/zitadel/operator" "github.com/caos/zitadel/operator"
"github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/ambassador" "github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/ambassador"
"github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/configuration" "github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/configuration"
"github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/database"
"github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/deployment" "github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/deployment"
"github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/migration" "github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/migration"
"github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/services" "github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/services"
"github.com/pkg/errors" "github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/setup"
) )
func AdaptFunc( func AdaptFunc(
@@ -54,8 +54,19 @@ func AdaptFunc(
internalMonitor := monitor.WithField("kind", "iam") internalMonitor := monitor.WithField("kind", "iam")
desiredKind, err := parseDesiredV0(desired) desiredKind, err := parseDesiredV0(desired)
_, _, sendAnalytics := mntr.Environment()
if sendAnalytics &&
desiredKind != nil &&
desiredKind.Spec != nil &&
desiredKind.Spec.Configuration != nil &&
desiredKind.Spec.Configuration.DNS != nil &&
desiredKind.Spec.Configuration.DNS.Domain != "" {
monitor.SwitchEnvironment(strings.ToLower(strings.ReplaceAll(desiredKind.Spec.Configuration.DNS.Domain, ".", "-")))
}
if err != nil { if err != nil {
return nil, nil, nil, nil, nil, false, errors.Wrap(err, "parsing desired state failed") return nil, nil, nil, nil, nil, false, fmt.Errorf("parsing desired state failed: %w", err)
} }
desired.Parsed = desiredKind desired.Parsed = desiredKind
@@ -114,7 +125,6 @@ func AdaptFunc(
certPath, certPath,
secretName, secretName,
secretPath, secretPath,
version,
consoleCMName, consoleCMName,
secretVarsName, secretVarsName,
secretPasswordName, secretPasswordName,

View File

@@ -38,7 +38,6 @@ func AdaptFunc(
certPath string, certPath string,
secretName string, secretName string,
secretPath string, secretPath string,
version *string,
consoleCMName string, consoleCMName string,
secretVarsName string, secretVarsName string,
secretPasswordName string, secretPasswordName string,
@@ -149,7 +148,6 @@ func AdaptFunc(
secretPath, secretPath,
googleServiceAccountJSONPath, googleServiceAccountJSONPath,
zitadelKeysPath, zitadelKeysPath,
version,
queried, queried,
), ),
) )
@@ -196,7 +194,6 @@ func AdaptFunc(
secretPath, secretPath,
googleServiceAccountJSONPath, googleServiceAccountJSONPath,
zitadelKeysPath, zitadelKeysPath,
version,
queried, queried,
), ),
), ),

View File

@@ -34,7 +34,7 @@ func SetConfigMap(
Name: cmName, Name: cmName,
Labels: labels, Labels: labels,
}, },
Data: literalsConfigMap(desired, users, certPath, secretPath, googleServiceAccountJSONPath, zitadelKeysPath, version, queried), Data: literalsConfigMap(desired, users, certPath, secretPath, googleServiceAccountJSONPath, zitadelKeysPath, queried),
}) })
} }
@@ -215,7 +215,6 @@ func TestConfiguration_Adapt(t *testing.T) {
certPath, certPath,
secretName, secretName,
secretPath, secretPath,
&version,
consoleCMName, consoleCMName,
secretVarsName, secretVarsName,
secretPasswordName, secretPasswordName,
@@ -325,7 +324,6 @@ func TestConfiguration_AdaptFull(t *testing.T) {
certPath, certPath,
secretName, secretName,
secretPath, secretPath,
&version,
consoleCMName, consoleCMName,
secretVarsName, secretVarsName,
secretPasswordName, secretPasswordName,

View File

@@ -19,7 +19,6 @@ type Configuration struct {
DNS *DNS `yaml:"dns"` DNS *DNS `yaml:"dns"`
ClusterDNS string `yaml:"clusterdns"` ClusterDNS string `yaml:"clusterdns"`
AssetStorage *AssetStorage `yaml:"assetStorage,omitempty"` AssetStorage *AssetStorage `yaml:"assetStorage,omitempty"`
Sentry *Sentry `yaml:"sentry,omitempty"`
} }
func (c *Configuration) Validate() (err error) { func (c *Configuration) Validate() (err error) {
@@ -143,11 +142,3 @@ type Cache struct {
ShortMaxAge string `yaml:"shortMaxAge,omitempty"` ShortMaxAge string `yaml:"shortMaxAge,omitempty"`
ShortSharedMaxAge string `yaml:"shortSharedMaxAge,omitempty"` ShortSharedMaxAge string `yaml:"shortSharedMaxAge,omitempty"`
} }
type Sentry struct {
SentryDSN *secret.Secret `yaml:"sentryDSN,omitempty"`
ExistingSentryDSN *secret.Existing `yaml:"existingSentryDSN,omitempty"`
Environment string `yaml:"environment,omitempty"`
Version string `yaml:"version,omitempty"`
Usage string `yaml:"usage,omitempty"`
}

View File

@@ -5,6 +5,8 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/secret/read" "github.com/caos/orbos/pkg/secret/read"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
@@ -19,7 +21,6 @@ func literalsConfigMap(
desired *Configuration, desired *Configuration,
users map[string]string, users map[string]string,
certPath, secretPath, googleServiceAccountJSONPath, zitadelKeysPath string, certPath, secretPath, googleServiceAccountJSONPath, zitadelKeysPath string,
version *string,
queried map[string]interface{}, queried map[string]interface{},
) map[string]string { ) map[string]string {
@@ -110,13 +111,12 @@ func literalsConfigMap(
literalsConfigMap["ZITADEL_ASSET_STORAGE_BUCKET_PREFIX"] = desired.AssetStorage.BucketPrefix literalsConfigMap["ZITADEL_ASSET_STORAGE_BUCKET_PREFIX"] = desired.AssetStorage.BucketPrefix
literalsConfigMap["ZITADEL_ASSET_STORAGE_MULTI_DELETE"] = strconv.FormatBool(desired.AssetStorage.MultiDelete) literalsConfigMap["ZITADEL_ASSET_STORAGE_MULTI_DELETE"] = strconv.FormatBool(desired.AssetStorage.MultiDelete)
} }
if desired.Sentry != nil {
literalsConfigMap["SENTRY_ENVIRONMENT"] = desired.Sentry.Environment
literalsConfigMap["SENTRY_RELEASE"] = *version
literalsConfigMap["SENTRY_USAGE"] = desired.Sentry.Usage
}
} }
sentryEnv, _, doIngest := mntr.Environment()
literalsConfigMap["SENTRY_ENVIRONMENT"] = sentryEnv
literalsConfigMap["SENTRY_USAGE"] = strconv.FormatBool(doIngest)
db, err := database.GetDatabaseInQueried(queried) db, err := database.GetDatabaseInQueried(queried)
if err == nil { if err == nil {
literalsConfigMap["ZITADEL_EVENTSTORE_HOST"] = db.Host literalsConfigMap["ZITADEL_EVENTSTORE_HOST"] = db.Host
@@ -197,16 +197,13 @@ func literalsSecretVars(k8sClient kubernetes.ClientInt, desired *Configuration)
literalsSecretVars["ZITADEL_ASSET_STORAGE_SECRET_ACCESS_KEY"] = value literalsSecretVars["ZITADEL_ASSET_STORAGE_SECRET_ACCESS_KEY"] = value
} }
} }
if desired.Sentry != nil {
as := desired.Sentry _, dsns, doIngest := mntr.Environment()
if as.SentryDSN != nil || as.ExistingSentryDSN != nil { zitadelDsn := ""
value, err := read.GetSecretValue(k8sClient, as.SentryDSN, as.ExistingSentryDSN) if doIngest {
if err != nil { zitadelDsn = dsns["zitadel"]
return nil, err
}
literalsSecretVars["SENTRY_DSN"] = value
}
} }
literalsSecretVars["SENTRY_DSN"] = zitadelDsn
} }
return literalsSecretVars, nil return literalsSecretVars, nil
} }

View File

@@ -222,7 +222,6 @@ func TestConfiguration_LiteralsConfigMap(t *testing.T) {
secretPath := "test" secretPath := "test"
googleSA := "test" googleSA := "test"
zitadelKeyPath := "test" zitadelKeyPath := "test"
version := "test"
users := map[string]string{ users := map[string]string{
"migration": "migration", "migration": "migration",
"management": "management", "management": "management",
@@ -296,9 +295,11 @@ func TestConfiguration_LiteralsConfigMap(t *testing.T) {
"ZITADEL_ASSET_STORAGE_LOCATION": "", "ZITADEL_ASSET_STORAGE_LOCATION": "",
"ZITADEL_ASSET_STORAGE_BUCKET_PREFIX": "", "ZITADEL_ASSET_STORAGE_BUCKET_PREFIX": "",
"ZITADEL_ASSET_STORAGE_MULTI_DELETE": "false", "ZITADEL_ASSET_STORAGE_MULTI_DELETE": "false",
"SENTRY_ENVIRONMENT": "",
"SENTRY_USAGE": "false",
} }
literals := literalsConfigMap(desiredEmpty, users, certPath, secretPath, googleSA, zitadelKeyPath, &version, queried) literals := literalsConfigMap(desiredEmpty, users, certPath, secretPath, googleSA, zitadelKeyPath, queried)
assert.Equal(t, equals, literals) assert.Equal(t, equals, literals)
} }
@@ -308,7 +309,6 @@ func TestConfiguration_LiteralsConfigMapFull(t *testing.T) {
secretPath := "test" secretPath := "test"
googleSA := "test" googleSA := "test"
zitadelKeyPath := "test" zitadelKeyPath := "test"
version := "test"
users := map[string]string{ users := map[string]string{
"migration": "migration2", "migration": "migration2",
"management": "management2", "management": "management2",
@@ -382,8 +382,10 @@ func TestConfiguration_LiteralsConfigMapFull(t *testing.T) {
"ZITADEL_ASSET_STORAGE_LOCATION": "location", "ZITADEL_ASSET_STORAGE_LOCATION": "location",
"ZITADEL_ASSET_STORAGE_BUCKET_PREFIX": "bucketprefix", "ZITADEL_ASSET_STORAGE_BUCKET_PREFIX": "bucketprefix",
"ZITADEL_ASSET_STORAGE_MULTI_DELETE": "false", "ZITADEL_ASSET_STORAGE_MULTI_DELETE": "false",
"SENTRY_ENVIRONMENT": "",
"SENTRY_USAGE": "false",
} }
literals := literalsConfigMap(desiredFull, users, certPath, secretPath, googleSA, zitadelKeyPath, &version, queried) literals := literalsConfigMap(desiredFull, users, certPath, secretPath, googleSA, zitadelKeyPath, queried)
assert.EqualValues(t, equals, literals) assert.EqualValues(t, equals, literals)
} }
@@ -461,6 +463,7 @@ func TestConfiguration_LiteralsSecretVars(t *testing.T) {
"ZITADEL_TWILIO_SID": "", "ZITADEL_TWILIO_SID": "",
"ZITADEL_ASSET_STORAGE_ACCESS_KEY_ID": "", "ZITADEL_ASSET_STORAGE_ACCESS_KEY_ID": "",
"ZITADEL_ASSET_STORAGE_SECRET_ACCESS_KEY": "", "ZITADEL_ASSET_STORAGE_SECRET_ACCESS_KEY": "",
"SENTRY_DSN": "",
} }
literals, err := literalsSecretVars(client, desiredEmpty) literals, err := literalsSecretVars(client, desiredEmpty)
assert.NoError(t, err) assert.NoError(t, err)
@@ -477,6 +480,7 @@ func TestConfiguration_LiteralsSecretVarsFull(t *testing.T) {
"ZITADEL_TWILIO_SID": "sid", "ZITADEL_TWILIO_SID": "sid",
"ZITADEL_ASSET_STORAGE_ACCESS_KEY_ID": "accesskeyid", "ZITADEL_ASSET_STORAGE_ACCESS_KEY_ID": "accesskeyid",
"ZITADEL_ASSET_STORAGE_SECRET_ACCESS_KEY": "secretaccesskey", "ZITADEL_ASSET_STORAGE_SECRET_ACCESS_KEY": "secretaccesskey",
"SENTRY_DSN": "",
} }
literals, err := literalsSecretVars(client, desiredFull) literals, err := literalsSecretVars(client, desiredFull)
@@ -534,6 +538,7 @@ func TestConfiguration_LiteralsSecretVarsExisting(t *testing.T) {
"ZITADEL_TWILIO_SID": sid, "ZITADEL_TWILIO_SID": sid,
"ZITADEL_ASSET_STORAGE_ACCESS_KEY_ID": akid, "ZITADEL_ASSET_STORAGE_ACCESS_KEY_ID": akid,
"ZITADEL_ASSET_STORAGE_SECRET_ACCESS_KEY": sak, "ZITADEL_ASSET_STORAGE_SECRET_ACCESS_KEY": sak,
"SENTRY_DSN": "",
} }
literals, err := literalsSecretVars(client, desiredFull) literals, err := literalsSecretVars(client, desiredFull)

View File

@@ -1,9 +1,10 @@
package configuration package configuration
import ( import (
"fmt"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/pkg/errors"
) )
func GetReadyFunc( func GetReadyFunc(
@@ -18,23 +19,23 @@ func GetReadyFunc(
return func(k8sClient kubernetes.ClientInt) error { return func(k8sClient kubernetes.ClientInt) error {
monitor.Debug("Waiting for configuration to be created") monitor.Debug("Waiting for configuration to be created")
if err := k8sClient.WaitForSecret(namespace, secretName, timeout); err != nil { if err := k8sClient.WaitForSecret(namespace, secretName, timeout); err != nil {
return errors.Wrap(err, "error while waiting for secret") return fmt.Errorf("error while waiting for secret: %w", err)
} }
if err := k8sClient.WaitForSecret(namespace, secretVarsName, timeout); err != nil { if err := k8sClient.WaitForSecret(namespace, secretVarsName, timeout); err != nil {
return errors.Wrap(err, "error while waiting for vars secret ") return fmt.Errorf("error while waiting for vars secret: %w", err)
} }
if err := k8sClient.WaitForSecret(namespace, secretPasswordName, timeout); err != nil { if err := k8sClient.WaitForSecret(namespace, secretPasswordName, timeout); err != nil {
return errors.Wrap(err, "error while waiting for password secret") return fmt.Errorf("error while waiting for password secret: %w", err)
} }
if err := k8sClient.WaitForConfigMap(namespace, cmName, timeout); err != nil { if err := k8sClient.WaitForConfigMap(namespace, cmName, timeout); err != nil {
return errors.Wrap(err, "error while waiting for configmap") return fmt.Errorf("error while waiting for configmap: %w", err)
} }
if err := k8sClient.WaitForConfigMap(namespace, consoleCMName, timeout); err != nil { if err := k8sClient.WaitForConfigMap(namespace, consoleCMName, timeout); err != nil {
return errors.Wrap(err, "error while waiting for console configmap") return fmt.Errorf("error while waiting for console configmap: %w", err)
} }
monitor.Debug("configuration is created") monitor.Debug("configuration is created")
return nil return nil

View File

@@ -1,21 +1,21 @@
package deployment package deployment
import ( import (
"fmt"
"time" "time"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/orbos/pkg/labels" "github.com/caos/orbos/pkg/labels"
"github.com/caos/zitadel/operator" "github.com/caos/zitadel/operator"
"github.com/pkg/errors"
) )
func GetReadyFunc(monitor mntr.Monitor, namespace string, name *labels.Name) operator.EnsureFunc { func GetReadyFunc(monitor mntr.Monitor, namespace string, name *labels.Name) operator.EnsureFunc {
return func(k8sClient kubernetes.ClientInt) error { return func(k8sClient kubernetes.ClientInt) error {
monitor.Info("waiting for deployment to be ready") monitor.Info("waiting for deployment to be ready")
if err := k8sClient.WaitUntilDeploymentReady(namespace, name.Name(), true, true, 60*time.Second); err != nil { if err := k8sClient.WaitUntilDeploymentReady(namespace, name.Name(), true, true, 60*time.Second); err != nil {
monitor.Error(errors.Wrap(err, "error while waiting for deployment to be ready")) return fmt.Errorf("error while waiting for deployment to be ready: %w", err)
return err
} }
monitor.Info("deployment is ready") monitor.Info("deployment is ready")
return nil return nil

View File

@@ -3,11 +3,13 @@ package zitadel
import ( import (
"fmt" "fmt"
corev1 "k8s.io/api/core/v1"
"github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes/k8s" "github.com/caos/orbos/pkg/kubernetes/k8s"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/configuration" "github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/configuration"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1"
) )
type DesiredV0 struct { type DesiredV0 struct {
@@ -29,7 +31,7 @@ type Spec struct {
func (s *Spec) validate() (err error) { func (s *Spec) validate() (err error) {
defer func() { defer func() {
if err != nil { if err != nil {
err = fmt.Errorf("validating spec failed: %w", err) err = mntr.ToUserError(fmt.Errorf("validating spec failed: %w", err))
} }
}() }()
@@ -43,8 +45,7 @@ func parseDesiredV0(desiredTree *tree.Tree) (*DesiredV0, error) {
} }
if err := desiredTree.Original.Decode(desiredKind); err != nil { if err := desiredTree.Original.Decode(desiredKind); err != nil {
return nil, errors.Wrap(err, "parsing desired state failed") return nil, mntr.ToUserError(fmt.Errorf("parsing desired state failed: %w", err))
} }
return desiredKind, nil return desiredKind, nil
} }

View File

@@ -4,26 +4,26 @@ import (
"crypto/sha512" "crypto/sha512"
"encoding/base64" "encoding/base64"
"encoding/json" "encoding/json"
"fmt"
"os" "os"
"path/filepath" "path/filepath"
"regexp" "regexp"
"sort" "sort"
"github.com/pkg/errors"
"github.com/rakyll/statik/fs" "github.com/rakyll/statik/fs"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/orbos/pkg/kubernetes/resources/configmap" "github.com/caos/orbos/pkg/kubernetes/resources/configmap"
"github.com/caos/orbos/pkg/kubernetes/resources/job" "github.com/caos/orbos/pkg/kubernetes/resources/job"
"github.com/caos/orbos/pkg/labels" "github.com/caos/orbos/pkg/labels"
"github.com/caos/zitadel/operator" "github.com/caos/zitadel/operator"
"github.com/caos/zitadel/operator/helpers" "github.com/caos/zitadel/operator/helpers"
"github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/database" "github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/database"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
_ "github.com/caos/zitadel/statik" _ "github.com/caos/zitadel/statik"
) )
@@ -209,7 +209,7 @@ func getMigrationFiles(monitor mntr.Monitor, root string) []migration {
statikFS, err := fs.New() statikFS, err := fs.New()
if err != nil { if err != nil {
monitor.Error(errors.Wrap(err, "failed to load migration files")) monitor.Error(fmt.Errorf("failed to load migration files: %w", err))
return migrations return migrations
} }
err = fs.Walk(statikFS, root, func(path string, info os.FileInfo, err error) error { err = fs.Walk(statikFS, root, func(path string, info os.FileInfo, err error) error {

View File

@@ -1,10 +1,11 @@
package migration package migration
import ( import (
"fmt"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/zitadel/operator" "github.com/caos/zitadel/operator"
"github.com/pkg/errors"
) )
func GetCleanupFunc( func GetCleanupFunc(
@@ -15,8 +16,7 @@ func GetCleanupFunc(
return func(k8sClient kubernetes.ClientInt) error { return func(k8sClient kubernetes.ClientInt) error {
monitor.Info("cleanup migration job") monitor.Info("cleanup migration job")
if err := k8sClient.DeleteJob(namespace, getJobName(reason)); err != nil { if err := k8sClient.DeleteJob(namespace, getJobName(reason)); err != nil {
monitor.Error(errors.Wrap(err, "error during job deletion")) return fmt.Errorf("error during job deletion: %w", err)
return err
} }
monitor.Info("migration cleanup is completed") monitor.Info("migration cleanup is completed")
return nil return nil

View File

@@ -1,12 +1,13 @@
package migration package migration
import ( import (
"fmt"
"time" "time"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/zitadel/operator" "github.com/caos/zitadel/operator"
"github.com/pkg/errors"
) )
const ( const (
@@ -21,8 +22,7 @@ func GetDoneFunc(
return func(k8sClient kubernetes.ClientInt) error { return func(k8sClient kubernetes.ClientInt) error {
monitor.Info("waiting for migration to be completed") monitor.Info("waiting for migration to be completed")
if err := k8sClient.WaitUntilJobCompleted(namespace, getJobName(reason), timeout); err != nil { if err := k8sClient.WaitUntilJobCompleted(namespace, getJobName(reason), timeout); err != nil {
monitor.Error(errors.Wrap(err, "error while waiting for migration to be completed")) return fmt.Errorf("error while waiting for migration to be completed: %w", err)
return err
} }
monitor.Info("migration is completed") monitor.Info("migration is completed")
return nil return nil

View File

@@ -125,19 +125,5 @@ func getSecretsMap(desiredKind *DesiredV0) (
secrets[secretKey] = conf.AssetStorage.SecretAccessKey secrets[secretKey] = conf.AssetStorage.SecretAccessKey
existing[secretKey] = conf.AssetStorage.ExistingSecretAccessKey existing[secretKey] = conf.AssetStorage.ExistingSecretAccessKey
if conf.Sentry == nil {
conf.Sentry = &configuration.Sentry{}
}
if conf.Sentry.SentryDSN == nil {
conf.Sentry.SentryDSN = &secret.Secret{}
}
if conf.Sentry.ExistingSentryDSN == nil {
conf.Sentry.ExistingSentryDSN = &secret.Existing{}
}
SentryDSN := "sentrydsn"
secrets[SentryDSN] = conf.Sentry.SentryDSN
existing[SentryDSN] = conf.Sentry.ExistingSentryDSN
return secrets, existing return secrets, existing
} }

View File

@@ -1,11 +1,13 @@
package setup package setup
import ( import (
"fmt"
"time"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/zitadel/operator" "github.com/caos/zitadel/operator"
"github.com/pkg/errors"
"time"
) )
const ( const (
@@ -20,8 +22,7 @@ func GetDoneFunc(
return func(k8sClient kubernetes.ClientInt) error { return func(k8sClient kubernetes.ClientInt) error {
monitor.Info("waiting for setup to be completed") monitor.Info("waiting for setup to be completed")
if err := k8sClient.WaitUntilJobCompleted(namespace, getJobName(reason), timeout); err != nil { if err := k8sClient.WaitUntilJobCompleted(namespace, getJobName(reason), timeout); err != nil {
monitor.Error(errors.Wrap(err, "error while waiting for setup to be completed")) return fmt.Errorf("error while waiting for setup to be completed: %w", err)
return err
} }
monitor.Info("migration is completed") monitor.Info("migration is completed")
return nil return nil

View File

@@ -1,16 +1,18 @@
package orb package orb
import ( import (
"fmt"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/kubernetes" "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/orbos/pkg/kubernetes/resources/namespace" "github.com/caos/orbos/pkg/kubernetes/resources/namespace"
"github.com/caos/orbos/pkg/orb" "github.com/caos/orbos/pkg/orb"
"github.com/caos/orbos/pkg/secret" "github.com/caos/orbos/pkg/secret"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/caos/zitadel/operator" "github.com/caos/zitadel/operator"
"github.com/caos/zitadel/operator/zitadel/kinds/iam" "github.com/caos/zitadel/operator/zitadel/kinds/iam"
zitadeldb "github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/database" zitadeldb "github.com/caos/zitadel/operator/zitadel/kinds/iam/zitadel/database"
"github.com/pkg/errors"
) )
const ( const (
@@ -38,7 +40,9 @@ func AdaptFunc(
err error, err error,
) { ) {
defer func() { defer func() {
err = errors.Wrapf(err, "building %s failed", desiredTree.Common.Kind) if err != nil {
err = fmt.Errorf("building %s failed: %w", desiredTree.Common.Kind, err)
}
}() }()
allSecrets = make(map[string]*secret.Secret) allSecrets = make(map[string]*secret.Secret)
@@ -48,7 +52,7 @@ func AdaptFunc(
desiredKind, err := ParseDesiredV0(desiredTree) desiredKind, err := ParseDesiredV0(desiredTree)
if err != nil { if err != nil {
return nil, nil, nil, nil, nil, false, errors.Wrap(err, "parsing desired state failed") return nil, nil, nil, nil, nil, false, fmt.Errorf("parsing desired state failed: %w", err)
} }
desiredTree.Parsed = desiredKind desiredTree.Parsed = desiredKind
currentTree = &tree.Tree{} currentTree = &tree.Tree{}
@@ -122,10 +126,7 @@ func AdaptFunc(
} }
currentTree.Parsed = &DesiredV0{ currentTree.Parsed = &DesiredV0{
Common: &tree.Common{ Common: tree.NewCommon("zitadel.caos.ch/Orb", "v0", false),
Kind: "zitadel.caos.ch/Orb",
Version: "v0",
},
IAM: iamCurrent, IAM: iamCurrent,
} }

View File

@@ -1,9 +1,12 @@
package orb package orb
import ( import (
"github.com/caos/orbos/pkg/tree" "fmt"
"github.com/pkg/errors"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
"github.com/caos/orbos/mntr"
"github.com/caos/orbos/pkg/tree"
) )
type DesiredV0 struct { type DesiredV0 struct {
@@ -28,9 +31,9 @@ func ParseDesiredV0(desiredTree *tree.Tree) (*DesiredV0, error) {
desiredKind := &DesiredV0{Common: desiredTree.Common} desiredKind := &DesiredV0{Common: desiredTree.Common}
if err := desiredTree.Original.Decode(desiredKind); err != nil { if err := desiredTree.Original.Decode(desiredKind); err != nil {
return nil, errors.Wrap(err, "parsing desired state failed") return nil, mntr.ToUserError(fmt.Errorf("parsing desired state failed: %w", err))
} }
desiredKind.Common.Version = "v0" desiredKind.Common.OverwriteVersion("v0")
return desiredKind, nil return desiredKind, nil
} }

View File

@@ -1,15 +1,17 @@
package orb package orb
import ( import (
"errors"
"fmt" "fmt"
"github.com/caos/orbos/mntr" "github.com/caos/orbos/mntr"
kubernetes2 "github.com/caos/orbos/pkg/kubernetes" kubernetes2 "github.com/caos/orbos/pkg/kubernetes"
"github.com/caos/orbos/pkg/labels" "github.com/caos/orbos/pkg/labels"
"github.com/caos/orbos/pkg/tree" "github.com/caos/orbos/pkg/tree"
"github.com/caos/orbos/pkg/treelabels" "github.com/caos/orbos/pkg/treelabels"
"github.com/caos/zitadel/operator" "github.com/caos/zitadel/operator"
"github.com/caos/zitadel/pkg/kubernetes" "github.com/caos/zitadel/pkg/kubernetes"
"github.com/pkg/errors"
) )
func Reconcile( func Reconcile(
@@ -24,17 +26,12 @@ func Reconcile(
recMonitor := monitor.WithField("version", spec.Version) recMonitor := monitor.WithField("version", spec.Version)
if spec.Version == "" { if spec.Version == "" {
err := errors.New("No version provided for self-reconciling") return mntr.ToUserError(errors.New("no version provided for self-reconciling"))
recMonitor.Error(err)
return err
} }
if spec.SelfReconciling { if spec.SelfReconciling {
desiredTree := &tree.Tree{ desiredTree := &tree.Tree{
Common: &tree.Common{ Common: tree.NewCommon("zitadel.caos.ch/Orb", "v0", false),
Kind: "zitadel.caos.ch/Orb",
Version: "v0",
},
} }
if err := kubernetes.EnsureZitadelOperatorArtifacts(monitor, treelabels.MustForAPI(desiredTree, mustZITADELOperator(&spec.Version)), k8sClient, spec.Version, spec.NodeSelector, spec.Tolerations, spec.CustomImageRegistry, gitops); err != nil { if err := kubernetes.EnsureZitadelOperatorArtifacts(monitor, treelabels.MustForAPI(desiredTree, mustZITADELOperator(&spec.Version)), k8sClient, spec.Version, spec.NodeSelector, spec.Tolerations, spec.CustomImageRegistry, gitops); err != nil {
@@ -45,8 +42,7 @@ func Reconcile(
return nil return nil
}, func(k8sClient kubernetes2.ClientInt) error { }, func(k8sClient kubernetes2.ClientInt) error {
if err := kubernetes.DestroyZitadelOperator(monitor, labels.MustForAPI(labels.NoopOperator("zitadel-operator"), "zitadel", "v0"), k8sClient, gitops); err != nil { if err := kubernetes.DestroyZitadelOperator(monitor, labels.MustForAPI(labels.NoopOperator("zitadel-operator"), "zitadel", "v0"), k8sClient, gitops); err != nil {
monitor.Error(errors.Wrap(err, "Failed to destroy zitadel-operator in k8s-cluster")) return fmt.Errorf("failed to destroy zitadel-operator in k8s-cluster: %w", err)
return err
} }
monitor.Info("Destroyed zitadel-operator") monitor.Info("Destroyed zitadel-operator")
return nil return nil

View File

@@ -256,6 +256,10 @@ status:
}} }}
} }
if _, _, analyticsEnabled := mntr.Environment(); !analyticsEnabled {
cmd = append(cmd, "--disable-analytics")
}
deployment := &apps.Deployment{ deployment := &apps.Deployment{
ObjectMeta: mach.ObjectMeta{ ObjectMeta: mach.ObjectMeta{
Name: nameLabels.Name(), Name: nameLabels.Name(),
@@ -601,6 +605,10 @@ status:
}} }}
} }
if _, _, analyticsEnabled := mntr.Environment(); !analyticsEnabled {
cmd = append(cmd, "--disable-analytics")
}
deployment := &apps.Deployment{ deployment := &apps.Deployment{
ObjectMeta: mach.ObjectMeta{ ObjectMeta: mach.ObjectMeta{
Name: nameLabels.Name(), Name: nameLabels.Name(),