Skip to content

Commit

Permalink
#1 Add blueprint v2 from k8s-dogu-operator
Browse files Browse the repository at this point in the history
  • Loading branch information
ppxl committed Jan 16, 2025
1 parent 9a46660 commit 46b2cc0
Show file tree
Hide file tree
Showing 16 changed files with 1,292 additions and 0 deletions.
29 changes: 29 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module github.com/cloudogu/blueprint-lib

go 1.23.4

require (
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/pkg/errors v0.9.1
github.com/stretchr/testify v1.10.0
)

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
github.com/gammazero/toposort v0.1.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
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
)
95 changes: 95 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0=
github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/cloudogu/ces-commons-lib v0.2.0 h1:yOEZWFl4W9N3J/6fok4svE3UufK5GQQtyxvwtIF5AdM=
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=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/eapache/go-resiliency v1.7.0 h1:n3NRTnBn5N0Cbi/IeOHuQn9s2UwVUH7Ga0ZWcP+9JTA=
github.com/eapache/go-resiliency v1.7.0/go.mod h1:5yPzW0MIvSe0JDsv0v+DvcjEv2FyD6iZYSs1ZI+iQho=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
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=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY=
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/apimachinery v0.31.2 h1:i4vUt2hPK56W6mlT7Ry+AO8eEsyxMD1U44NR22CLTYw=
k8s.io/apimachinery v0.31.2/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
18 changes: 18 additions & 0 deletions v2/blueprint.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package v2

// Blueprint describes an abstraction of CES components that should be absent or present within one or more CES
// instances. When the same Blueprint is applied to two different CES instances it is required to leave two equal
// instances in terms of the components.
//
// In general additions without changing the version are fine, as long as they don't change semantics. Removal or
// renaming are breaking changes and require a new blueprint API version.
type Blueprint struct {
// 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 []Dogu
// Components contains a set of exact components versions which should be present or absent in the CES instance after which
// this blueprint was applied. Optional.
Components []Component
// Config contains all config entries to set via blueprint.
Config Config
}
10 changes: 10 additions & 0 deletions v2/blueprintMask.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package v2

// BlueprintMask describes an abstraction of CES components that should alter a blueprint definition before
// applying it to a CES system via a blueprint upgrade. The blueprint mask does not change the blueprint
// itself, but is applied to the information in it to generate a new, effective blueprint.
type BlueprintMask struct {
// Dogus contains a set of dogus which alters the states of the dogus in the blueprint this mask is applied on.
// The names and target states of all dogus must not be empty.
Dogus []MaskDogu
}
37 changes: 37 additions & 0 deletions v2/component.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
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
// after a blueprint was applied.
type Component struct {
// Name defines the name and namespace of the component. Must not be empty.
Name QualifiedComponentName
// Version defines the version of the package 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 *semver.Version
// 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)
}
52 changes: 52 additions & 0 deletions v2/componentName.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package v2

import (
"errors"
"fmt"
"strings"
)

type QualifiedComponentName struct {
Namespace ComponentNamespace
SimpleName SimpleComponentName
}

type ComponentNamespace string
type SimpleComponentName string

func NewQualifiedComponentName(namespace ComponentNamespace, simpleName SimpleComponentName) (QualifiedComponentName, error) {
componentName := QualifiedComponentName{Namespace: namespace, SimpleName: simpleName}
err := componentName.Validate()
if err != nil {
return QualifiedComponentName{}, err
}
return QualifiedComponentName{Namespace: namespace, SimpleName: simpleName}, nil
}

func (componentName QualifiedComponentName) Validate() error {
var errorList []error
if componentName.Namespace == "" {
errorList = append(errorList, fmt.Errorf("namespace of component %q must not be empty", componentName.SimpleName))
}
if componentName.SimpleName == "" {
errorList = append(errorList, fmt.Errorf("component name must not be empty: '%s/%s'", componentName.Namespace, componentName.SimpleName))
}
return errors.Join(errorList...)
}

// String returns the component name with namespace, e.g. k8s/k8s-dogu-operator
func (componentName QualifiedComponentName) String() string {
return fmt.Sprintf("%s/%s", componentName.Namespace, componentName.SimpleName)
}

