diff --git a/.golangci.yml b/.golangci.yml index f5455f0d..4891b55e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -32,6 +32,7 @@ linters-settings: - github.com/onsi/ginkgo/v2 - github.com/openshift-kni/eco-gosystem/tests/internal/inittools - github.com/openshift-kni/eco-gosystem/tests/ran-du/internal/randuinittools + - github.com/openshift-kni/eco-gosystem/tests/imagebasedupgrade/internal/imagebasedupgradeinittools # Select the Go version to target. The default is '1.13'. go: "1.19" # https://staticcheck.io/docs/options#checks @@ -117,6 +118,10 @@ issues: linters: - gochecknoinits + - path: 'tests/imagebasedupgrade/internal/imagebasedupgradeinittools' + linters: + - gochecknoinits + - path: "tests/.*/tests/.*" linters: - depguard diff --git a/go.mod b/go.mod index e80bb771..b4822abe 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/onsi/ginkgo/v2 v2.13.2 github.com/onsi/gomega v1.30.0 github.com/openshift-kni/cluster-group-upgrades-operator v0.0.0-20231216054307-28180628cf50 - github.com/openshift-kni/eco-goinfra v0.0.0-20240109203119-975bf2617254 + github.com/openshift-kni/eco-goinfra v0.0.0-20240119165249-4757abb333e9 github.com/openshift-kni/k8sreporter v1.0.5 github.com/openshift/cluster-node-tuning-operator v0.0.0-20231225123609-e63d2c9626fe gonum.org/v1/gonum v0.14.0 @@ -108,6 +108,7 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/nmstate/kubernetes-nmstate/api v0.0.0-20231116153922-80c6e01df02e // indirect + github.com/openshift-kni/lifecycle-agent v0.0.0-20240109211418-4489c4a1eb46 // indirect github.com/openshift/api v3.9.1-0.20190916204813-cdbe64fb0c91+incompatible // indirect github.com/openshift/assisted-service/api v0.0.0 // indirect github.com/openshift/assisted-service/models v0.0.0 // indirect @@ -115,7 +116,7 @@ require ( github.com/openshift/cluster-nfd-operator v0.0.0-20231206145954-f49a827bf617 // indirect github.com/openshift/custom-resource-status v1.1.3-0.20220503160415-f2fdb4999d87 // indirect github.com/openshift/hive/apis v0.0.0-20220222213051-def9088fdb5a // indirect - github.com/openshift/library-go v0.0.0-20231020125025-211b32f1a1f2 // indirect + github.com/openshift/library-go v0.0.0-20231027143522-b8cd45d2d2c8 // indirect github.com/openshift/local-storage-operator v0.0.0-20231220121151-4e580bd14c46 // indirect github.com/openshift/machine-config-operator v0.0.1-0.20230807154212-886c5c3fc7a9 // indirect github.com/openshift/ptp-operator v0.0.0-20231220185604-29113b41981b // indirect diff --git a/go.sum b/go.sum index 17c74ac1..9746fbf8 100644 --- a/go.sum +++ b/go.sum @@ -1167,10 +1167,12 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI= github.com/openshift-kni/cluster-group-upgrades-operator v0.0.0-20231216054307-28180628cf50 h1:0Lw0f9ncgoXKo1JnQrEo4fGqYelTV+5huXzJvziDG9E= github.com/openshift-kni/cluster-group-upgrades-operator v0.0.0-20231216054307-28180628cf50/go.mod h1:vfydLuqf4QsLXI5busOIjbuvvURuE0oeLCwjvXj34Mo= -github.com/openshift-kni/eco-goinfra v0.0.0-20240109203119-975bf2617254 h1:RF35GGZ0Y7bQRClgtHq0a9/X03mIOvBB2hPJrWQjOMI= -github.com/openshift-kni/eco-goinfra v0.0.0-20240109203119-975bf2617254/go.mod h1:glATkU/NliNAZZTGgFwY0rTJhrcHnXE+jjAjgQAKoNQ= +github.com/openshift-kni/eco-goinfra v0.0.0-20240119165249-4757abb333e9 h1:0WaeqNRsT7zMpGDwAlThZ6K5it7ipXAphC+/WQ8w6UQ= +github.com/openshift-kni/eco-goinfra v0.0.0-20240119165249-4757abb333e9/go.mod h1:/3PLkMxhTHtSp10aD0jD72tXgngD6x8WPWoZdlaEpmc= github.com/openshift-kni/k8sreporter v1.0.5 h1:1GYBc/BTZyVoXilHef43v9A8BSzw700zAPZ6zsZvo6Y= github.com/openshift-kni/k8sreporter v1.0.5/go.mod h1:fg8HI9yxiKAi6UzR6NTtrmQmA2WKzUqmkRUHwQ1+Bj8= +github.com/openshift-kni/lifecycle-agent v0.0.0-20240109211418-4489c4a1eb46 h1:I6ZcMvy98fAzd/5IySrli8inlMuUFfS0+LE57ln8lqs= +github.com/openshift-kni/lifecycle-agent v0.0.0-20240109211418-4489c4a1eb46/go.mod h1:+7AXvmYXtR4+UjvoMDeeRt4MrV32YK0uUHtHhEPn8MQ= github.com/openshift/api v0.0.0-20231115210901-4c4a0a24f2fc h1:VCR7TBU90EPmz1fjW1sqdVVpe5GmOHyJTTyQ5XmnmtE= github.com/openshift/api v0.0.0-20231115210901-4c4a0a24f2fc/go.mod h1:yimSGmjsI+XF1mr+AKBs2//fSXIOhhetHGbMlBEfXbs= github.com/openshift/assisted-service/api v0.0.0-20230907160625-4e1a1e59cef0 h1:JRsvPEsCDGSQxLGU0faqNjVXXyruURLb3mc4F8YstRw= @@ -1187,8 +1189,8 @@ github.com/openshift/custom-resource-status v1.1.3-0.20220503160415-f2fdb4999d87 github.com/openshift/custom-resource-status v1.1.3-0.20220503160415-f2fdb4999d87/go.mod h1:DB/Mf2oTeiAmVVX1gN+NEqweonAPY0TKUwADizj8+ZA= github.com/openshift/hive/apis v0.0.0-20220222213051-def9088fdb5a h1:E+XPJs/aVvYsrlJzo2ED38ZTR2RTNUlFMmOaFAAdMZg= github.com/openshift/hive/apis v0.0.0-20220222213051-def9088fdb5a/go.mod h1:E1bgquRiwfugdArdecPbpYIrAdve5kTzMaJb0+8jMXI= -github.com/openshift/library-go v0.0.0-20231020125025-211b32f1a1f2 h1:TWG/YVRhSvjYq8iIwJ2Wpoopgg0zuh+ZAl1RSm4J8Z0= -github.com/openshift/library-go v0.0.0-20231020125025-211b32f1a1f2/go.mod h1:ZFwNwC3opc/7aOvzUbU95zp33Lbxet48h80ryH3p6DY= +github.com/openshift/library-go v0.0.0-20231027143522-b8cd45d2d2c8 h1:5t2pHTyvfpy5xcKrLCj+6OITwIRdyH1CNG8Ob3vVJvc= +github.com/openshift/library-go v0.0.0-20231027143522-b8cd45d2d2c8/go.mod h1:8UzmrBMCn7+GzouL8DVYkL9COBQTB1Ggd13/mHJQCUg= github.com/openshift/local-storage-operator v0.0.0-20231220121151-4e580bd14c46 h1:ltEp1+e1U18KCi8E+879li1FHCC+Wz/kNUPX3Y2o95o= github.com/openshift/local-storage-operator v0.0.0-20231220121151-4e580bd14c46/go.mod h1:14iQ/wwY3MTQRMHe04Lvx8Zhbh7ESJSRsN40coqDRw8= github.com/openshift/machine-config-operator v0.0.1-0.20230807154212-886c5c3fc7a9 h1:lEH5TQGyDjnJZocsI4FE0BcWKkKtqW3OOsBkRvGd9Rs= diff --git a/tests/imagebasedupgrade/imagebasedupgrade_suite_test.go b/tests/imagebasedupgrade/imagebasedupgrade_suite_test.go new file mode 100644 index 00000000..88be5b1b --- /dev/null +++ b/tests/imagebasedupgrade/imagebasedupgrade_suite_test.go @@ -0,0 +1,14 @@ +package imagebasedupgrade_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + _ "github.com/openshift-kni/eco-gosystem/tests/imagebasedupgrade/tests" +) + +func TestImageBasedUpgrade(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "ImageBasedUpgrade Suite") +} diff --git a/tests/imagebasedupgrade/internal/imagebasedupgradeinittools/imagebasedupgradeinittools.go b/tests/imagebasedupgrade/internal/imagebasedupgradeinittools/imagebasedupgradeinittools.go new file mode 100644 index 00000000..c11fb01d --- /dev/null +++ b/tests/imagebasedupgrade/internal/imagebasedupgradeinittools/imagebasedupgradeinittools.go @@ -0,0 +1,49 @@ +package imagebasedupgradeinittools + +import ( + "os" + + "github.com/golang/glog" + "github.com/openshift-kni/eco-goinfra/pkg/clients" + "github.com/openshift-kni/eco-gosystem/tests/imagebasedupgrade/internal/imagebasedupgradeparams" + "github.com/openshift-kni/eco-gosystem/tests/internal/inittools" +) + +var ( + // SeedHubAPIClient is the api client to the hub cluster. + SeedHubAPIClient *clients.Settings + // TargetHubAPIClient is the api client to the hub cluster. + TargetHubAPIClient *clients.Settings + // SeedSNOAPIClient is the api client to the seed SNO cluster. + SeedSNOAPIClient *clients.Settings + // TargetSNOAPIClient is the api client to the target SNO cluster. + TargetSNOAPIClient *clients.Settings +) + +// init loads all variables automatically when this package is imported. Once package is imported a user has full +// access to all vars within init function. It is recommended to import this package using dot import. +func init() { + SeedHubAPIClient = inittools.APIClient + TargetHubAPIClient = inittools.APIClient + SeedSNOAPIClient = DefineAPIClient(imagebasedupgradeparams.SeedSNOKubeEnvKey) + TargetSNOAPIClient = DefineAPIClient(imagebasedupgradeparams.TargetSNOKubeEnvKey) +} + +// DefineAPIClient creates new api client instance connected to given cluster. +func DefineAPIClient(kubeconfigEnvVar string) *clients.Settings { + kubeFilePath, present := os.LookupEnv(kubeconfigEnvVar) + if !present { + glog.Fatalf("can not load api client. Please check %s env var", kubeconfigEnvVar) + + return nil + } + + client := clients.New(kubeFilePath) + if client == nil { + glog.Fatalf("client is not set please check %s env variable", kubeconfigEnvVar) + + return nil + } + + return client +} diff --git a/tests/imagebasedupgrade/internal/imagebasedupgradeparams/const.go b/tests/imagebasedupgrade/internal/imagebasedupgradeparams/const.go new file mode 100644 index 00000000..4ecbc57d --- /dev/null +++ b/tests/imagebasedupgrade/internal/imagebasedupgradeparams/const.go @@ -0,0 +1,16 @@ +package imagebasedupgradeparams + +const ( + // SeedHubKubeEnvKey is the hub's kubeconfig env var. + SeedHubKubeEnvKey string = "KUBECONFIG_SEED_HUB" + // TargetHubKubeEnvKey is the hub's kubeconfig env var. + TargetHubKubeEnvKey string = "KUBECONFIG_TARGET_HUB" + // SeedSNOKubeEnvKey is the seed kubeconfig env var. + SeedSNOKubeEnvKey string = "KUBECONFIG_SEED_SNO" + // TargetSNOKubeEnvKey is the target kubeconfig env var. + TargetSNOKubeEnvKey string = "KUBECONFIG_TARGET_SNO" + // ImagebasedupgradeCrName is the Imagebasedupgrade CR name. + ImagebasedupgradeCrName string = "upgrade" + // ImagebasedupgradeCrNamespace is the Imagebasedupgrade CR namespace. + ImagebasedupgradeCrNamespace string = "openshift-lifecycle-agent" +) diff --git a/tests/imagebasedupgrade/tests/happy-path-upgrade.go b/tests/imagebasedupgrade/tests/happy-path-upgrade.go new file mode 100644 index 00000000..88ad9f8e --- /dev/null +++ b/tests/imagebasedupgrade/tests/happy-path-upgrade.go @@ -0,0 +1,55 @@ +package tests + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "github.com/openshift-kni/eco-goinfra/pkg/lca" + "github.com/openshift-kni/eco-goinfra/pkg/polarion" + "github.com/openshift-kni/eco-gosystem/tests/imagebasedupgrade/internal/imagebasedupgradeinittools" + "github.com/openshift-kni/eco-gosystem/tests/imagebasedupgrade/internal/imagebasedupgradeparams" +) + +// IbuCr is a dedicated var to use and act on it. +var IbuCr = lca.NewImageBasedUpgradeBuilder( + imagebasedupgradeinittools.TargetSNOAPIClient, imagebasedupgradeparams.ImagebasedupgradeCrName) + +var _ = Describe( + "HappyPathUpgrade", + Ordered, + ContinueOnFailure, + Label("HappyPathUpgrade"), func() { + BeforeAll(func() { + By("Generating seed image", func() { + // Test Automation Code Implementation is to be done. + }) + }) + + AfterAll(func() { + // Rollback to pre-upgrade state and reset PolicyGenTemplate. + }) + + It("End to end upgrade happy path", polarion.ID("68954"), Label("HappyPathUpgrade"), func() { + + By("Checking ImageBasedUpgrade CR exists with Idle stage in Target SNO", func() { + crExists := IbuCr.Exists() + Expect(crExists).To(BeTrue()) + }) + + By("Updating ImageBasedUpgrade CR with Prep stage in Target SNO", func() { + IbuCr.WithStage("Prep") + }) + + By("Updating ImageBasedUpgrade CR with Upgrade stage in Target SNO", func() { + IbuCr.WithStage("Upgrade") + }) + + By(" Verifying target SNO cluster ACM registration post upgrade", func() { + + }) + + By("Updating ImageBasedUpgrade CR with Idle stage in Target SNO", func() { + IbuCr.WithStage("Idle") + + }) + }) + }) diff --git a/vendor/github.com/openshift-kni/eco-goinfra/pkg/clients/clients.go b/vendor/github.com/openshift-kni/eco-goinfra/pkg/clients/clients.go index 3667680e..3458f184 100644 --- a/vendor/github.com/openshift-kni/eco-goinfra/pkg/clients/clients.go +++ b/vendor/github.com/openshift-kni/eco-goinfra/pkg/clients/clients.go @@ -44,6 +44,8 @@ import ( nmstatev1 "github.com/nmstate/kubernetes-nmstate/api/v1" nmstateV1alpha1 "github.com/nmstate/kubernetes-nmstate/api/v1alpha1" + lcasgv1alpha1 "github.com/openshift-kni/lifecycle-agent/api/seedgenerator/v1alpha1" + lcav1alpha1 "github.com/openshift-kni/lifecycle-agent/api/v1alpha1" operatorV1 "github.com/openshift/api/operator/v1" hiveextV1Beta1 "github.com/openshift/assisted-service/api/hiveextension/v1beta1" agentInstallV1Beta1 "github.com/openshift/assisted-service/api/v1beta1" @@ -190,6 +192,14 @@ func SetScheme(crScheme *runtime.Scheme) error { return err } + if err := lcav1alpha1.AddToScheme(crScheme); err != nil { + return err + } + + if err := lcasgv1alpha1.AddToScheme(crScheme); err != nil { + return err + } + if err := operatorV1.Install(crScheme); err != nil { return err } diff --git a/vendor/github.com/openshift-kni/eco-goinfra/pkg/lca/imagebasedupgrade.go b/vendor/github.com/openshift-kni/eco-goinfra/pkg/lca/imagebasedupgrade.go new file mode 100644 index 00000000..640e3f1b --- /dev/null +++ b/vendor/github.com/openshift-kni/eco-goinfra/pkg/lca/imagebasedupgrade.go @@ -0,0 +1,353 @@ +package lca + +import ( + "context" + "time" + + goclient "sigs.k8s.io/controller-runtime/pkg/client" + + "github.com/golang/glog" + + "fmt" + + "github.com/openshift-kni/eco-goinfra/pkg/clients" + "github.com/openshift-kni/eco-goinfra/pkg/msg" + lcav1alpha1 "github.com/openshift-kni/lifecycle-agent/api/v1alpha1" + + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" +) + +const ( + isTrue = "True" + isFalse = "False" + isComplete = "Completed" +) + +// ImageBasedUpgradeBuilder provides struct for the imagebasedupgrade object containing connection to +// the cluster and the imagebasedupgrade definitions. +type ImageBasedUpgradeBuilder struct { + // ImageBasedUpgrade definition. Used to store the imagebasedupgrade object. + Definition *lcav1alpha1.ImageBasedUpgrade + + // Created imagebasedupgrade object. + Object *lcav1alpha1.ImageBasedUpgrade + // Used in functions that define or mutate the imagebasedupgrade definition. + // errorMsg is processed before the imagebasedupgrade object is created + errorMsg string + apiClient *clients.Settings +} + +// AdditionalOptions additional options for imagebasedupgrade object. +type AdditionalOptions func(builder *ImageBasedUpgradeBuilder) (*ImageBasedUpgradeBuilder, error) + +// NewImageBasedUpgradeBuilder creates a new instance of ImageBasedUpgrade. +func NewImageBasedUpgradeBuilder( + apiClient *clients.Settings, + name string, +) *ImageBasedUpgradeBuilder { + builder := ImageBasedUpgradeBuilder{ + apiClient: apiClient, + Definition: &lcav1alpha1.ImageBasedUpgrade{ + ObjectMeta: metaV1.ObjectMeta{ + Name: name, + }, + }, + } + + if name == "" { + glog.V(100).Infof("The name of the imagebasedupgrade is empty") + + builder.errorMsg = "ImageBasedUpgrade name cannot be empty" + } + + return &builder +} + +// WithOptions creates imagebasedupgrade with generic mutation options. +func (builder *ImageBasedUpgradeBuilder) WithOptions(options ...AdditionalOptions) *ImageBasedUpgradeBuilder { + if valid, _ := builder.validate(); !valid { + return builder + } + + glog.V(100).Infof("Setting imagebasedupgrade additional options") + + for _, option := range options { + if option != nil { + builder, err := option(builder) + + if err != nil { + glog.V(100).Infof("Error occurred in mutation function") + + builder.errorMsg = err.Error() + + return builder + } + } + } + + return builder +} + +// PullImageBasedUpgrade pulls existing imagebasedupgrade from cluster. +func PullImageBasedUpgrade(apiClient *clients.Settings, name string) (*ImageBasedUpgradeBuilder, error) { + glog.V(100).Infof("Pulling existing imagebasedupgrade name %s from cluster", name) + + builder := ImageBasedUpgradeBuilder{ + apiClient: apiClient, + Definition: &lcav1alpha1.ImageBasedUpgrade{ + ObjectMeta: metaV1.ObjectMeta{ + Name: name, + }, + }, + } + + if name == "" { + glog.V(100).Infof("The name of the imagebasedupgrade is empty") + + builder.errorMsg = "imagebasedupgrade 'name' cannot be empty" + } + + if !builder.Exists() { + return nil, fmt.Errorf("imagebasedupgrade object %s doesn't exist", name) + } + + builder.Definition = builder.Object + + return &builder, nil +} + +// Update modifies the imagebasedupgrade resource on the cluster +// to match what is defined in the local definition of the builder. +func (builder *ImageBasedUpgradeBuilder) Update() (*ImageBasedUpgradeBuilder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Updating imagebasedupgrade %s", + builder.Definition.Name) + + if !builder.Exists() { + glog.V(100).Infof("imagebasedupgrade %s does not exist", + builder.Definition.Name) + + builder.errorMsg = "Unable to update non-existing imagebasedupgrade" + } + + if builder.errorMsg != "" { + return nil, fmt.Errorf(builder.errorMsg) + } + + err := builder.apiClient.Update(context.TODO(), builder.Definition) + if err == nil { + builder.Object = builder.Definition + } + + return builder, err +} + +// Delete removes the existing imagebasedupgrade from a cluster. +// Note that a new imagebasedupgrade with the specs from the deleted +// one is created instantly upon deletion. +func (builder *ImageBasedUpgradeBuilder) Delete() (*ImageBasedUpgradeBuilder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Deleting the imagebasedupgrade %s", + builder.Definition.Name) + + if !builder.Exists() { + return builder, fmt.Errorf("imagebasedupgrade cannot be deleted because it does not exist") + } + + err := builder.apiClient.Delete(context.TODO(), builder.Definition) + + if err != nil { + return builder, fmt.Errorf("can not delete imagebasedupgrade: %w", err) + } + + builder.Object = nil + + return builder, nil +} + +// Get returns imagebasedupgrade object if found. +func (builder *ImageBasedUpgradeBuilder) Get() (*lcav1alpha1.ImageBasedUpgrade, error) { + if valid, err := builder.validate(); !valid { + return nil, err + } + + glog.V(100).Infof("Getting imagebasedupgrade %s", + builder.Definition.Name) + + imagebasedupgrade := &lcav1alpha1.ImageBasedUpgrade{} + err := builder.apiClient.Get(context.TODO(), goclient.ObjectKey{ + Name: builder.Definition.Name, + }, imagebasedupgrade) + + if err != nil { + return nil, err + } + + return imagebasedupgrade, err +} + +// Exists checks whether the given imagebasedupgrade exists. +func (builder *ImageBasedUpgradeBuilder) Exists() bool { + if valid, _ := builder.validate(); !valid { + return false + } + + glog.V(100).Infof("Checking if imagebasedupgrade %s", + builder.Definition.Name) + + var err error + builder.Object, err = builder.Get() + + return err == nil || !k8serrors.IsNotFound(err) +} + +// WithSeedImage sets the seed image used by the imagebasedupgrade. +func (builder *ImageBasedUpgradeBuilder) WithSeedImage( + seedImage string) *ImageBasedUpgradeBuilder { + if valid, _ := builder.validate(); !valid { + return builder + } + + glog.V(100).Infof("Setting image %s in imagebasedupgrade", seedImage) + + builder.Definition.Spec.SeedImageRef.Image = seedImage + + return builder +} + +// WithSeedImageVersion sets the seed image version used by the imagebasedupgrade. +func (builder *ImageBasedUpgradeBuilder) WithSeedImageVersion( + seedImageVersion string) *ImageBasedUpgradeBuilder { + if valid, _ := builder.validate(); !valid { + return builder + } + + glog.V(100).Infof("Setting seed image version %s in imagebasedupgrade", seedImageVersion) + + builder.Definition.Spec.SeedImageRef.Version = seedImageVersion + + return builder +} + +// WaitUntilStageComplete waits the specified timeout for the imagebasedupgrade to complete +// actions for the provided stage . +func (builder *ImageBasedUpgradeBuilder) WaitUntilStageComplete(stage string) (*ImageBasedUpgradeBuilder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Waiting for imagebasedupgrade %s to set stage %s", + builder.Definition.Name, + stage) + + if !builder.Exists() { + glog.V(100).Infof("The imagebasedupgrade does not exist on the cluster") + + return builder, fmt.Errorf(builder.errorMsg) + } + + // Polls periodically to determine if imagebasedupgrade is in desired state. + var err error + err = wait.PollUntilContextTimeout( + context.TODO(), time.Second*3, time.Minute*30, true, func(ctx context.Context) (bool, error) { + builder.Object, err = builder.Get() + + if err != nil { + return false, nil + } + + for _, condition := range builder.Object.Status.Conditions { + switch stage { + case "Idle": + if condition.Status == isTrue && condition.Type == "Idle" { + return true, nil + } + + case "Prep": + if condition.Status == isFalse && condition.Type == "PrepInProgress" && + condition.Message == "Prep completed" && condition.Reason == isComplete { + return true, nil + + } + case "Upgrade": + if condition.Status == isFalse && condition.Type == "UpgradeInProgress" && + condition.Message == "Upgrade completed" && condition.Reason == isComplete { + return true, nil + } + + case "Rollback": + if condition.Status == isFalse && condition.Type == "RollbackInProgress" && + condition.Message == "Rollback completed" && condition.Reason == isComplete { + return true, nil + } + + default: + return false, fmt.Errorf("wrong stage selected for imagebasedupgrade") + + } + + } + + return false, nil + + }) + + if err == nil { + return builder, nil + } + + return nil, err +} + +// WithStage sets the stage used by the imagebasedupgrade. +func (builder *ImageBasedUpgradeBuilder) WithStage( + stage string) *ImageBasedUpgradeBuilder { + if valid, _ := builder.validate(); !valid { + return builder + } + + glog.V(100).Infof("Setting stage %s in imagebasedupgrade", stage) + builder.Definition.Spec.Stage = lcav1alpha1.ImageBasedUpgradeStage(stage) + + return builder +} + +// validate will check that the builder and builder definition are properly initialized before +// accessing any member fields. +func (builder *ImageBasedUpgradeBuilder) validate() (bool, error) { + resourceCRD := "ImageBasedUpgrade" + + if builder == nil { + glog.V(100).Infof("The %s builder is uninitialized", resourceCRD) + + return false, fmt.Errorf("error: received nil %s builder", resourceCRD) + } + + if builder.Definition == nil { + glog.V(100).Infof("The %s is undefined", resourceCRD) + + builder.errorMsg = msg.UndefinedCrdObjectErrString(resourceCRD) + } + + if builder.apiClient == nil { + glog.V(100).Infof("The %s builder apiclient is nil", resourceCRD) + + builder.errorMsg = fmt.Sprintf("%s builder cannot have nil apiClient", resourceCRD) + } + + if builder.errorMsg != "" { + glog.V(100).Infof("The %s builder has error message: %s", resourceCRD, builder.errorMsg) + + return false, fmt.Errorf(builder.errorMsg) + } + + return true, nil +} diff --git a/vendor/github.com/openshift-kni/eco-goinfra/pkg/lca/seedgenerator.go b/vendor/github.com/openshift-kni/eco-goinfra/pkg/lca/seedgenerator.go new file mode 100644 index 00000000..e2576659 --- /dev/null +++ b/vendor/github.com/openshift-kni/eco-goinfra/pkg/lca/seedgenerator.go @@ -0,0 +1,294 @@ +package lca + +import ( + "context" + "fmt" + "time" + + "github.com/golang/glog" + "github.com/openshift-kni/eco-goinfra/pkg/clients" + "github.com/openshift-kni/eco-goinfra/pkg/msg" + lcasgv1alpha1 "github.com/openshift-kni/lifecycle-agent/api/seedgenerator/v1alpha1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" + goclient "sigs.k8s.io/controller-runtime/pkg/client" +) + +// SeedGenerator provides struct for the seedgenerator object containing connection to +// the cluster and the seedgenerator definitions. +type SeedGeneratorBuilder struct { + // SeedGenerator definition. Used to store the seedgenerator object. + Definition *lcasgv1alpha1.SeedGenerator + // Created seedgenerator object. + Object *lcasgv1alpha1.SeedGenerator + // Used in functions that define or mutate the seedgenerator definition. + // errorMsg is processed before the seedgenerator object is created + errorMsg string + apiClient *clients.Settings +} + +// SeedGeneratorAdditionalOptions additional options for imagebasedupgrade object. +type SeedGeneratorAdditionalOptions func(builder *SeedGeneratorBuilder) (*SeedGeneratorBuilder, error) + +// NewBuilder creates a new instance of SeedGenerator. +func NewSeedGeneratorBuilder( + apiClient *clients.Settings, + name string, +) *SeedGeneratorBuilder { + builder := SeedGeneratorBuilder{ + apiClient: apiClient, + Definition: &lcasgv1alpha1.SeedGenerator{ + ObjectMeta: metaV1.ObjectMeta{ + Name: name, + }, + }, + } + + if name == "" { + glog.V(100).Infof("The name of the seedgenerator is empty") + + builder.errorMsg = "SeedGenerator name cannot be empty" + } + + return &builder +} + +// WithOptions creates seedgenerator with generic mutation options. +func (builder *SeedGeneratorBuilder) WithOptions(options ...SeedGeneratorAdditionalOptions) *SeedGeneratorBuilder { + if valid, _ := builder.validate(); !valid { + return builder + } + + glog.V(100).Infof("Setting seedgenerator additional options") + + for _, option := range options { + if option != nil { + builder, err := option(builder) + + if err != nil { + glog.V(100).Infof("Error occurred in mutation function") + + builder.errorMsg = err.Error() + + return builder + } + } + } + + return builder +} + +// Create makes a seedgenerator in the cluster and stores the created object in struct. +func (builder *SeedGeneratorBuilder) Create() (*SeedGeneratorBuilder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Creating the seedgenerator %s", + builder.Definition.Name) + + var err error + if !builder.Exists() { + err = builder.apiClient.Create(context.TODO(), builder.Definition) + if err == nil { + builder.Object = builder.Definition + } + } + + return builder, err +} + +// PullSeedGenerator pulls existing seedgenerator from cluster. +func PullSeedGenerator(apiClient *clients.Settings, name string) (*SeedGeneratorBuilder, error) { + glog.V(100).Infof("Pulling existing seedgenerator name %s from cluster", name) + + builder := SeedGeneratorBuilder{ + apiClient: apiClient, + Definition: &lcasgv1alpha1.SeedGenerator{ + ObjectMeta: metaV1.ObjectMeta{ + Name: name, + }, + }, + } + + if name == "" { + glog.V(100).Infof("The name of the seedgenerator is empty") + + builder.errorMsg = "seedgenerator 'name' cannot be empty" + } + + if !builder.Exists() { + return nil, fmt.Errorf("seedgenerator object %s doesn't exist", name) + } + + builder.Definition = builder.Object + + return &builder, nil +} + +// Delete removes the existing seedgenerator from a cluster. +func (builder *SeedGeneratorBuilder) Delete() (*SeedGeneratorBuilder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Deleting the seedgenerator %s", + builder.Definition.Name) + + if !builder.Exists() { + return builder, fmt.Errorf("seedgenerator cannot be deleted because it does not exist") + } + + err := builder.apiClient.Delete(context.TODO(), builder.Definition) + + if err != nil { + return builder, fmt.Errorf("can not delete seedgenerator: %w", err) + } + + builder.Object = nil + + return builder, nil +} + +// Get returns seedgenerator object if found. +func (builder *SeedGeneratorBuilder) Get() (*lcasgv1alpha1.SeedGenerator, error) { + if valid, err := builder.validate(); !valid { + return nil, err + } + + glog.V(100).Infof("Getting seedgenerator %s", + builder.Definition.Name) + + seedgenerator := &lcasgv1alpha1.SeedGenerator{} + err := builder.apiClient.Get(context.TODO(), goclient.ObjectKey{ + Name: builder.Definition.Name, + }, seedgenerator) + + if err != nil { + return nil, err + } + + return seedgenerator, err +} + +// Exists checks whether the given seedgenerator exists. +func (builder *SeedGeneratorBuilder) Exists() bool { + if valid, _ := builder.validate(); !valid { + return false + } + + glog.V(100).Infof("Checking if seedgenerator %s exists", + builder.Definition.Name) + + var err error + builder.Object, err = builder.Get() + + return err == nil || !k8serrors.IsNotFound(err) +} + +// WithSeedImage sets the seed image used by the seedgenerator. +func (builder *SeedGeneratorBuilder) WithSeedImage( + seedImage string) *SeedGeneratorBuilder { + if valid, _ := builder.validate(); !valid { + return builder + } + + glog.V(100).Infof("Setting seed image %s in seedgenerator", seedImage) + + builder.Definition.Spec.SeedImage = seedImage + + return builder +} + +// WithRecertImage sets the recert image used by the seedgenerator. +func (builder *SeedGeneratorBuilder) WithRecertImage( + recertImage string) *SeedGeneratorBuilder { + if valid, _ := builder.validate(); !valid { + return builder + } + + glog.V(100).Infof("Setting recert image %s in seedgenerator", recertImage) + + builder.Definition.Spec.RecertImage = recertImage + + return builder +} + +// WaitUntilComplete waits the specified timeout for the seedgenerator to complete +// actions. +func (builder *SeedGeneratorBuilder) WaitUntilComplete(timeout time.Duration) (*SeedGeneratorBuilder, error) { + if valid, err := builder.validate(); !valid { + return builder, err + } + + glog.V(100).Infof("Waiting for seedgenerator %s to complete actions", + builder.Definition.Name) + + if !builder.Exists() { + glog.V(100).Infof("The seedgenerator does not exist on the cluster") + + return builder, fmt.Errorf(builder.errorMsg) + } + + // Polls periodically to determine if seedgenerator is in desired state. + var err error + err = wait.PollUntilContextTimeout( + context.TODO(), time.Second*3, timeout, true, func(ctx context.Context) (bool, error) { + builder.Object, err = builder.Get() + + if err != nil { + return false, nil + } + + for _, condition := range builder.Object.Status.Conditions { + + if condition.Status == "True" && condition.Type == "SeedGenCompleted" && + condition.Reason == "Completed" { + return true, nil + } + + } + + return false, nil + + }) + + if err == nil { + return builder, nil + } + + return nil, err +} + +// validate will check that the builder and builder definition are properly initialized before +// accessing any member fields. +func (builder *SeedGeneratorBuilder) validate() (bool, error) { + resourceCRD := "SeedGenerator" + + if builder == nil { + glog.V(100).Infof("The %s builder is uninitialized", resourceCRD) + + return false, fmt.Errorf("error: received nil %s builder", resourceCRD) + } + + if builder.Definition == nil { + glog.V(100).Infof("The %s is undefined", resourceCRD) + + builder.errorMsg = msg.UndefinedCrdObjectErrString(resourceCRD) + } + + if builder.apiClient == nil { + glog.V(100).Infof("The %s builder apiclient is nil", resourceCRD) + + builder.errorMsg = fmt.Sprintf("%s builder cannot have nil apiClient", resourceCRD) + } + + if builder.errorMsg != "" { + glog.V(100).Infof("The %s builder has error message: %s", resourceCRD, builder.errorMsg) + + return false, fmt.Errorf(builder.errorMsg) + } + + return true, nil +} diff --git a/vendor/github.com/openshift-kni/lifecycle-agent/LICENSE b/vendor/github.com/openshift-kni/lifecycle-agent/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/vendor/github.com/openshift-kni/lifecycle-agent/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/openshift-kni/lifecycle-agent/api/seedgenerator/v1alpha1/groupversion_info.go b/vendor/github.com/openshift-kni/lifecycle-agent/api/seedgenerator/v1alpha1/groupversion_info.go new file mode 100644 index 00000000..01cc9995 --- /dev/null +++ b/vendor/github.com/openshift-kni/lifecycle-agent/api/seedgenerator/v1alpha1/groupversion_info.go @@ -0,0 +1,44 @@ +/* +Copyright 2023. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1alpha1 contains API Schema definitions for the lca v1alpha1 API group +// +kubebuilder:object:generate=true +// +groupName=lca.openshift.io +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "lca.openshift.io", Version: "v1alpha1"} + + // SchemeGroupVersion is expected by k8s.io/code-generator + SchemeGroupVersion = schema.GroupVersion{Group: "lca.openshift.io", Version: "v1alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) + +// Resource takes an unqualified resource and returns a Group qualified GroupResource. Expected by k8s.io/code-generator +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} diff --git a/vendor/github.com/openshift-kni/lifecycle-agent/api/seedgenerator/v1alpha1/types.go b/vendor/github.com/openshift-kni/lifecycle-agent/api/seedgenerator/v1alpha1/types.go new file mode 100644 index 00000000..bd3d0045 --- /dev/null +++ b/vendor/github.com/openshift-kni/lifecycle-agent/api/seedgenerator/v1alpha1/types.go @@ -0,0 +1,69 @@ +/* +Copyright 2023. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status +//+kubebuilder:resource:path=seedgenerators,scope=Cluster,shortName=seedgen +//+kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" +//+kubebuilder:printcolumn:name="State",type="string",JSONPath=".status.conditions[-1:].type" +//+kubebuilder:printcolumn:name="Details",type="string",JSONPath=".status.conditions[-1:].message" + +// SeedGenerator is the Schema for the seedgenerators API +// +operator-sdk:csv:customresourcedefinitions:displayName="Seed Generator",resources={{Namespace, v1}} +type SeedGenerator struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + //+kubebuilder:validation:XValidation:rule="self == oldSelf",message="cannot modify spec, cr must be deleted and recreated" + Spec SeedGeneratorSpec `json:"spec,omitempty"` + Status SeedGeneratorStatus `json:"status,omitempty"` +} + +// SeedGeneratorSpec defines the desired state of SeedGenerator +type SeedGeneratorSpec struct { + SeedImage string `json:"seedImage,omitempty"` + RecertImage string `json:"recertImage,omitempty"` +} + +// SeedGeneratorStatus defines the observed state of SeedGenerator +type SeedGeneratorStatus struct { + // +operator-sdk:csv:customresourcedefinitions:type=status,displayName="Status" + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + StartedAt metav1.Time `json:"startedAt,omitempty"` + CompletedAt metav1.Time `json:"completedAt,omitempty"` + // +operator-sdk:csv:customresourcedefinitions:type=status,displayName="Conditions" + Conditions []metav1.Condition `json:"conditions,omitempty"` +} + +//+kubebuilder:object:root=true + +// SeedGeneratorList contains a list of SeedGenerator +type SeedGeneratorList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []SeedGenerator `json:"items"` +} + +func init() { + SchemeBuilder.Register(&SeedGenerator{}, &SeedGeneratorList{}) +} diff --git a/vendor/github.com/openshift-kni/lifecycle-agent/api/seedgenerator/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/openshift-kni/lifecycle-agent/api/seedgenerator/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000..6cc81cd1 --- /dev/null +++ b/vendor/github.com/openshift-kni/lifecycle-agent/api/seedgenerator/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,124 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2023. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SeedGenerator) DeepCopyInto(out *SeedGenerator) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SeedGenerator. +func (in *SeedGenerator) DeepCopy() *SeedGenerator { + if in == nil { + return nil + } + out := new(SeedGenerator) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SeedGenerator) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SeedGeneratorList) DeepCopyInto(out *SeedGeneratorList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]SeedGenerator, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SeedGeneratorList. +func (in *SeedGeneratorList) DeepCopy() *SeedGeneratorList { + if in == nil { + return nil + } + out := new(SeedGeneratorList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *SeedGeneratorList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SeedGeneratorSpec) DeepCopyInto(out *SeedGeneratorSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SeedGeneratorSpec. +func (in *SeedGeneratorSpec) DeepCopy() *SeedGeneratorSpec { + if in == nil { + return nil + } + out := new(SeedGeneratorSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SeedGeneratorStatus) DeepCopyInto(out *SeedGeneratorStatus) { + *out = *in + in.StartedAt.DeepCopyInto(&out.StartedAt) + in.CompletedAt.DeepCopyInto(&out.CompletedAt) + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SeedGeneratorStatus. +func (in *SeedGeneratorStatus) DeepCopy() *SeedGeneratorStatus { + if in == nil { + return nil + } + out := new(SeedGeneratorStatus) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/github.com/openshift-kni/lifecycle-agent/api/v1alpha1/groupversion_info.go b/vendor/github.com/openshift-kni/lifecycle-agent/api/v1alpha1/groupversion_info.go new file mode 100644 index 00000000..01cc9995 --- /dev/null +++ b/vendor/github.com/openshift-kni/lifecycle-agent/api/v1alpha1/groupversion_info.go @@ -0,0 +1,44 @@ +/* +Copyright 2023. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1alpha1 contains API Schema definitions for the lca v1alpha1 API group +// +kubebuilder:object:generate=true +// +groupName=lca.openshift.io +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "lca.openshift.io", Version: "v1alpha1"} + + // SchemeGroupVersion is expected by k8s.io/code-generator + SchemeGroupVersion = schema.GroupVersion{Group: "lca.openshift.io", Version: "v1alpha1"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) + +// Resource takes an unqualified resource and returns a Group qualified GroupResource. Expected by k8s.io/code-generator +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} diff --git a/vendor/github.com/openshift-kni/lifecycle-agent/api/v1alpha1/types.go b/vendor/github.com/openshift-kni/lifecycle-agent/api/v1alpha1/types.go new file mode 100644 index 00000000..0aa9a859 --- /dev/null +++ b/vendor/github.com/openshift-kni/lifecycle-agent/api/v1alpha1/types.go @@ -0,0 +1,126 @@ +/* +Copyright 2023. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:resource:path=imagebasedupgrades,scope=Cluster,shortName=ibu +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp" +// +kubebuilder:printcolumn:name="Stage",type="string",JSONPath=".spec.stage" +// +kubebuilder:printcolumn:name="State",type="string",JSONPath=".status.conditions[-1:].type" +// +kubebuilder:printcolumn:name="Details",type="string",JSONPath=".status.conditions[-1:].message" +// +kubebuilder:validation:XValidation:message="can not change spec.seedImageRef while ibu is in progress", rule="!has(oldSelf.status) || oldSelf.status.conditions.exists(c, c.type=='Idle' && c.status=='True') || has(oldSelf.spec.seedImageRef) && has(self.spec.seedImageRef) && oldSelf.spec.seedImageRef==self.spec.seedImageRef || !has(self.spec.seedImageRef) && !has(oldSelf.spec.seedImageRef)" +// +kubebuilder:validation:XValidation:message="can not change spec.oadpContent while ibu is in progress", rule="!has(oldSelf.status) || oldSelf.status.conditions.exists(c, c.type=='Idle' && c.status=='True') || has(oldSelf.spec.oadpContent) && has(self.spec.oadpContent) && oldSelf.spec.oadpContent==self.spec.oadpContent || !has(self.spec.oadpContent) && !has(oldSelf.spec.oadpContent)" +// +kubebuilder:validation:XValidation:message="can not change spec.extraManifests while ibu is in progress", rule="!has(oldSelf.status) || oldSelf.status.conditions.exists(c, c.type=='Idle' && c.status=='True') || has(oldSelf.spec.extraManifests) && has(self.spec.extraManifests) && oldSelf.spec.extraManifests==self.spec.extraManifests || !has(self.spec.extraManifests) && !has(oldSelf.spec.extraManifests)" +// +operator-sdk:csv:customresourcedefinitions:displayName="Image-based Cluster Upgrade",resources={{Namespace, v1},{Deployment,apps/v1}} +// ImageBasedUpgrade is the Schema for the ImageBasedUpgrades API +type ImageBasedUpgrade struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ImageBasedUpgradeSpec `json:"spec,omitempty"` + Status ImageBasedUpgradeStatus `json:"status,omitempty"` +} + +// ImageBasedUpgradeStage defines the type for the IBU stage field +type ImageBasedUpgradeStage string + +// Stages defines the string values for valid stages +var Stages = struct { + Idle ImageBasedUpgradeStage + Prep ImageBasedUpgradeStage + Upgrade ImageBasedUpgradeStage + Rollback ImageBasedUpgradeStage +}{ + Idle: "Idle", + Prep: "Prep", + Upgrade: "Upgrade", + Rollback: "Rollback", +} + +// ImageBasedUpgradeSpec defines the desired state of ImageBasedUpgrade +type ImageBasedUpgradeSpec struct { + //+kubebuilder:validation:Enum=Idle;Prep;Upgrade;Rollback + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Stage" + Stage ImageBasedUpgradeStage `json:"stage,omitempty"` + //+operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Seed Image Reference" + SeedImageRef SeedImageRef `json:"seedImageRef,omitempty"` + AdditionalImages ConfigMapRef `json:"additionalImages,omitempty"` + OADPContent []ConfigMapRef `json:"oadpContent,omitempty"` + ExtraManifests []ConfigMapRef `json:"extraManifests,omitempty"` + RollbackTarget string `json:"rollbackTarget,omitempty"` +} + +// SeedImageRef defines the seed image and OCP version for the upgrade +type SeedImageRef struct { + Version string `json:"version,omitempty"` + Image string `json:"image,omitempty"` + PullSecretRef *PullSecretRef `json:"pullSecretRef,omitempty"` +} + +// ConfigMapRef defines a reference to a config map +type ConfigMapRef struct { + // +kubebuilder:validation:Required + // +required + Name string `json:"name"` + + // +kubebuilder:validation:Required + // +required + Namespace string `json:"namespace"` +} + +// PullSecretRef defines a reference to a secret with credentials for pulling container images +type PullSecretRef struct { + // +kubebuilder:validation:Required + // +required + Name string `json:"name"` +} + +// ImageBasedUpgradeStatus defines the observed state of ImageBasedUpgrade +type ImageBasedUpgradeStatus struct { + // +operator-sdk:csv:customresourcedefinitions:type=status,displayName="Status" + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + StartedAt metav1.Time `json:"startedAt,omitempty"` + CompletedAt metav1.Time `json:"completedAt,omitempty"` + StateRoots []StateRoot `json:"stateRoots,omitempty"` + // +operator-sdk:csv:customresourcedefinitions:type=status,displayName="Conditions" + Conditions []metav1.Condition `json:"conditions,omitempty"` +} + +// StateRoot defines a list of saved pod states and the running OCP version when they are saved +type StateRoot struct { + Version string `json:"version,omitempty"` + // TODO add fields for saved states +} + +// +kubebuilder:object:root=true + +// ImageBasedUpgradeList contains a list of ImageBasedUpgrade +type ImageBasedUpgradeList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ImageBasedUpgrade `json:"items"` +} + +func init() { + SchemeBuilder.Register(&ImageBasedUpgrade{}, &ImageBasedUpgradeList{}) +} diff --git a/vendor/github.com/openshift-kni/lifecycle-agent/api/v1alpha1/zz_generated.deepcopy.go b/vendor/github.com/openshift-kni/lifecycle-agent/api/v1alpha1/zz_generated.deepcopy.go new file mode 100644 index 00000000..c8719140 --- /dev/null +++ b/vendor/github.com/openshift-kni/lifecycle-agent/api/v1alpha1/zz_generated.deepcopy.go @@ -0,0 +1,206 @@ +//go:build !ignore_autogenerated + +/* +Copyright 2023. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConfigMapRef) DeepCopyInto(out *ConfigMapRef) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigMapRef. +func (in *ConfigMapRef) DeepCopy() *ConfigMapRef { + if in == nil { + return nil + } + out := new(ConfigMapRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageBasedUpgrade) DeepCopyInto(out *ImageBasedUpgrade) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageBasedUpgrade. +func (in *ImageBasedUpgrade) DeepCopy() *ImageBasedUpgrade { + if in == nil { + return nil + } + out := new(ImageBasedUpgrade) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ImageBasedUpgrade) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageBasedUpgradeList) DeepCopyInto(out *ImageBasedUpgradeList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ImageBasedUpgrade, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageBasedUpgradeList. +func (in *ImageBasedUpgradeList) DeepCopy() *ImageBasedUpgradeList { + if in == nil { + return nil + } + out := new(ImageBasedUpgradeList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ImageBasedUpgradeList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageBasedUpgradeSpec) DeepCopyInto(out *ImageBasedUpgradeSpec) { + *out = *in + in.SeedImageRef.DeepCopyInto(&out.SeedImageRef) + out.AdditionalImages = in.AdditionalImages + if in.OADPContent != nil { + in, out := &in.OADPContent, &out.OADPContent + *out = make([]ConfigMapRef, len(*in)) + copy(*out, *in) + } + if in.ExtraManifests != nil { + in, out := &in.ExtraManifests, &out.ExtraManifests + *out = make([]ConfigMapRef, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageBasedUpgradeSpec. +func (in *ImageBasedUpgradeSpec) DeepCopy() *ImageBasedUpgradeSpec { + if in == nil { + return nil + } + out := new(ImageBasedUpgradeSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ImageBasedUpgradeStatus) DeepCopyInto(out *ImageBasedUpgradeStatus) { + *out = *in + in.StartedAt.DeepCopyInto(&out.StartedAt) + in.CompletedAt.DeepCopyInto(&out.CompletedAt) + if in.StateRoots != nil { + in, out := &in.StateRoots, &out.StateRoots + *out = make([]StateRoot, len(*in)) + copy(*out, *in) + } + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageBasedUpgradeStatus. +func (in *ImageBasedUpgradeStatus) DeepCopy() *ImageBasedUpgradeStatus { + if in == nil { + return nil + } + out := new(ImageBasedUpgradeStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PullSecretRef) DeepCopyInto(out *PullSecretRef) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PullSecretRef. +func (in *PullSecretRef) DeepCopy() *PullSecretRef { + if in == nil { + return nil + } + out := new(PullSecretRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SeedImageRef) DeepCopyInto(out *SeedImageRef) { + *out = *in + if in.PullSecretRef != nil { + in, out := &in.PullSecretRef, &out.PullSecretRef + *out = new(PullSecretRef) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SeedImageRef. +func (in *SeedImageRef) DeepCopy() *SeedImageRef { + if in == nil { + return nil + } + out := new(SeedImageRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StateRoot) DeepCopyInto(out *StateRoot) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StateRoot. +func (in *StateRoot) DeepCopy() *StateRoot { + if in == nil { + return nil + } + out := new(StateRoot) + in.DeepCopyInto(out) + return out +} diff --git a/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go b/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go index 554112c4..c585a65b 100644 --- a/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go +++ b/vendor/github.com/openshift/library-go/pkg/crypto/crypto.go @@ -758,15 +758,17 @@ func GetServerCert(certFile, keyFile string, hostnames sets.String) (*TLSCertifi } cert := server.Certs[0] - ips, dns := IPAddressesDNSNames(hostnames.List()) - missingIps := ipsNotInSlice(ips, cert.IPAddresses) - missingDns := stringsNotInSlice(dns, cert.DNSNames) - if len(missingIps) == 0 && len(missingDns) == 0 { + certNames := sets.NewString() + for _, ip := range cert.IPAddresses { + certNames.Insert(ip.String()) + } + certNames.Insert(cert.DNSNames...) + if hostnames.Equal(certNames) { klog.V(4).Infof("Found existing server certificate in %s", certFile) return server, nil } - return nil, fmt.Errorf("Existing server certificate in %s was missing some hostnames (%v) or IP addresses (%v).", certFile, missingDns, missingIps) + return nil, fmt.Errorf("Existing server certificate in %s does not match required hostnames.", certFile) } func (ca *CA) MakeAndWriteServerCert(certFile, keyFile string, hostnames sets.String, expireDays int) (*TLSCertificateConfig, error) { @@ -1212,41 +1214,3 @@ func writeKeyFile(f io.Writer, key crypto.PrivateKey) error { return nil } - -func stringsNotInSlice(needles []string, haystack []string) []string { - missing := []string{} - for _, needle := range needles { - if !stringInSlice(needle, haystack) { - missing = append(missing, needle) - } - } - return missing -} - -func stringInSlice(needle string, haystack []string) bool { - for _, straw := range haystack { - if needle == straw { - return true - } - } - return false -} - -func ipsNotInSlice(needles []net.IP, haystack []net.IP) []net.IP { - missing := []net.IP{} - for _, needle := range needles { - if !ipInSlice(needle, haystack) { - missing = append(missing, needle) - } - } - return missing -} - -func ipInSlice(needle net.IP, haystack []net.IP) bool { - for _, straw := range haystack { - if needle.Equal(straw) { - return true - } - } - return false -} diff --git a/vendor/modules.txt b/vendor/modules.txt index f0f90267..5814c30b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -401,7 +401,7 @@ github.com/onsi/gomega/types ## explicit; go 1.20 github.com/openshift-kni/cluster-group-upgrades-operator/pkg/api/clustergroupupgrades github.com/openshift-kni/cluster-group-upgrades-operator/pkg/api/clustergroupupgrades/v1alpha1 -# github.com/openshift-kni/eco-goinfra v0.0.0-20240109203119-975bf2617254 +# github.com/openshift-kni/eco-goinfra v0.0.0-20240119165249-4757abb333e9 ## explicit; go 1.20 github.com/openshift-kni/eco-goinfra/pkg/argocd github.com/openshift-kni/eco-goinfra/pkg/argocd/argocdtypes @@ -411,6 +411,7 @@ github.com/openshift-kni/eco-goinfra/pkg/clients github.com/openshift-kni/eco-goinfra/pkg/clusterversion github.com/openshift-kni/eco-goinfra/pkg/daemonset github.com/openshift-kni/eco-goinfra/pkg/deployment +github.com/openshift-kni/eco-goinfra/pkg/lca github.com/openshift-kni/eco-goinfra/pkg/mco github.com/openshift-kni/eco-goinfra/pkg/msg github.com/openshift-kni/eco-goinfra/pkg/nad @@ -429,6 +430,10 @@ github.com/openshift-kni/eco-goinfra/pkg/statefulset # github.com/openshift-kni/k8sreporter v1.0.5 ## explicit; go 1.20 github.com/openshift-kni/k8sreporter +# github.com/openshift-kni/lifecycle-agent v0.0.0-20240109211418-4489c4a1eb46 +## explicit; go 1.20 +github.com/openshift-kni/lifecycle-agent/api/seedgenerator/v1alpha1 +github.com/openshift-kni/lifecycle-agent/api/v1alpha1 # github.com/openshift/api v3.9.1-0.20190916204813-cdbe64fb0c91+incompatible => github.com/openshift/api v0.0.0-20231115210901-4c4a0a24f2fc ## explicit; go 1.20 github.com/openshift/api @@ -579,7 +584,7 @@ github.com/openshift/hive/apis/hive/v1/openstack github.com/openshift/hive/apis/hive/v1/ovirt github.com/openshift/hive/apis/hive/v1/vsphere github.com/openshift/hive/apis/scheme -# github.com/openshift/library-go v0.0.0-20231020125025-211b32f1a1f2 +# github.com/openshift/library-go v0.0.0-20231027143522-b8cd45d2d2c8 ## explicit; go 1.20 github.com/openshift/library-go/pkg/controller/factory github.com/openshift/library-go/pkg/crypto