Skip to content
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

WIP: Bump K8s modules, controller-runtime and KUTTL #1799

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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 cmd/manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ func main() {

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
CertDir: getEnv("KUDO_CERT_DIR", filepath.Join("/tmp", "cert")),
Port: 443,
SyncPeriod: syncPeriod,
})
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion config/crds/kudo.dev_instances.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.4.1
controller-gen.kubebuilder.io/version: v0.4.2-0.20210129215148-557da250b856
creationTimestamp: null
name: instances.kudo.dev
spec:
Expand Down
2 changes: 1 addition & 1 deletion config/crds/kudo.dev_operators.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.4.1
controller-gen.kubebuilder.io/version: v0.4.2-0.20210129215148-557da250b856
creationTimestamp: null
name: operators.kudo.dev
spec:
Expand Down
2 changes: 1 addition & 1 deletion config/crds/kudo.dev_operatorversions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.4.1
controller-gen.kubebuilder.io/version: v0.4.2-0.20210129215148-557da250b856
creationTimestamp: null
name: operatorversions.kudo.dev
spec:
Expand Down
28 changes: 13 additions & 15 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,33 +11,31 @@ require (
github.com/google/go-cmp v0.5.2
github.com/gosuri/uitable v0.0.4
github.com/huandu/xstrings v1.3.2 // indirect
github.com/kudobuilder/kuttl v0.8.1
github.com/kudobuilder/kuttl v0.9.0
github.com/manifoldco/promptui v0.8.0
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/moby/term v0.0.0-20200915141129-7f0af18e79f2 // indirect
github.com/onsi/ginkgo v1.14.1
github.com/onsi/gomega v1.10.2
github.com/spf13/afero v1.4.0
github.com/spf13/cobra v1.0.0
github.com/spf13/cobra v1.1.1
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.6.1
github.com/thoas/go-funk v0.7.0
github.com/xlab/treeprint v1.0.0
github.com/yourbasic/graph v0.0.0-20170921192928-40eb135c0b26
golang.org/x/net v0.0.0-20200904194848-62affa334b73 // indirect
golang.org/x/sync v0.0.0-20200930132711-30421366ff76
golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
golang.org/x/tools v0.0.0-20200616195046-dc31b401abb5 // indirect
gopkg.in/yaml.v2 v2.3.0
k8s.io/api v0.19.2
k8s.io/apiextensions-apiserver v0.19.2
k8s.io/apimachinery v0.19.2
k8s.io/cli-runtime v0.19.2
k8s.io/client-go v0.19.2
k8s.io/code-generator v0.19.2
k8s.io/component-base v0.19.2
k8s.io/kubectl v0.19.2
sigs.k8s.io/controller-runtime v0.6.3
sigs.k8s.io/controller-tools v0.4.1
k8s.io/api v0.20.2
k8s.io/apiextensions-apiserver v0.20.2
k8s.io/apimachinery v0.20.2
k8s.io/cli-runtime v0.20.2
k8s.io/client-go v0.20.2
k8s.io/code-generator v0.20.2
k8s.io/component-base v0.20.2
k8s.io/kubectl v0.20.2
sigs.k8s.io/controller-runtime v0.8.2
sigs.k8s.io/controller-tools v0.4.2-0.20210129215148-557da250b856
sigs.k8s.io/yaml v1.2.0
)
468 changes: 278 additions & 190 deletions go.sum

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion hack/run-operator-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ rm -rf operators
git clone https://github.com/kudobuilder/operators
mkdir operators/bin/
cp ./bin/kubectl-kudo operators/bin/
sed "s/%version%/$KUDO_VERSION/" operators/kudo-test.yaml.tmpl > operators/kudo-test.yaml

# TODO (asekretenko): Use kuttl directly instead of kudo test.
# This will obviate the need to patch apiVersion.
cat operators/kudo-test.yaml.tmpl | sed "s/%version%/$KUDO_VERSION/" | sed "s/apiVersion: kudo.dev\/v1alpha1/apiVersion: kuttl.dev\/v1beta1/" > operators/kudo-test.yaml

