Skip to content

Rename OperatorVersion CRs from name-<operatorVersion> to name-<appVersion>-<operatorVersion> #1684

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Oct 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
d45938c
Added migration, adjusted incluster_resolver
ANeumann82 Sep 10, 2020
8d231ff
Extract operator version sorting into kudo package
ANeumann82 Sep 10, 2020
90399cb
Started to add tests
ANeumann82 Sep 10, 2020
83e386c
Fixed migration, adjusted upgrade test to confirm migration
ANeumann82 Sep 15, 2020
d2a04f5
Merge branch 'main' into an/rename-operatorversions
ANeumann82 Sep 15, 2020
0bd2cc9
Adjusted migrations
ANeumann82 Sep 15, 2020
7683c13
Use adjusted operator version tests
ANeumann82 Sep 16, 2020
88701b4
Fixed integration test
ANeumann82 Sep 16, 2020
4733914
Fix e2e-tests
ANeumann82 Sep 16, 2020
be11d6d
Small cleanup
ANeumann82 Sep 16, 2020
0fe273c
Merge branch 'main' into an/rename-operatorversions
ANeumann82 Sep 16, 2020
d54c556
Cleanup migrations
ANeumann82 Sep 16, 2020
d2aab43
Merge branch 'main' into an/rename-operatorversions
ANeumann82 Sep 21, 2020
b1f5b4f
Adjustments for merged main
ANeumann82 Sep 21, 2020
c5f7030
Small cleanup
ANeumann82 Sep 21, 2020
ec415a5
Use SemVer v3
ANeumann82 Sep 22, 2020
108c854
Updated documentation
ANeumann82 Sep 23, 2020
553a1fa
Verify that OV `appVersion` is also a semver (if present)
zen-dog Sep 23, 2020
971404a
Usre more go-like var names
ANeumann82 Sep 25, 2020
11dd956
Add SemVer verify for appVersion back in.
ANeumann82 Sep 25, 2020
13ffcd7
Small changes from review
ANeumann82 Oct 2, 2020
48304db
Code review requests
ANeumann82 Oct 8, 2020
9c8b72b
Adjusted migration
ANeumann82 Oct 8, 2020
45366f1
Removed migration
ANeumann82 Oct 8, 2020
fb3f2a8
Merge branch 'main' into an/rename-operatorversions
ANeumann82 Oct 8, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU=
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU=
Expand Down
2 changes: 1 addition & 1 deletion hack/run-operator-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ docker build . \
-t "kudobuilder/controller:$KUDO_VERSION"

rm -rf operators
git clone https://github.com/kudobuilder/operators
git clone --branch "an/rename-operatorversions" https://github.com/kudobuilder/operators
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will need to be removed before merging - It requires changes on the operator tests

mkdir operators/bin/
cp ./bin/kubectl-kudo operators/bin/
sed "s/%version%/$KUDO_VERSION/" operators/kudo-test.yaml.tmpl > operators/kudo-test.yaml
Expand Down
43 changes: 40 additions & 3 deletions pkg/apis/kudo/v1beta1/operatorversion_types_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,37 @@ import (

"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/kudobuilder/kudo/pkg/util/kudo"
)

func OperatorInstanceName(operatorName string) string {
return fmt.Sprintf("%s-instance", operatorName)
}

