Skip to content

Commit

Permalink
feat(operators): reconcile v1 operator resources
Browse files Browse the repository at this point in the history
Enable the Operator API in v1 by default.
  • Loading branch information
njhale committed Jul 31, 2020
1 parent 1306e80 commit f018a71
Show file tree
Hide file tree
Showing 14 changed files with 72 additions and 223 deletions.
32 changes: 1 addition & 31 deletions cmd/olm/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,7 @@ package main

import (
"context"
"fmt"

"github.com/operator-framework/api/crds"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/log/zap"

Expand All @@ -30,14 +25,7 @@ func Manager(ctx context.Context) (ctrl.Manager, error) {

// Setup a new controller to reconcile Operators
setupLog.Info("configuring controller")
client, err := apiextensionsv1.NewForConfig(mgr.GetConfig())
if err != nil {
return nil, err
}

if feature.Gate.Enabled(feature.OperatorLifecycleManagerV2) {
setupLog.Info(fmt.Sprintf("feature enabled: %v", feature.OperatorLifecycleManagerV2))

if feature.Gate.Enabled(feature.OperatorLifecycleManagerV1) {
operatorReconciler, err := operators.NewOperatorReconciler(
mgr.GetClient(),
ctrl.Log.WithName("controllers").WithName("operator"),
Expand All @@ -47,24 +35,6 @@ func Manager(ctx context.Context) (ctrl.Manager, error) {
return nil, err
}

crd, err := client.CustomResourceDefinitions().Create(ctx, crds.Operator(), metav1.CreateOptions{})
if err != nil {
if !apierrors.IsAlreadyExists(err) {
return nil, err
}

// Already exists, try to update
if crd, err = client.CustomResourceDefinitions().Get(ctx, crds.Operator().GetName(), metav1.GetOptions{}); err != nil {
return nil, err
}

crd.Spec = crds.Operator().Spec
if _, err = client.CustomResourceDefinitions().Update(ctx, crd, metav1.UpdateOptions{}); err != nil {
return nil, err
}
}
setupLog.Info("v2alpha1 CRDs installed")

if err = operatorReconciler.SetupWithManager(mgr); err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/controller/operators/adoption_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import (
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"

operatorsv1 "github.com/operator-framework/api/pkg/operators/v1"
operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
operatorsv2alpha1 "github.com/operator-framework/api/pkg/operators/v2alpha1"
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/decorators"
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil"
)
Expand Down Expand Up @@ -224,7 +224,7 @@ func (r *AdoptionReconciler) adoptComponents(ctx context.Context, csv *operators

var operators []decorators.Operator
for _, name := range decorators.OperatorNames(csv.GetLabels()) {
o := &operatorsv2alpha1.Operator{}
o := &operatorsv1.Operator{}
o.SetName(name.Name)
operator, err := r.factory.NewOperator(o)
if err != nil {
Expand Down
18 changes: 9 additions & 9 deletions pkg/controller/operators/decorators/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/tools/reference"

operatorsv2alpha1 "github.com/operator-framework/api/pkg/operators/v2alpha1"
operatorsv1 "github.com/operator-framework/api/pkg/operators/v1"
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/codec"
)

Expand Down Expand Up @@ -47,7 +47,7 @@ func OperatorNames(labels map[string]string) (names []types.NamespacedName) {
type OperatorFactory interface {
// NewOperator returns an Operator decorator that wraps the given external Operator representation.
// An error is returned if the decorator cannon be instantiated.
NewOperator(external *operatorsv2alpha1.Operator) (*Operator, error)
NewOperator(external *operatorsv1.Operator) (*Operator, error)

// NewPackageOperator returns an Operator decorator for a package and install namespace.
NewPackageOperator(pkg, namespace string) (*Operator, error)
Expand All @@ -58,7 +58,7 @@ type schemedOperatorFactory struct {
scheme *runtime.Scheme
}

func (s *schemedOperatorFactory) NewOperator(external *operatorsv2alpha1.Operator) (*Operator, error) {
func (s *schemedOperatorFactory) NewOperator(external *operatorsv1.Operator) (*Operator, error) {
if external == nil {
return nil, fmt.Errorf(newOperatorError, "cannot create operator with nil external type")
}
Expand All @@ -80,7 +80,7 @@ func (s *schemedOperatorFactory) NewPackageOperator(pkg, namespace string) (*Ope
name = fmt.Sprintf("%s.%s", pkg, namespace)
}

o := &operatorsv2alpha1.Operator{}
o := &operatorsv1.Operator{}
o.SetName(name)

return s.NewOperator(o)
Expand All @@ -99,7 +99,7 @@ func NewSchemedOperatorFactory(scheme *runtime.Scheme) (OperatorFactory, error)

// Operator decorates an external Operator and provides convenience methods for managing it.
type Operator struct {
*operatorsv2alpha1.Operator
*operatorsv1.Operator

scheme *runtime.Scheme
componentLabelKey string
Expand Down Expand Up @@ -188,7 +188,7 @@ func (o *Operator) ResetComponents() error {
return err
}

o.Status.Components = &operatorsv2alpha1.Components{
o.Status.Components = &operatorsv1.Components{
LabelSelector: labelSelector,
}

Expand Down Expand Up @@ -231,7 +231,7 @@ func (o *Operator) AddComponents(components ...runtime.Object) error {
return err
}

var refs []operatorsv2alpha1.RichReference
var refs []operatorsv1.RichReference
for _, obj := range components {
// Unpack nested components
if nested, err := meta.ExtractList(obj); err == nil {
Expand Down Expand Up @@ -318,12 +318,12 @@ func (c *Component) Matches(selector labels.Selector) (matches bool, err error)
return
}

func (c *Component) Reference() (ref *operatorsv2alpha1.RichReference, err error) {
func (c *Component) Reference() (ref *operatorsv1.RichReference, err error) {
truncated, err := c.truncatedReference()
if err != nil {
return
}
ref = &operatorsv2alpha1.RichReference{
ref = &operatorsv1.RichReference{
ObjectReference: truncated,
}

Expand Down
22 changes: 11 additions & 11 deletions pkg/controller/operators/decorators/operator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"k8s.io/apimachinery/pkg/types"
k8sscheme "k8s.io/client-go/kubernetes/scheme"

operatorsv2alpha1 "github.com/operator-framework/api/pkg/operators/v2alpha1"
operatorsv1 "github.com/operator-framework/api/pkg/operators/v1"
)

func TestOperatorNames(t *testing.T) {
Expand Down Expand Up @@ -88,13 +88,13 @@ func TestAddComponents(t *testing.T) {
require.NoError(t, k8sscheme.AddToScheme(scheme))

type fields struct {
operator *operatorsv2alpha1.Operator
operator *operatorsv1.Operator
}
type args struct {
components []runtime.Object
}
type results struct {
operator *operatorsv2alpha1.Operator
operator *operatorsv1.Operator
err error
}

Expand All @@ -107,8 +107,8 @@ func TestAddComponents(t *testing.T) {
{
description: "Empty/ComponentsAdded",
fields: fields{
operator: func() *operatorsv2alpha1.Operator {
operator := &operatorsv2alpha1.Operator{}
operator: func() *operatorsv1.Operator {
operator := &operatorsv1.Operator{}
operator.SetName("puffin")

return operator
Expand Down Expand Up @@ -144,10 +144,10 @@ func TestAddComponents(t *testing.T) {
},
},
results: results{
operator: func() *operatorsv2alpha1.Operator {
operator := &operatorsv2alpha1.Operator{}
operator: func() *operatorsv1.Operator {
operator := &operatorsv1.Operator{}
operator.SetName("puffin")
operator.Status.Components = &operatorsv2alpha1.Components{
operator.Status.Components = &operatorsv1.Components{
LabelSelector: &metav1.LabelSelector{
MatchExpressions: []metav1.LabelSelectorRequirement{
{
Expand All @@ -157,7 +157,7 @@ func TestAddComponents(t *testing.T) {
},
},
}
operator.Status.Components.Refs = []operatorsv2alpha1.RichReference{
operator.Status.Components.Refs = []operatorsv1.RichReference{
{
ObjectReference: &corev1.ObjectReference{
APIVersion: "v1",
Expand All @@ -172,9 +172,9 @@ func TestAddComponents(t *testing.T) {
Namespace: "atlantic",
Name: "puffin",
},
Conditions: []operatorsv2alpha1.Condition{
Conditions: []operatorsv1.Condition{
{
Type: operatorsv2alpha1.ConditionType(corev1.PodReady),
Type: operatorsv1.ConditionType(corev1.PodReady),
Status: corev1.ConditionTrue,
},
},
Expand Down
13 changes: 2 additions & 11 deletions pkg/controller/operators/olm/config.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
package olm

import (
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer"
"time"

"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/queueinformer"

"github.com/pkg/errors"
"github.com/sirupsen/logrus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilclock "k8s.io/apimachinery/pkg/util/clock"
"k8s.io/client-go/rest"

configv1client "github.com/openshift/client-go/config/clientset/versioned"
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/internalversion"
"github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned"
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/install"
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/registry/resolver"
Expand All @@ -29,7 +29,6 @@ type operatorConfig struct {
logger *logrus.Logger
operatorClient operatorclient.ClientInterface
externalClient versioned.Interface
internalClient internalversion.Interface
strategyResolver install.StrategyResolverInterface
apiReconciler resolver.APIIntersectionReconciler
apiLabeler labeler.Labeler
Expand Down Expand Up @@ -64,8 +63,6 @@ func (o *operatorConfig) validate() (err error) {
err = newInvalidConfigError("operator client", "must not be nil")
case o.externalClient == nil:
err = newInvalidConfigError("external client", "must not be nil")
// case o.internalClient == nil:
// err = newInvalidConfigError("internal client", "must not be nil")
case o.strategyResolver == nil:
err = newInvalidConfigError("strategy resolver", "must not be nil")
case o.apiReconciler == nil:
Expand Down Expand Up @@ -134,12 +131,6 @@ func WithExternalClient(externalClient versioned.Interface) OperatorOption {
}
}

func WithInternalClient(internalClient internalversion.Interface) OperatorOption {
return func(config *operatorConfig) {
config.internalClient = internalClient
}
}

func WithStrategyResolver(strategyResolver install.StrategyResolverInterface) OperatorOption {
return func(config *operatorConfig) {
config.strategyResolver = strategyResolver
Expand Down
9 changes: 4 additions & 5 deletions pkg/controller/operators/operator_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (

operatorsv1 "github.com/operator-framework/api/pkg/operators/v1"
operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
operatorsv2alpha1 "github.com/operator-framework/api/pkg/operators/v2alpha1"
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/decorators"
)

Expand All @@ -34,7 +33,7 @@ var (
apiregistrationv1.AddToScheme,
operatorsv1alpha1.AddToScheme,
operatorsv1.AddToScheme,
operatorsv2alpha1.AddToScheme,
operatorsv1.AddToScheme,
)

// AddToScheme adds all types necessary for the controller to operate.
Expand Down Expand Up @@ -67,7 +66,7 @@ func (r *OperatorReconciler) SetupWithManager(mgr ctrl.Manager) error {
// Note: If we want to support resources composed of custom resources, we need to figure out how
// to dynamically add resource types to watch.
return ctrl.NewControllerManagedBy(mgr).
For(&operatorsv2alpha1.Operator{}).
For(&operatorsv1.Operator{}).
Watches(&source.Kind{Type: &appsv1.Deployment{}}, enqueueOperator).
Watches(&source.Kind{Type: &corev1.Namespace{}}, enqueueOperator).
Watches(&source.Kind{Type: &corev1.ServiceAccount{}}, enqueueOperator).
Expand Down Expand Up @@ -118,7 +117,7 @@ func (r *OperatorReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {

// Fetch the Operator from the cache
ctx := context.TODO()
in := &operatorsv2alpha1.Operator{}
in := &operatorsv1.Operator{}
if err := r.Get(ctx, req.NamespacedName, in); err != nil {
if apierrors.IsNotFound(err) {
log.Info("Could not find Operator")
Expand Down Expand Up @@ -230,7 +229,7 @@ func (r *OperatorReconciler) mapComponentRequests(obj handler.MapObject) (reques

// Otherwise, best-effort generate a new operator
// TODO(njhale): Implement verification that the operator-discovery admission webhook accepted this label (JWT or maybe sign a set of fields?)
operator := &operatorsv2alpha1.Operator{}
operator := &operatorsv1.Operator{}
operator.SetName(name.Name)
if err := r.Create(context.Background(), operator); err != nil && !apierrors.IsAlreadyExists(err) {
r.log.Error(err, "couldn't generate operator", "operator", name, "component", obj.Meta.GetSelfLink())
Expand Down
16 changes: 8 additions & 8 deletions pkg/controller/operators/operator_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"

operatorsv2alpha1 "github.com/operator-framework/api/pkg/operators/v2alpha1"
operatorsv1 "github.com/operator-framework/api/pkg/operators/v1"
"github.com/operator-framework/operator-lifecycle-manager/pkg/controller/operators/decorators"
"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/testobj"
)

var _ = Describe("Operator Controller", func() {
var (
ctx context.Context
operator *operatorsv2alpha1.Operator
operator *operatorsv1.Operator
name types.NamespacedName
expectedKey string
expectedComponentLabelSelector *metav1.LabelSelector
Expand Down Expand Up @@ -49,7 +49,7 @@ var _ = Describe("Operator Controller", func() {

Describe("component selection", func() {
BeforeEach(func() {
Eventually(func() (*operatorsv2alpha1.Components, error) {
Eventually(func() (*operatorsv1.Components, error) {
err := k8sClient.Get(ctx, name, operator)
return operator.Status.Components, err
}, timeout, interval).ShouldNot(BeNil())
Expand All @@ -62,7 +62,7 @@ var _ = Describe("Operator Controller", func() {

Context("with no components bearing its label", func() {
Specify("a status containing no component references", func() {
Consistently(func() ([]operatorsv2alpha1.RichReference, error) {
Consistently(func() ([]operatorsv1.RichReference, error) {
err := k8sClient.Get(ctx, name, operator)
return operator.Status.Components.Refs, err
}, timeout, interval).Should(BeEmpty())
Expand All @@ -72,7 +72,7 @@ var _ = Describe("Operator Controller", func() {
Context("with components bearing its label", func() {
var (
objs []runtime.Object
expectedRefs []operatorsv2alpha1.RichReference
expectedRefs []operatorsv1.RichReference
namespace string
)

Expand All @@ -97,7 +97,7 @@ var _ = Describe("Operator Controller", func() {
})

Specify("a status containing its component references", func() {
Eventually(func() ([]operatorsv2alpha1.RichReference, error) {
Eventually(func() ([]operatorsv1.RichReference, error) {
err := k8sClient.Get(ctx, name, operator)
return operator.Status.Components.Refs, err
}, timeout, interval).Should(ConsistOf(expectedRefs))
Expand Down Expand Up @@ -133,7 +133,7 @@ var _ = Describe("Operator Controller", func() {
})

It("should add the component references", func() {
Eventually(func() ([]operatorsv2alpha1.RichReference, error) {
Eventually(func() ([]operatorsv1.RichReference, error) {
err := k8sClient.Get(ctx, name, operator)
return operator.Status.Components.Refs, err
}, timeout, interval).Should(ConsistOf(expectedRefs))
Expand All @@ -148,7 +148,7 @@ var _ = Describe("Operator Controller", func() {
})

It("should remove the component references", func() {
Eventually(func() ([]operatorsv2alpha1.RichReference, error) {
Eventually(func() ([]operatorsv1.RichReference, error) {
err := k8sClient.Get(ctx, name, operator)
return operator.Status.Components.Refs, err
}, timeout, interval).Should(BeEmpty())
Expand Down
Loading

0 comments on commit f018a71

Please sign in to comment.