Skip to content

Commit

Permalink
#4 reuse targetDogu and targetComponent for blueprint and effective b…
Browse files Browse the repository at this point in the history
…lueprint
  • Loading branch information
alexander-dammeier committed Dec 18, 2023
1 parent fb6b2e0 commit f6fc455
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 226 deletions.
13 changes: 7 additions & 6 deletions pkg/adapter/kubernetes/blueprintSpecCRRepository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"github.com/cloudogu/k8s-blueprint-operator/pkg/adapter/serializer"
"github.com/cloudogu/k8s-blueprint-operator/pkg/adapter/serializer/blueprintMaskV1"
"github.com/cloudogu/k8s-blueprint-operator/pkg/adapter/serializer/blueprintV2"
"github.com/cloudogu/k8s-blueprint-operator/pkg/adapter/serializer/effectiveBlueprintV1"
Expand Down Expand Up @@ -152,8 +153,8 @@ func Test_blueprintSpecRepo_Update(t *testing.T) {
Status: v1.BlueprintStatus{
Phase: domain.StatusPhaseValidated,
EffectiveBlueprint: effectiveBlueprintV1.EffectiveBlueprintV1{
Dogus: []effectiveBlueprintV1.TargetDogu{},
Components: []effectiveBlueprintV1.TargetComponent{},
Dogus: []serializer.TargetDogu{},
Components: []serializer.TargetComponent{},
RegistryConfig: map[string]string{},
RegistryConfigAbsent: []string{},
RegistryConfigEncrypted: map[string]string{},
Expand Down Expand Up @@ -235,8 +236,8 @@ func Test_blueprintSpecRepo_Update(t *testing.T) {
Status: v1.BlueprintStatus{
Phase: domain.StatusPhaseValidated,
EffectiveBlueprint: effectiveBlueprintV1.EffectiveBlueprintV1{
Dogus: []effectiveBlueprintV1.TargetDogu{},
Components: []effectiveBlueprintV1.TargetComponent{},
Dogus: []serializer.TargetDogu{},
Components: []serializer.TargetComponent{},
RegistryConfig: map[string]string{},
RegistryConfigAbsent: []string{},
RegistryConfigEncrypted: map[string]string{},
Expand Down Expand Up @@ -287,8 +288,8 @@ func Test_blueprintSpecRepo_Update(t *testing.T) {
Status: v1.BlueprintStatus{
Phase: domain.StatusPhaseValidated,
EffectiveBlueprint: effectiveBlueprintV1.EffectiveBlueprintV1{
Dogus: []effectiveBlueprintV1.TargetDogu{},
Components: []effectiveBlueprintV1.TargetComponent{},
Dogus: []serializer.TargetDogu{},
Components: []serializer.TargetComponent{},
RegistryConfig: map[string]string{},
RegistryConfigAbsent: []string{},
RegistryConfigEncrypted: map[string]string{},
Expand Down
112 changes: 8 additions & 104 deletions pkg/adapter/serializer/blueprintV2/blueprintV2.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package blueprintV2
import (
"errors"
"fmt"
"github.com/cloudogu/cesapp-lib/core"
"github.com/cloudogu/k8s-blueprint-operator/pkg/adapter/serializer"
"github.com/cloudogu/k8s-blueprint-operator/pkg/domain"
"github.com/cloudogu/k8s-blueprint-operator/pkg/util"
Expand All @@ -19,10 +18,10 @@ type BlueprintV2 struct {
serializer.GeneralBlueprint
// Dogus contains a set of exact dogu versions which should be present or absent in the CES instance after which this
// blueprint was applied. Optional.
Dogus []TargetDogu `json:"dogus,omitempty"`
Dogus []serializer.TargetDogu `json:"dogus,omitempty"`
// Packages contains a set of exact package versions which should be present or absent in the CES instance after which
// this blueprint was applied. The packages must correspond to the used operation system package manager. Optional.
Components []TargetComponent `json:"components,omitempty"`
Components []serializer.TargetComponent `json:"components,omitempty"`
// Used to configure registry globalRegistryEntries on blueprint upgrades
RegistryConfig RegistryConfig `json:"registryConfig,omitempty"`
// Used to remove registry globalRegistryEntries on blueprint upgrades
Expand All @@ -33,43 +32,21 @@ type BlueprintV2 struct {

type RegistryConfig map[string]map[string]interface{}

// TargetDogu defines a Dogu, its version, and the installation state in which it is supposed to be after a blueprint
// was applied.
type TargetDogu struct {
// Name defines the name of the dogu including its namespace, f. i. "official/nginx". Must not be empty.
Name string `json:"name"`
// Version defines the version of the dogu that is to be installed. Must not be empty if the targetState is "present";
// otherwise it is optional and is not going to be interpreted.
Version string `json:"version"`
// TargetState defines a state of installation of this dogu. Optional field, but defaults to "TargetStatePresent"
TargetState string `json:"targetState"`
}

type TargetComponent struct {
// Name defines the name of the component including its namespace, f. i. "official/nginx". Must not be empty.
Name string `json:"name"`
// Version defines the version of the dogu that is to be installed. Must not be empty if the targetState is "present";
// otherwise it is optional and is not going to be interpreted.
Version string `json:"version"`
// TargetState defines a state of installation of this component. Optional field, but defaults to "TargetStatePresent"
TargetState string `json:"targetState"`
}

func ConvertToBlueprintV2(blueprint domain.Blueprint) (BlueprintV2, error) {
var errorList []error
convertedDogus := util.Map(blueprint.Dogus, func(dogu domain.Dogu) TargetDogu {
convertedDogus := util.Map(blueprint.Dogus, func(dogu domain.Dogu) serializer.TargetDogu {
newState, err := serializer.ToSerializerTargetState(dogu.TargetState)
errorList = append(errorList, err)
return TargetDogu{
return serializer.TargetDogu{
Name: dogu.GetQualifiedName(),
Version: dogu.Version.Raw,
TargetState: newState,
}
})
convertedComponents := util.Map(blueprint.Components, func(component domain.Component) TargetComponent {
convertedComponents := util.Map(blueprint.Components, func(component domain.Component) serializer.TargetComponent {
newState, err := serializer.ToSerializerTargetState(component.TargetState)
errorList = append(errorList, err)
return TargetComponent{
return serializer.TargetComponent{
Name: component.Name,
Version: component.Version.Raw,
TargetState: newState,
Expand Down Expand Up @@ -100,8 +77,8 @@ func convertToBlueprint(blueprint BlueprintV2) (domain.Blueprint, error) {
default:
return domain.Blueprint{}, fmt.Errorf("unsupported Blueprint API Version: %s", blueprint.API)
}
convertedDogus, doguErr := convertDogus(blueprint.Dogus)
convertedComponents, compErr := convertComponents(blueprint.Components)
convertedDogus, doguErr := serializer.ConvertDogus(blueprint.Dogus)
convertedComponents, compErr := serializer.ConvertComponents(blueprint.Components)
err := errors.Join(doguErr, compErr)
if err != nil {
return domain.Blueprint{}, fmt.Errorf("syntax of blueprintV2 is not correct: %w", err)
Expand All @@ -114,76 +91,3 @@ func convertToBlueprint(blueprint BlueprintV2) (domain.Blueprint, error) {
RegistryConfigEncrypted: domain.RegistryConfig(blueprint.RegistryConfigEncrypted),
}, nil
}

func convertDogus(dogus []TargetDogu) ([]domain.Dogu, error) {
var convertedDogus []domain.Dogu
var errorList []error

for _, dogu := range dogus {
doguNamespace, doguName, err := serializer.SplitDoguName(dogu.Name)
if err != nil {
errorList = append(errorList, err)
continue
}
newState, err := serializer.ToDomainTargetState(dogu.TargetState)
if err != nil {
errorList = append(errorList, err)
continue
}
var version core.Version
if dogu.Version != "" {
version, err = core.ParseVersion(dogu.Version)
if err != nil {
errorList = append(errorList, fmt.Errorf("could not parse version of target dogu %q: %w", dogu.Name, err))
continue
}
}
convertedDogus = append(convertedDogus, domain.Dogu{
Namespace: doguNamespace,
Name: doguName,
Version: version,
TargetState: newState,
})
}

err := errors.Join(errorList...)
if err != nil {
return convertedDogus, fmt.Errorf("cannot convert blueprint dogus: %w", err)
}

return convertedDogus, err
}

func convertComponents(components []TargetComponent) ([]domain.Component, error) {
var convertedComponents []domain.Component
var errorList []error

for _, component := range components {
newState, err := serializer.ToDomainTargetState(component.TargetState)
errorList = append(errorList, err)
if err != nil {
errorList = append(errorList, err)
continue
}
var version core.Version
if component.Version != "" {
version, err = core.ParseVersion(component.Version)
if err != nil {
errorList = append(errorList, fmt.Errorf("could not parse version of target component %q: %w", component.Name, err))
continue
}
}
convertedComponents = append(convertedComponents, domain.Component{
Name: component.Name,
Version: version,
TargetState: newState,
})
}

err := errors.Join(errorList...)
if err != nil {
return convertedComponents, fmt.Errorf("cannot convert blueprint components: %w", err)
}

return convertedComponents, err
}
12 changes: 6 additions & 6 deletions pkg/adapter/serializer/blueprintV2/blueprintV2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ func Test_ConvertToBlueprintV2(t *testing.T) {

blueprintV2, err := ConvertToBlueprintV2(blueprint)

convertedDogus := []TargetDogu{
convertedDogus := []serializer.TargetDogu{
{Name: "absent/dogu1", Version: version3_2_1_1.Raw, TargetState: "absent"},
{Name: "absent/dogu2", TargetState: "absent"},
{Name: "present/dogu3", Version: version3_2_1_2.Raw, TargetState: "present"},
{Name: "present/dogu4", Version: version1_2_3_3.Raw, TargetState: "present"},
}

convertedComponents := []TargetComponent{
convertedComponents := []serializer.TargetComponent{
{Name: "component1", Version: version3_2_1_1.Raw, TargetState: "absent"},
{Name: "absent/component2", TargetState: "absent"},
{Name: "present-component3", Version: version3_2_1_2.Raw, TargetState: "present"},
Expand All @@ -81,14 +81,14 @@ func Test_ConvertToBlueprintV2(t *testing.T) {
}

func Test_ConvertToBlueprint(t *testing.T) {
dogus := []TargetDogu{
dogus := []serializer.TargetDogu{
{Name: "absent/dogu1", Version: version3_2_1_1.Raw, TargetState: "absent"},
{Name: "absent/dogu2", TargetState: "absent"},
{Name: "present/dogu3", Version: version3_2_1_2.Raw, TargetState: "present"},
{Name: "present/dogu4", Version: version1_2_3_3.Raw},
}

components := []TargetComponent{
components := []serializer.TargetComponent{
{Name: "component1", Version: version3_2_1_1.Raw, TargetState: "absent"},
{Name: "absent/component2", TargetState: "absent"},
{Name: "present-component3", Version: version3_2_1_2.Raw, TargetState: "present"},
Expand Down Expand Up @@ -149,13 +149,13 @@ func Test_ConvertToBlueprint(t *testing.T) {
func Test_ConvertToBlueprint_errors(t *testing.T) {
blueprintV2 := BlueprintV2{
GeneralBlueprint: serializer.GeneralBlueprint{API: serializer.V2},
Dogus: []TargetDogu{
Dogus: []serializer.TargetDogu{
{Name: "dogu1", Version: version3_2_1_1.Raw},
{Name: "official/dogu1", Version: version3_2_1_1.Raw, TargetState: "unknown"},
{Name: "name/space/dogu2", Version: version3_2_1_2.Raw},
{Name: "official/dogu3", Version: "abc"},
},
Components: []TargetComponent{
Components: []serializer.TargetComponent{
{Name: "component1", Version: version3_2_1_1.Raw, TargetState: "not known state"},
{Name: "official/dogu3", Version: "abc"},
},
Expand Down
Loading

0 comments on commit f6fc455

Please sign in to comment.