func OperatorVersionName(operatorName, version string) string {
return fmt.Sprintf("%s-%s", operatorName, version)
func OperatorVersionName(operatorName, appVersion, opVersion string) string {
if appVersion == "" {
return fmt.Sprintf("%s-%s", operatorName, opVersion)
}
return fmt.Sprintf("%s-%s-%s", operatorName, appVersion, opVersion)
}

func (ov *OperatorVersion) FullyQualifiedName() string {
return fmt.Sprintf("%s-%s", ov.Name, ov.Spec.AppVersion)
return OperatorVersionName(ov.Spec.Operator.Name, ov.Spec.AppVersion, ov.Spec.Version)
}

func (ov *OperatorVersion) EqualOperatorVersion(other *OperatorVersion) bool {
return ov.FullyQualifiedName() == other.FullyQualifiedName()
}

func ListOperatorVersions(ns string, c client.Reader) (l *OperatorVersionList, err error) {
l = &OperatorVersionList{}
if err := c.List(context.TODO(), l, client.InNamespace(ns)); err != nil {
return nil, err
}
return l, nil
}

func GetOperatorVersionByName(name, ns string, c client.Reader) (ov *OperatorVersion, err error) {
ov = &OperatorVersion{}
err = c.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: ns}, ov)
Expand All @@ -32,3 +45,27 @@ func GetOperatorVersionByName(name, ns string, c client.Reader) (ov *OperatorVer
}
return ov, nil
}

// Sortable Operator implements functionality to correctly sort OVs by name, appVersion and operatorVersion
var _ kudo.SortableOperator = &OperatorVersion{}

func (ov *OperatorVersion) OperatorName() string {
return ov.Spec.Operator.Name
}

func (ov *OperatorVersion) OperatorVersion() string {
return ov.Spec.Version
}

func (ov *OperatorVersion) AppVersion() string {
return ov.Spec.AppVersion
}

func ToSortableOperatorList(ovList []OperatorVersion) kudo.SortableOperatorList {
l := kudo.SortableOperatorList{}
for _, ov := range ovList {
ov := ov
l = append(l, &ov)
}
return l
}
2 changes: 1 addition & 1 deletion pkg/controller/instance/resolver_incluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ type InClusterResolver struct {
}

