Skip to content

Commit

Permalink
#1 Move functionality back to blueprint operator
Browse files Browse the repository at this point in the history
  • Loading branch information
ppxl committed Jan 16, 2025
1 parent d976dad commit 3022bd0
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 328 deletions.
9 changes: 4 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ module github.com/cloudogu/blueprint-lib
go 1.23.4

require (
github.com/Masterminds/semver/v3 v3.3.0
github.com/cloudogu/ces-commons-lib v0.2.0
github.com/cloudogu/cesapp-lib v0.18.0
github.com/cloudogu/k8s-blueprint-operator/v2 v2.2.2
github.com/cloudogu/k8s-registry-lib v0.5.1
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.10.0
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c
k8s.io/apimachinery v0.31.2
)

require (
github.com/Masterminds/semver/v3 v3.3.0 // indirect
github.com/cloudogu/k8s-registry-lib v0.5.1 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/eapache/go-resiliency v1.7.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
Expand All @@ -21,9 +22,7 @@ require (
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
github.com/x448/float16 v0.8.4 // indirect
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect
golang.org/x/sys v0.29.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apimachinery v0.31.2 // indirect
)
4 changes: 0 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ github.com/cloudogu/ces-commons-lib v0.2.0 h1:yOEZWFl4W9N3J/6fok4svE3UufK5GQQtyx
github.com/cloudogu/ces-commons-lib v0.2.0/go.mod h1:4rvR2RTDDaz5a6OZ1fW27G0MOnl5I3ackeiHxt4gn3o=
github.com/cloudogu/cesapp-lib v0.18.0 h1:9VsWJLXiyhcKlbOcQ/M3O6xvZqpOfKlRqdkjwqAmOy4=
github.com/cloudogu/cesapp-lib v0.18.0/go.mod h1:J05eXFxnz4enZblABlmiVTZaUtJ+LIhlJ2UF6l9jpDw=
github.com/cloudogu/k8s-blueprint-operator/v2 v2.2.2 h1:Yok8Uq0wrN8WhcIYSfTgwpEXfs9rizm8MJDyDBrQsQU=
github.com/cloudogu/k8s-blueprint-operator/v2 v2.2.2/go.mod h1:xlpK+7giaTr9iEcWw96NKYEXInaRhysvDNwK3NSPj8E=
github.com/cloudogu/k8s-registry-lib v0.5.1 h1:gbdrhETUm53GP65LoljrS1kekDDl/onBPfrOQTQpt1s=
github.com/cloudogu/k8s-registry-lib v0.5.1/go.mod h1:mdMOgknEOrGQH1zc/3K859iPhwpqwtzigK9QrjM3Vk0=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
Expand All @@ -18,8 +16,6 @@ github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/gammazero/toposort v0.1.1 h1:OivGxsWxF3U3+U80VoLJ+f50HcPU1MIqE1JlKzoJ2Eg=
github.com/gammazero/toposort v0.1.1/go.mod h1:H2cozTnNpMw0hg2VHAYsAxmkHXBYroNangj2NTBQDvw=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
Expand Down
20 changes: 1 addition & 19 deletions v2/component.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
package v2

import (
"errors"
"fmt"

"github.com/Masterminds/semver/v3"
"github.com/cloudogu/k8s-blueprint-operator/v2/pkg/domain/ecosystem"
)

// Component represents a CES component (e.g. operators), its version, and the installation state in which it is supposed to be
Expand All @@ -19,19 +15,5 @@ type Component struct {
// TargetState defines a state of installation of this package. Optional field, but defaults to "TargetStatePresent"
TargetState TargetState
// DeployConfig defines generic properties for the component. This field is optional.
DeployConfig ecosystem.DeployConfig
}

// Validate checks if the component is semantically correct.
func (component *Component) Validate() error {
nameError := component.Name.Validate()

var versionErr error
if component.TargetState == TargetStatePresent {
if component.Version == nil {
versionErr = fmt.Errorf("version of component %q must not be empty", component.Name)
}
}

return errors.Join(versionErr, nameError)
DeployConfig map[string]interface{}
}
79 changes: 0 additions & 79 deletions v2/component_test.go

This file was deleted.

152 changes: 14 additions & 138 deletions v2/config.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package v2

import (
"errors"
"fmt"
"golang.org/x/exp/maps"
"slices"

cescommons "github.com/cloudogu/ces-commons-lib/dogu"
"golang.org/x/exp/maps"
)

// censorValue is the value for censoring sensitive blueprint configuration data.
const censorValue = "*****"

type Config struct {
Dogus map[cescommons.SimpleName]CombinedDoguConfig
Global GlobalConfig
Expand All @@ -21,35 +20,35 @@ type CombinedDoguConfig struct {
}

type DoguConfig struct {
Present map[common.DoguConfigKey]common.DoguConfigValue
Absent []common.DoguConfigKey
Present map[DoguConfigKey]DoguConfigValue
Absent []DoguConfigKey
}

type SensitiveDoguConfig = DoguConfig

type GlobalConfig struct {
Present map[common.GlobalConfigKey]common.GlobalConfigValue
Absent []common.GlobalConfigKey
Present map[GlobalConfigKey]GlobalConfigValue
Absent []GlobalConfigKey
}

func (config GlobalConfig) GetGlobalConfigKeys() []common.GlobalConfigKey {
var keys []common.GlobalConfigKey
func (config GlobalConfig) GetGlobalConfigKeys() []GlobalConfigKey {
var keys []GlobalConfigKey
keys = append(keys, maps.Keys(config.Present)...)
keys = append(keys, config.Absent...)
return keys
}

func (config Config) GetDoguConfigKeys() []common.DoguConfigKey {
var keys []common.DoguConfigKey
func (config Config) GetDoguConfigKeys() []DoguConfigKey {
var keys []DoguConfigKey
for _, doguConfig := range config.Dogus {
keys = append(keys, maps.Keys(doguConfig.Config.Present)...)
keys = append(keys, doguConfig.Config.Absent...)
}
return keys
}

func (config Config) GetSensitiveDoguConfigKeys() []common.SensitiveDoguConfigKey {
var keys []common.SensitiveDoguConfigKey
func (config Config) GetSensitiveDoguConfigKeys() []SensitiveDoguConfigKey {
var keys []SensitiveDoguConfigKey
for _, doguConfig := range config.Dogus {
keys = append(keys, maps.Keys(doguConfig.SensitiveConfig.Present)...)
keys = append(keys, doguConfig.SensitiveConfig.Absent...)
Expand Down Expand Up @@ -88,126 +87,3 @@ func (config Config) censorValues() Config {
}
return config
}

func (config Config) validate() error {
var errs []error
for doguName, doguConfig := range config.Dogus {
if doguName != doguConfig.DoguName {
errs = append(errs, fmt.Errorf("dogu name %q in map and dogu name %q in value are not equal", doguName, doguConfig.DoguName))
}
errs = append(errs, doguConfig.validate())
}
errs = append(errs, config.Global.validate())

return errors.Join(errs...)
}

func (config CombinedDoguConfig) validate() error {
err := errors.Join(
config.Config.validate(config.DoguName),
config.SensitiveConfig.validate(config.DoguName),
config.validateConflictingConfigKeys(),
)

if err != nil {
return fmt.Errorf("config for dogu %q is invalid: %w", config.DoguName, err)
}
return nil
}

// validateConflictingConfigKeys checks that there are no conflicting keys in normal config and sensitive config.
// This is a problem as both config types are loaded via the same API in dogus at the moment.
func (config CombinedDoguConfig) validateConflictingConfigKeys() error {
var normalKeys []common.DoguConfigKey
normalKeys = append(normalKeys, maps.Keys(config.Config.Present)...)
normalKeys = append(normalKeys, config.Config.Absent...)
var sensitiveKeys []common.SensitiveDoguConfigKey
sensitiveKeys = append(sensitiveKeys, maps.Keys(config.SensitiveConfig.Present)...)
sensitiveKeys = append(sensitiveKeys, config.SensitiveConfig.Absent...)

var errorList []error

for _, sensitiveKey := range sensitiveKeys {
keyToSearch := common.DoguConfigKey{
DoguName: sensitiveKey.DoguName,
Key: sensitiveKey.Key,
}
if slices.Contains(normalKeys, keyToSearch) {
errorList = append(errorList, fmt.Errorf("dogu config key %s cannot be in normal and sensitive configuration at the same time", keyToSearch))
}
}
return errors.Join(errorList...)
}

func (config DoguConfig) validate(referencedDoguName cescommons.SimpleName) error {
var errs []error

for configKey := range config.Present {
err := configKey.Validate()
if err != nil {
errs = append(errs, fmt.Errorf("present dogu config key invalid: %w", err))
}

// validate that all keys are of the same dogu
if referencedDoguName != configKey.DoguName {
errs = append(errs, fmt.Errorf("present %s does not match superordinate dogu name %q", configKey, referencedDoguName))
}
}

for _, configKey := range config.Absent {
err := configKey.Validate()
if err != nil {
errs = append(errs, fmt.Errorf("absent dogu config key invalid: %w", err))
}

// absent keys cannot be present
_, isPresent := config.Present[configKey]
if isPresent {
errs = append(errs, fmt.Errorf("%s cannot be present and absent at the same time", configKey))
}

// validate that all keys are of the same dogu
if referencedDoguName != configKey.DoguName {
errs = append(errs, fmt.Errorf("absent %s does not match superordinate dogu name %q", configKey, referencedDoguName))
}
}

absentDuplicates := util.GetDuplicates(config.Absent)
if len(absentDuplicates) > 0 {
errs = append(errs, fmt.Errorf("absent dogu config should not contain duplicate keys: %v", absentDuplicates))
}

return errors.Join(errs...)
}

func (config GlobalConfig) validate() error {
var errs []error
for configKey := range config.Present {

// empty key is not allowed
if string(configKey) == "" {
errs = append(errs, fmt.Errorf("key for present global config should not be empty"))
}
}

for _, configKey := range config.Absent {

// empty key is not allowed
if string(configKey) == "" {
errs = append(errs, fmt.Errorf("key for absent global config should not be empty"))
}

// absent keys cannot be present
_, isPresent := config.Present[configKey]
if isPresent {
errs = append(errs, fmt.Errorf("global config key %q cannot be present and absent at the same time", configKey))
}
}

absentDuplicates := util.GetDuplicates(config.Absent)
if len(absentDuplicates) > 0 {
errs = append(errs, fmt.Errorf("absent global config should not contain duplicate keys: %v", absentDuplicates))
}

return errors.Join(errs...)
}
Loading

0 comments on commit 3022bd0

Please sign in to comment.