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

Handle when particular resource does not exists on cluster #6369

Closed
josericardomcastro opened this issue Mar 22, 2023 · 5 comments
Closed

Handle when particular resource does not exists on cluster #6369

josericardomcastro opened this issue Mar 22, 2023 · 5 comments
Assignees
Labels
language/go Issue is related to a Go operator project triage/support Indicates an issue that is a support question.
Milestone

Comments

@josericardomcastro
Copy link

Type of question

How to implement a specific feature

Question

What did you do?

I am creating an operator to watch and reconcile many resources, deployment, ingress and routes (Openshift). I plan to use and test the same version of this operator in many diffferent clusters (EKS, AKS, GKE and OCP-Openshift Cluster).

in the main.go file im adding the resources

import (
...
	routev1 "github.com/openshift/api/route/v1"
	clientgoscheme "k8s.io/client-go/kubernetes/scheme"
...
)
func init() {
	utilruntime.Must(clientgoscheme.AddToScheme(scheme))
	utilruntime.Must(routev1.AddToScheme(scheme))

	//+kubebuilder:scaffold:scheme
}

func main() {
...
        if err = (&controllers.IngressReconciler{
	        Client: mgr.GetClient(),
	        Scheme: mgr.GetScheme(),
        }).SetupWithManager(mgr); err != nil {
	        setupLog.Error(err, "unable to create controller", "controller", "Ingress")
	        os.Exit(1)
        }
        
        if err = (&controllers.RouteReconciler{
	        Client: mgr.GetClient(),
	        Scheme: mgr.GetScheme(),
        }).SetupWithManager(mgr); err != nil {
	        setupLog.Error(err, "unable to create controller", "controller", "Route")
	        os.Exit(1)
        }
...
}

But in some cases i will use this operator on cluster that does not have/know the resource Route.

So, is there a way to check if the resource exists first and handle the error?

What did you expect to see?

No errors when i run the operator on any cluster.

What did you see instead? Under which circumstances?

Any cluster, except and Openshift cluster.

1.679423138669724e+09   ERROR   controller-runtime.source       
if kind is a CRD, it should be installed before calling Start        {"kind": "Route.route.openshift.io", "error": "no matches for kind \"Route\" in version \"route.openshift.io/v1\""}
sigs.k8s.io/controller-runtime/pkg/source.(*Kind).Start.func1.1

Environment

Operator type:

/language go

Kubernetes cluster type:

Minukube, EKS and OpenShift

$ operator-sdk version

operator-sdk version: "v1.27.0", commit: "5cbdad9209332043b7c730856b6302edc8996faf", kubernetes version: "v1.25.0", go version: "go1.19.5", GOOS: "darwin", GOARCH: "arm64"

$ go version

go version go1.20.2 darwin/arm64

$ kubectl version

Client Version: version.Info{Major:"1", Minor:"26", GitVersion:"v1.26.1", GitCommit:"8f94681cd294aa8cfd3407b8191f6c70214973a4", GitTreeState:"clean", BuildDate:"2023-01-18T15:51:24Z", GoVersion:"go1.19.5", Compiler:"gc", Platform:"darwin/arm64"}
Kustomize Version: v4.5.7
Server Version: version.Info{Major:"1", Minor:"23+", GitVersion:"v1.23.14-eks-ffeb93d", GitCommit:"96e7d52c98a32f2b296ca7f19dc9346cf79915ba", GitTreeState:"clean", BuildDate:"2022-11-29T18:43:31Z", GoVersion:"go1.17.13", Compiler:"gc", Platform:"linux/amd64"}
WARNING: version difference between client (1.26) and server (1.23) exceeds the supported minor version skew of +/-1
@openshift-ci openshift-ci bot added the language/go Issue is related to a Go operator project label Mar 22, 2023
@jberkhahn jberkhahn added the triage/support Indicates an issue that is a support question. label Mar 27, 2023
@jberkhahn
Copy link
Contributor

/assign @OchiengEd

@openshift-ci
Copy link

openshift-ci bot commented Mar 27, 2023

@jberkhahn: GitHub didn't allow me to assign the following users: OchiengEd.

Note that only operator-framework members with read permissions, repo collaborators and people who have commented on this issue/PR can be assigned. Additionally, issues/PRs can only have 10 assignees at the same time.
For more information please see the contributor guide

In response to this:

/assign @OchiengEd

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@OchiengEd
Copy link
Contributor

I will take a look at this.

@jberkhahn jberkhahn added this to the Backlog milestone Mar 27, 2023
@OchiengEd
Copy link
Contributor

Hi @josericardomcastro , to answer your specific question you might need to add a helper function. For example we can call it has hasRoutes and will appear as below:

func hasRoute(kclient *kubernetes.ClientSet) bool {
       // OpenShift route group and version
  	routeGV := schema.GroupVersion{
		Group:   "route.openshift.io",
		Version: "v1",
	}

	if err := discovery.ServerSupportsVersion(kclient, routeGV); err != nil {
		return false
	}
	
	return true
}

To implement the above function, you will need to to import the following golang modules:

  • k8s.io/apimachinery/pkg/runtime/schema
  • k8s.io/client-go/discovery

On a sidenote, looking at the code snippet you shared, I am inclined to ask if Ingress and Routes are primary resources managed by your operator. For example, a MySQL resource would be the primary resource managed by a mysql-operator whereas statefulsets, secrets, configmaps, etc would be secondary resources.

If Routes and Ingress objects are secondary resources in your operator, they should not have reconcilers defined in your main.go.

This is in reference to the following code block:

        if err = (&controllers.IngressReconciler{
	        Client: mgr.GetClient(),
	        Scheme: mgr.GetScheme(),
        }).SetupWithManager(mgr); err != nil {
	        setupLog.Error(err, "unable to create controller", "controller", "Ingress")
	        os.Exit(1)
        }
        
        if err = (&controllers.RouteReconciler{
	        Client: mgr.GetClient(),
	        Scheme: mgr.GetScheme(),
        }).SetupWithManager(mgr); err != nil {
	        setupLog.Error(err, "unable to create controller", "controller", "Route")
	        os.Exit(1)
        }

Lastly, the code section in the init function is correct.

@josericardomcastro
Copy link
Author

Hey @OchiengEd,

Thanks a lot for you help, your solution worked as expected for me.

And regarding your question, yes, the ingress/router are primary resources in my operator.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
language/go Issue is related to a Go operator project triage/support Indicates an issue that is a support question.
Projects
None yet
Development

No branches or pull requests

3 participants