func (r InClusterResolver) Resolve(name string, appVersion string, operatorVersion string) (*packages.Package, error) {
ovn := kudoapi.OperatorVersionName(name, operatorVersion)
ovn := kudoapi.OperatorVersionName(name, appVersion, operatorVersion)

ov, err := kudoapi.GetOperatorVersionByName(ovn, r.ns, r.c)
if err != nil {
Expand Down
3 changes: 2 additions & 1 deletion pkg/engine/task/task_kudo_operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ func (kt KudoOperatorTask) Run(ctx Context) (bool, error) {
namespace := ctx.Meta.InstanceNamespace
operatorName := kt.OperatorName
operatorVersion := kt.OperatorVersion
operatorVersionName := kudoapi.OperatorVersionName(operatorName, operatorVersion)
appVersion := kt.AppVersion
operatorVersionName := kudoapi.OperatorVersionName(operatorName, appVersion, operatorVersion)
instanceName := dependencyInstanceName(ctx.Meta.InstanceName, kt.InstanceName, operatorName)

// 1. - Expand parameter file if exists -
Expand Down
1 change: 1 addition & 0 deletions pkg/kudoctl/cmd/verify/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ func (VersionVerifier) Verify(pf *packages.Files) verifier.Result {
return res
}
verifySemVer(pf.Operator.OperatorVersion, "operatorVersion", &res, true)
verifySemVer(pf.Operator.AppVersion, "appVersion", &res, false)
verifySemVer(pf.Operator.KubernetesVersion, "kubernetesVersion", &res, true)
verifySemVer(pf.Operator.KUDOVersion, "kudoVersion", &res, false)
return res
Expand Down
7 changes: 7 additions & 0 deletions pkg/kudoctl/kube/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"k8s.io/client-go/tools/clientcmd"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/kudobuilder/kudo/pkg/client/clientset/versioned"
"github.com/kudobuilder/kudo/pkg/kudoctl/clog"
)

Expand All @@ -19,6 +20,7 @@ type Client struct {
ExtClient apiextensionsclient.Interface
DynamicClient dynamic.Interface
CtrlClient client.Client
KudoClient versioned.Interface
}

// GetConfig returns a Kubernetes client config for a given kubeconfig.
Expand Down Expand Up @@ -70,11 +72,16 @@ func GetKubeClientForConfig(config *rest.Config) (*Client, error) {
if err != nil {
return nil, fmt.Errorf("could not create Controller Runtime client: %s", err)
}
kudoClient, err := versioned.NewForConfig(config)
if err != nil {
return nil, fmt.Errorf("could not create KUDO client: %v", err)
}

return &Client{
KubeClient: kubeClient,
ExtClient: extClient,
DynamicClient: dynamicClient,
CtrlClient: ctrlClient,
KudoClient: kudoClient,
}, nil
}
12 changes: 8 additions & 4 deletions pkg/kudoctl/kudoinit/migration/migration.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package migration

import "github.com/kudobuilder/kudo/pkg/kudoctl/kube"

// Migrater is the base interface for migrations.
type Migrater interface {
CanMigrate(client *kube.Client) error
Migrate(client *kube.Client) error
// CanMigrate checks if there are any conditions that would prevent this migration to run
// This function should only return an error if it is sure that the migration can not be executed
CanMigrate() error

// Migrate executes the migration. The call must be idempotent and ignore already migrated resources
// It can be called multiple times on the same cluster and encounter migrated and unmigrated resources.
Migrate() error
}
56 changes: 56 additions & 0 deletions pkg/kudoctl/kudoinit/migration/migration_helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// This package contains helper functions that can be reused by all migrations
package migration

import (
"context"
"fmt"

v1 "k8s.io/apimachinery/pkg/apis/meta/v1"

kudoapi "github.com/kudobuilder/kudo/pkg/apis/kudo/v1beta1"
"github.com/kudobuilder/kudo/pkg/kudoctl/kube"
)

// ForEachNamespace calls the given function for all namespaces in the cluster
func ForEachNamespace(client *kube.Client, f func(ns string) error) error {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: These functions would make sense in pkg/kudoctl/util/kudo as well. But with a kube.Client and kudo.Client, it looks like our usage of the Kubernetes client API will need some refactoring first.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeaaaah.... The usage of the different clients is something that really should be refactored and cleaned up. Same with the loggers.

We should have established rules which client(s) and which logger(s) is used where, (i.e. CLI code, Manager code and shared code), but that's a discussion for a different time :)

l, err := client.KubeClient.CoreV1().Namespaces().List(context.TODO(), v1.ListOptions{})
if err != nil {
return fmt.Errorf("failed to fetch namespaces: %v", err)
}
for _, ns := range l.Items {
if err := f(ns.Name); err != nil {
return fmt.Errorf("failed to run function for namespace %q: %v", ns.Name, err)
}
}
return nil
}

// ForEachOperatorVersion calls the given function for all operatorversions in the given namespace
func ForEachOperatorVersion(client *kube.Client, ns string, f func(ov *kudoapi.OperatorVersion) error) error {
l, err := client.KudoClient.KudoV1beta1().OperatorVersions(ns).List(context.TODO(), v1.ListOptions{})
if err != nil {
return fmt.Errorf("failed to fetch OperatorVersions from namespace %q: %v", ns, err)
}
for _, ov := range l.Items {
ov := ov
if err := f(&ov); err != nil {
return fmt.Errorf("failed to run function for OperatorVersion \"%s/%s\": %v", ov.Namespace, ov.Name, err)
}
}
return nil
}

// ForEachInstance calls the given function for all instances in the given namespace
func ForEachInstance(client *kube.Client, ns string, f func(ov *kudoapi.Instance) error) error {
l, err := client.KudoClient.KudoV1beta1().Instances(ns).List(context.TODO(), v1.ListOptions{})
if err != nil {
return fmt.Errorf("failed to fetch Instances from namespace %q: %v", ns, err)
}
for _, i := range l.Items {
i := i
if err := f(&i); err != nil {
return fmt.Errorf("failed to run function for Instance \"%s/%s\": %v", i.Namespace, i.Name, err)
}
}
return nil
}
20 changes: 10 additions & 10 deletions pkg/kudoctl/kudoinit/setup/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,9 @@ func (i *Installer) VerifyInstallation(client *kube.Client, result *verifier.Res
return nil
}

func requiredMigrations() []migration.Migrater {

func requiredMigrations(client *kube.Client, dryRun bool) []migration.Migrater {
// Determine which migrations to run
return []migration.Migrater{
// Implement actual migrations
}
return []migration.Migrater{}
}

func (i *Installer) PreUpgradeVerify(client *kube.Client, result *verifier.Result) error {
Expand All @@ -88,13 +85,16 @@ func (i *Installer) PreUpgradeVerify(client *kube.Client, result *verifier.Resul
return nil
}

// Step 2 - Verify that any migration is possible
migrations := requiredMigrations()
// Step 2 - Verify that all migrations can run (with dryRun)
migrations := requiredMigrations(client, true)
clog.V(1).Printf("Verify that %d required migrations can be applied", len(migrations))
for _, m := range migrations {
if err := m.CanMigrate(client); err != nil {
if err := m.CanMigrate(); err != nil {
result.AddErrors(fmt.Errorf("migration %s failed install check: %v", m, err).Error())
}
if err := m.Migrate(); err != nil {
result.AddErrors(fmt.Errorf("migration %s failed dry-run: %v", m, err).Error())
}
}

// TODO: Verify existing operators and instances?
Expand All @@ -117,10 +117,10 @@ func (i *Installer) Upgrade(client *kube.Client) error {
}

// Step 5 - Execute Migrations
migrations := requiredMigrations()
migrations := requiredMigrations(client, false)
clog.Printf("Run %d migrations", len(migrations))
for _, m := range migrations {
if err := m.Migrate(client); err != nil {
if err := m.Migrate(); err != nil {
return fmt.Errorf("migration %s failed to execute: %v", m, err)
}
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/kudoctl/packages/convert/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func FilesToResources(files *packages.Files) (*packages.Resources, error) {
APIVersion: packages.APIVersion,
},
ObjectMeta: metav1.ObjectMeta{
Name: kudoapi.OperatorVersionName(files.Operator.Name, files.Operator.OperatorVersion),
Name: kudoapi.OperatorVersionName(files.Operator.Name, files.Operator.AppVersion, files.Operator.OperatorVersion),
},
Spec: kudoapi.OperatorVersionSpec{
Operator: corev1.ObjectReference{
Expand All @@ -78,7 +78,7 @@ func FilesToResources(files *packages.Files) (*packages.Resources, error) {
Status: kudoapi.OperatorVersionStatus{},
}

instance := BuildInstanceResource(files.Operator.Name, files.Operator.OperatorVersion)
instance := BuildInstanceResource(files.Operator.Name, files.Operator.AppVersion, files.Operator.OperatorVersion)

return &packages.Resources{
Operator: operator,
Expand All @@ -87,7 +87,7 @@ func FilesToResources(files *packages.Files) (*packages.Resources, error) {
}, nil
}

func BuildInstanceResource(operatorName, operatorVersion string) *kudoapi.Instance {
func BuildInstanceResource(operatorName, appVersion, operatorVersion string) *kudoapi.Instance {
return &kudoapi.Instance{
TypeMeta: metav1.TypeMeta{
Kind: "Instance",
Expand All @@ -99,7 +99,7 @@ func BuildInstanceResource(operatorName, operatorVersion string) *kudoapi.Instan
},
Spec: kudoapi.InstanceSpec{
OperatorVersion: corev1.ObjectReference{
Name: kudoapi.OperatorVersionName(operatorName, operatorVersion),
Name: kudoapi.OperatorVersionName(operatorName, appVersion, operatorVersion),
},
},
Status: kudoapi.InstanceStatus{},
Expand Down
Loading