if [ "$INTEGRATION_OUTPUT_JUNIT" == true ]
then
Expand Down
59 changes: 29 additions & 30 deletions pkg/controller/instance/instance_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,34 +67,33 @@ type Reconciler struct {
// SetupWithManager registers this reconciler with the controller manager
func (r *Reconciler) SetupWithManager(
mgr ctrl.Manager) error {
addOvRelatedInstancesToReconcile := handler.ToRequestsFunc(
func(obj handler.MapObject) []reconcile.Request {
requests := make([]reconcile.Request, 0)
instances := &kudoapi.InstanceList{}
// we are listing all instances here, which could come with some performance penalty
// obj possible optimization is to introduce filtering based on operatorversion (or operator)
err := mgr.GetClient().List(
context.TODO(),
instances,
)
if err != nil {
log.Printf("InstanceController: Error fetching instances list for operator %v: %v", obj.Meta.GetName(), err)
return nil
}
for _, instance := range instances.Items {
// we need to pick only those instances, that belong to the OperatorVersion we're reconciling
if instance.Spec.OperatorVersion.Name == obj.Meta.GetName() &&
instance.OperatorVersionNamespace() == obj.Meta.GetNamespace() {
requests = append(requests, reconcile.Request{
NamespacedName: types.NamespacedName{
Name: instance.Name,
Namespace: instance.Namespace,
},
})
}
addOvRelatedInstancesToReconcile := func(obj client.Object) []reconcile.Request {
requests := make([]reconcile.Request, 0)
instances := &kudoapi.InstanceList{}
// we are listing all instances here, which could come with some performance penalty
// obj possible optimization is to introduce filtering based on operatorversion (or operator)
err := mgr.GetClient().List(
context.TODO(),
instances,
)
if err != nil {
log.Printf("InstanceController: Error fetching instances list for operator %v: %v", obj.GetName(), err)
return nil
}
for _, instance := range instances.Items {
// we need to pick only those instances, that belong to the OperatorVersion we're reconciling
if instance.Spec.OperatorVersion.Name == obj.GetName() &&
instance.OperatorVersionNamespace() == obj.GetNamespace() {
requests = append(requests, reconcile.Request{
NamespacedName: types.NamespacedName{
Name: instance.Name,
Namespace: instance.Namespace,
},
})
}
return requests
})
}
return requests
}

return ctrl.NewControllerManagedBy(mgr).
// Owns(&kudoapi.Instance{}) is equivalent to Watches(&source.Kind{Type: <ForType-apiType>},
Expand All @@ -112,7 +111,7 @@ func (r *Reconciler) SetupWithManager(
Owns(&appsv1.StatefulSet{}).
Owns(&corev1.Pod{}).
WithEventFilter(eventFilter()).
Watches(&source.Kind{Type: &kudoapi.OperatorVersion{}}, &handler.EnqueueRequestsFromMapFunc{ToRequests: addOvRelatedInstancesToReconcile}).
Watches(&source.Kind{Type: &kudoapi.OperatorVersion{}}, handler.EnqueueRequestsFromMapFunc(addOvRelatedInstancesToReconcile)).
Complete(r)
}

Expand All @@ -137,7 +136,7 @@ func eventFilter() predicate.Funcs {
}

func isForPipePod(e event.DeleteEvent) bool {
return e.Meta.GetAnnotations() != nil && funk.Contains(e.Meta.GetAnnotations(), task.PipePodAnnotation)
return e.Object.GetAnnotations() != nil && funk.Contains(e.Object.GetAnnotations(), task.PipePodAnnotation)
}

// Reconcile is the main controller method that gets called every time something about the instance changes
Expand Down Expand Up @@ -166,7 +165,7 @@ func isForPipePod(e event.DeleteEvent) bool {
// +-------------------------------+
//
// Automatically generate RBAC rules to allow the Controller to read and write Deployments
func (r *Reconciler) Reconcile(request ctrl.Request) (ctrl.Result, error) {
func (r *Reconciler) Reconcile(ctx context.Context, request ctrl.Request) (ctrl.Result, error) {
// ---------- 1. Query the current state ----------

log.Printf("InstanceController: Received Reconcile request for instance %s", request.NamespacedName)
Expand Down
6 changes: 2 additions & 4 deletions pkg/controller/instance/instance_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -272,17 +272,15 @@ func TestEventFilterForDelete(t *testing.T) {
e event.DeleteEvent
}{
{"A Pod without annotations", true, event.DeleteEvent{
Meta: &v1.Pod{},
Object: nil,
Object: &v1.Pod{},
DeleteStateUnknown: false,
}},
{"A Pod with pipePod annotation", false, event.DeleteEvent{
Meta: &v1.Pod{
Object: &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
Annotations: map[string]string{task.PipePodAnnotation: "true"},
},
},
Object: nil,
DeleteStateUnknown: false,
}},
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/controller/operator/operator_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ func (r *Reconciler) SetupWithManager(
// Reconcile reads that state of the cluster for an Operator object and makes changes based on the state read
// and what is in the Operator.Spec
// Automatically generate RBAC rules to allow the Controller to read and write Deployments
func (r *Reconciler) Reconcile(request ctrl.Request) (ctrl.Result, error) {
func (r *Reconciler) Reconcile(ctx context.Context, request ctrl.Request) (ctrl.Result, error) {
// Fetch the operator
operator := &kudoapi.Operator{}
err := r.Get(context.TODO(), request.NamespacedName, operator)
err := r.Get(ctx, request.NamespacedName, operator)
if err != nil {
if errors.IsNotFound(err) {
// Object not found, return. Created objects are automatically garbage collected.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ func (r *Reconciler) SetupWithManager(
// and what is in the OperatorVersion.Spec.
//
// Automatically generate RBAC rules to allow the Controller to read and write Deployments
func (r *Reconciler) Reconcile(request ctrl.Request) (ctrl.Result, error) {
func (r *Reconciler) Reconcile(ctx context.Context, request ctrl.Request) (ctrl.Result, error) {
// Fetch the operator version
operatorVersion := &kudoapi.OperatorVersion{}
err := r.Get(context.TODO(), request.NamespacedName, operatorVersion)
err := r.Get(ctx, request.NamespacedName, operatorVersion)
if err != nil {
if errors.IsNotFound(err) {
// Object not found, return. Created objects are automatically garbage collected.
Expand Down
6 changes: 3 additions & 3 deletions pkg/engine/renderer/dependencies_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ func TestGetResources(t *testing.T) {
taskObjects []*unstructured.Unstructured
client client.Client
}{
{name: "from api server", taskObjects: []*unstructured.Unstructured{}, client: fake.NewFakeClientWithScheme(scheme.Scheme, &cm)},
{name: "from task objects", taskObjects: []*unstructured.Unstructured{&cmUnstructured}, client: fake.NewFakeClientWithScheme(scheme.Scheme)},
{name: "from api server without annotation", taskObjects: []*unstructured.Unstructured{}, client: fake.NewFakeClientWithScheme(scheme.Scheme, cmWithoutAnnotation)},
{name: "from api server", taskObjects: []*unstructured.Unstructured{}, client: fake.NewClientBuilder().WithScheme(scheme.Scheme).WithRuntimeObjects(&cm).Build()},
{name: "from task objects", taskObjects: []*unstructured.Unstructured{&cmUnstructured}, client: fake.NewClientBuilder().WithScheme(scheme.Scheme).Build()},
{name: "from api server without annotation", taskObjects: []*unstructured.Unstructured{}, client: fake.NewClientBuilder().WithScheme(scheme.Scheme).WithRuntimeObjects(cmWithoutAnnotation).Build()},
}

for _, tt := range tests {
Expand Down
14 changes: 9 additions & 5 deletions pkg/engine/renderer/enhancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import (
// and annotations
// it also takes care of setting an owner of all the resources to the provided object
type Enhancer interface {
Apply(objs []runtime.Object, metadata Metadata) ([]runtime.Object, error)
Apply(objs []client.Object, metadata Metadata) ([]client.Object, error)
}

// DefaultEnhancer is implementation of Enhancer that applies the defined conventions by directly editing runtime.Objects (Unstructured).
Expand All @@ -31,7 +31,7 @@ type DefaultEnhancer struct {

// Apply accepts templates to be rendered in kubernetes and enhances them with our own KUDO conventions
// These include the way we name our objects and what labels we apply to them
func (de *DefaultEnhancer) Apply(sourceObjs []runtime.Object, metadata Metadata) ([]runtime.Object, error) {
func (de *DefaultEnhancer) Apply(sourceObjs []client.Object, metadata Metadata) ([]client.Object, error) {
unstructuredObjs := make([]*unstructured.Unstructured, 0, len(sourceObjs))

for _, obj := range sourceObjs {
Expand Down Expand Up @@ -99,8 +99,8 @@ func (de *DefaultEnhancer) addDependenciesHashes(unstructuredObjs []*unstructure
return nil
}

func (de *DefaultEnhancer) convertToTyped(unstructuredObjs []*unstructured.Unstructured) ([]runtime.Object, error) {
objs := make([]runtime.Object, 0, len(unstructuredObjs))
func (de *DefaultEnhancer) convertToTyped(unstructuredObjs []*unstructured.Unstructured) ([]client.Object, error) {
objs := make([]client.Object, 0, len(unstructuredObjs))
for _, uo := range unstructuredObjs {
obj, err := de.Scheme.New(uo.GroupVersionKind())
if err != nil {
Expand All @@ -113,7 +113,11 @@ func (de *DefaultEnhancer) convertToTyped(unstructuredObjs []*unstructured.Unstr
return nil, fmt.Errorf("%wconverting from unstructured failed: %v", engine.ErrFatalExecution, err)
}

objs = append(objs, obj)
clientObj, implementsClientObject := obj.(client.Object)
if !implementsClientObject {
return nil, fmt.Errorf("%wruntime.Object converted from unstructured does not implement client.Object", engine.ErrFatalExecution)
}
objs = append(objs, clientObj)
}
return objs, nil
}
Expand Down
Loading