// QualifiedComponentNameFromString converts a qualified component as a string, e.g. "k8s/k8s-dogu-operator", to a dedicated QualifiedComponentName or raises an error if this is not possible.
func QualifiedComponentNameFromString(qualifiedName string) (QualifiedComponentName, error) {
splitName := strings.Split(qualifiedName, "/")
if len(splitName) != 2 {
return QualifiedComponentName{}, fmt.Errorf("component name needs to be in the form 'namespace/component' but is '%s'", qualifiedName)
}
return NewQualifiedComponentName(
ComponentNamespace(splitName[0]),
SimpleComponentName(splitName[1]),
)
}
31 changes: 31 additions & 0 deletions v2/componentName_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package v2

import (
"fmt"
"testing"

"github.com/stretchr/testify/assert"
)

func TestQualifiedComponentNameFromString(t *testing.T) {
tests := []struct {
test string
given string
expected QualifiedComponentName
wantErr assert.ErrorAssertionFunc
}{
{test: "ok", given: "k8s/k8s-dogu-operator", expected: QualifiedComponentName{ComponentNamespace("k8s"), SimpleComponentName("k8s-dogu-operator")}, wantErr: assert.NoError},
{test: "no ns", given: "k8s-dogu-operator", expected: QualifiedComponentName{}, wantErr: assert.Error},
{test: "no name", given: "k8s/", expected: QualifiedComponentName{}, wantErr: assert.Error},
{test: "double namespace", given: "k8s/test/k8s-dogu-operator", expected: QualifiedComponentName{}, wantErr: assert.Error},
}
for _, tt := range tests {
t.Run(tt.test, func(t *testing.T) {
got, err := QualifiedComponentNameFromString(tt.given)
if !tt.wantErr(t, err, fmt.Sprintf("TestQualifiedComponentNameFromString(%v)", tt.given)) {
return
}
assert.Equalf(t, tt.expected, got, "TestQualifiedComponentNameFromString(%v)", tt.given)
})
}
}
79 changes: 79 additions & 0 deletions v2/component_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package v2

import (
"testing"

"github.com/Masterminds/semver/v3"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/cloudogu/cesapp-lib/core"
)

var (
compVersion123 = semver.MustParse("1.2.3")
version123, _ = core.ParseVersion("1.2.3")
)

func TestComponent_Validate(t *testing.T) {
t.Run("errorOnMissingComponentVersion", func(t *testing.T) {
component := Component{Name: testComponentName, TargetState: TargetStatePresent}

err := component.Validate()

require.Error(t, err)
assert.Contains(t, err.Error(), `version of component "k8s/my-component" must not be empty`)
})

t.Run("errorOnEmptyComponentVersion", func(t *testing.T) {
component := Component{Name: testComponentName, Version: nil, TargetState: TargetStatePresent}

err := component.Validate()

require.Error(t, err)
assert.Contains(t, err.Error(), "version of component \"k8s/my-component\" must not be empty")
})

t.Run("errorOnMissingComponentName", func(t *testing.T) {
component := Component{Version: compVersion123, TargetState: TargetStatePresent}

err := component.Validate()

require.Error(t, err)
assert.Contains(t, err.Error(), "component name must not be empty")
})

t.Run("errorOnEmptyComponentNamespace", func(t *testing.T) {
component := Component{Name: v2.QualifiedComponentName{Namespace: "", SimpleName: "test"}, Version: compVersion123, TargetState: TargetStatePresent}
err := component.Validate()

require.Error(t, err)
assert.Contains(t, err.Error(), "namespace of component \"test\" must not be empty")
})

t.Run("errorOnEmptyComponentName", func(t *testing.T) {
component := Component{Name: v2.QualifiedComponentName{Namespace: "k8s"}, Version: compVersion123, TargetState: TargetStatePresent}

err := component.Validate()

require.Error(t, err)
assert.Contains(t, err.Error(), "component name must not be empty")
})

t.Run("emptyComponentStateDefaultsToPresent", func(t *testing.T) {
component := Component{Name: testComponentName, Version: compVersion123}

err := component.Validate()

require.NoError(t, err)
assert.Equal(t, TargetState(TargetStatePresent), component.TargetState)
})

t.Run("missingComponentVersionOkayForAbsent", func(t *testing.T) {
component := Component{Name: testComponentName, TargetState: TargetStateAbsent}

err := component.Validate()

require.NoError(t, err)
})
}
Loading

0 comments on commit 46b2cc0

Please sign in to comment.