Skip to content

Commit 75482d9

Browse files
authored
[resolution pt.7] resolver integration (#101)
* add bundle path to operator resource status * integrate resolver with reconciler Signed-off-by: perdasilva <[email protected]>
1 parent f7397a3 commit 75482d9

File tree

5 files changed

+152
-43
lines changed

5 files changed

+152
-43
lines changed

api/v1alpha1/operator_types.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ const (
3232
// TODO(user): add more Types, here and into init()
3333
TypeReady = "Ready"
3434

35-
// TODO(user): add more Reasons, here and into init()
36-
ReasonNotImplemented = "NotImplemented"
35+
ReasonNotImplemented = "NotImplemented"
36+
ReasonResolutionFailed = "ResolutionFailed"
37+
ReasonResolutionSucceeded = "ResolutionSucceeded"
3738
)
3839

3940
func init() {
@@ -54,6 +55,7 @@ type OperatorStatus struct {
5455
// +listType=map
5556
// +listMapKey=type
5657
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"`
58+
BundlePath string `json:"BundlePath,omitempty"`
5759
}
5860

5961
//+kubebuilder:object:root=true

config/crd/bases/operators.operatorframework.io_operators.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ spec:
4545
status:
4646
description: OperatorStatus defines the observed state of Operator
4747
properties:
48+
BundlePath:
49+
type: string
4850
conditions:
4951
items:
5052
description: "Condition contains details for one aspect of the current

controllers/operator_controller.go

Lines changed: 51 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ package controllers
1818

1919
import (
2020
"context"
21+
"strings"
2122

23+
operatorsv1alpha1 "github.com/operator-framework/operator-controller/api/v1alpha1"
24+
"github.com/operator-framework/operator-controller/internal/resolution"
2225
"k8s.io/apimachinery/pkg/api/equality"
2326
apimeta "k8s.io/apimachinery/pkg/api/meta"
2427
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -27,14 +30,14 @@ import (
2730
ctrl "sigs.k8s.io/controller-runtime"
2831
"sigs.k8s.io/controller-runtime/pkg/client"
2932
"sigs.k8s.io/controller-runtime/pkg/log"
30-
31-
operatorsv1alpha1 "github.com/operator-framework/operator-controller/api/v1alpha1"
3233
)
3334

3435
// OperatorReconciler reconciles a Operator object
3536
type OperatorReconciler struct {
3637
client.Client
3738
Scheme *runtime.Scheme
39+
40+
resolver *resolution.OperatorResolver
3841
}
3942

4043
//+kubebuilder:rbac:groups=operators.operatorframework.io,resources=operators,verbs=get;list;watch;create;update;patch;delete
@@ -97,24 +100,60 @@ func checkForUnexpectedFieldChange(a, b operatorsv1alpha1.Operator) bool {
97100
// Helper function to do the actual reconcile
98101
func (r *OperatorReconciler) reconcile(ctx context.Context, op *operatorsv1alpha1.Operator) (ctrl.Result, error) {
99102

100-
// TODO(user): change ReasonNotImplemented when functionality added
101-
readyCondition := metav1.Condition{
102-
Type: operatorsv1alpha1.TypeReady,
103-
Status: metav1.ConditionFalse,
104-
Reason: operatorsv1alpha1.ReasonNotImplemented,
105-
Message: "The Reconcile operation is not implemented",
106-
ObservedGeneration: op.GetGeneration(),
103+
// todo(perdasilva): this is a _hack_ we probably want to find a better way to ride or die resolve and update
104+
solution, err := r.resolver.Resolve(ctx)
105+
status := metav1.ConditionTrue
106+
reason := operatorsv1alpha1.ReasonResolutionSucceeded
107+
message := "resolution was successful"
108+
if err != nil {
109+
status = metav1.ConditionTrue
110+
reason = operatorsv1alpha1.ReasonResolutionFailed
111+
message = err.Error()
107112
}
108-
apimeta.SetStatusCondition(&op.Status.Conditions, readyCondition)
109113

110-
// TODO(user): your logic here
114+
// todo(perdasilva): more hacks - need to fix up the solution structure to be more useful
115+
packageVariableIDMap := map[string]string{}
116+
for variableID, ok := range solution {
117+
if ok {
118+
idComponents := strings.Split(string(variableID), "/")
119+
packageVariableIDMap[idComponents[1]] = string(variableID)
120+
}
121+
}
122+
123+
operatorList := &operatorsv1alpha1.OperatorList{}
124+
if err := r.Client.List(ctx, operatorList); err != nil {
125+
return ctrl.Result{}, err
126+
}
127+
128+
for _, operator := range operatorList.Items {
129+
apimeta.SetStatusCondition(&operator.Status.Conditions, metav1.Condition{
130+
Type: operatorsv1alpha1.TypeReady,
131+
Status: status,
132+
Reason: reason,
133+
Message: message,
134+
ObservedGeneration: op.GetGeneration(),
135+
})
136+
if varID, ok := packageVariableIDMap[operator.Spec.PackageName]; ok {
137+
operator.Status.BundlePath = varID
138+
}
139+
if err := r.Client.Status().Update(ctx, &operator); err != nil {
140+
return ctrl.Result{}, err
141+
}
142+
}
111143

112144
return ctrl.Result{}, nil
113145
}
114146

115147
// SetupWithManager sets up the controller with the Manager.
116148
func (r *OperatorReconciler) SetupWithManager(mgr ctrl.Manager) error {
117-
return ctrl.NewControllerManagedBy(mgr).
149+
r.resolver = resolution.NewOperatorResolver(mgr.GetClient(), resolution.HardcodedEntitySource)
150+
151+
err := ctrl.NewControllerManagedBy(mgr).
118152
For(&operatorsv1alpha1.Operator{}).
119153
Complete(r)
154+
155+
if err != nil {
156+
return err
157+
}
158+
return nil
120159
}

controllers/suite_test.go

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -21,38 +21,39 @@ import (
2121
"fmt"
2222
"path/filepath"
2323
"testing"
24+
"time"
2425

2526
. "github.com/onsi/ginkgo/v2"
2627
. "github.com/onsi/gomega"
27-
28+
operatorsv1alpha1 "github.com/operator-framework/operator-controller/api/v1alpha1"
29+
"github.com/operator-framework/operator-controller/controllers"
30+
operatorutil "github.com/operator-framework/operator-controller/internal/util"
2831
apimeta "k8s.io/apimachinery/pkg/api/meta"
2932
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
30-
"k8s.io/apimachinery/pkg/types"
3133
"k8s.io/apimachinery/pkg/util/rand"
3234
"k8s.io/client-go/kubernetes/scheme"
3335
"k8s.io/client-go/rest"
36+
ctrl "sigs.k8s.io/controller-runtime"
3437
"sigs.k8s.io/controller-runtime/pkg/client"
3538
"sigs.k8s.io/controller-runtime/pkg/envtest"
3639
logf "sigs.k8s.io/controller-runtime/pkg/log"
3740
"sigs.k8s.io/controller-runtime/pkg/log/zap"
38-
"sigs.k8s.io/controller-runtime/pkg/reconcile"
39-
40-
operatorsv1alpha1 "github.com/operator-framework/operator-controller/api/v1alpha1"
41-
"github.com/operator-framework/operator-controller/controllers"
42-
operatorutil "github.com/operator-framework/operator-controller/internal/util"
4341
//+kubebuilder:scaffold:imports
4442
)
4543

4644
// These tests use Ginkgo (BDD-style Go testing framework). Refer to
4745
// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.
4846

49-
var cfg *rest.Config
50-
var k8sClient client.Client
51-
var testEnv *envtest.Environment
47+
var (
48+
cfg *rest.Config
49+
k8sClient client.Client
50+
testEnv *envtest.Environment
51+
ctx context.Context
52+
cancel context.CancelFunc
53+
)
5254

5355
func TestAPIs(t *testing.T) {
5456
RegisterFailHandler(Fail)
55-
5657
RunSpecs(t, "Controller Suite")
5758
}
5859

@@ -80,15 +81,39 @@ var _ = BeforeSuite(func() {
8081
Expect(err).NotTo(HaveOccurred())
8182
Expect(k8sClient).NotTo(BeNil())
8283

84+
k8sManager, err := ctrl.NewManager(cfg, ctrl.Options{
85+
Scheme: scheme.Scheme,
86+
})
87+
Expect(err).ToNot(HaveOccurred())
88+
89+
err = (&controllers.OperatorReconciler{
90+
Client: k8sManager.GetClient(),
91+
Scheme: k8sManager.GetScheme(),
92+
}).SetupWithManager(k8sManager)
93+
Expect(err).ToNot(HaveOccurred())
94+
95+
ctx, cancel = context.WithCancel(context.Background())
96+
go func() {
97+
defer GinkgoRecover()
98+
err = k8sManager.Start(ctx)
99+
Expect(err).ToNot(HaveOccurred(), "failed to run manager")
100+
}()
101+
83102
})
84103

85104
var _ = AfterSuite(func() {
105+
cancel()
86106
By("tearing down the test environment")
87107
err := testEnv.Stop()
88108
Expect(err).NotTo(HaveOccurred())
89109
})
90110

91111
var _ = Describe("Reconcile Test", func() {
112+
const (
113+
timeout = time.Second * 10
114+
interval = time.Millisecond * 250
115+
)
116+
92117
When("an Operator is created", func() {
93118
var (
94119
operator *operatorsv1alpha1.Operator
@@ -99,10 +124,8 @@ var _ = Describe("Reconcile Test", func() {
99124
)
100125
BeforeEach(func() {
101126
ctx = context.Background()
102-
103127
opName = fmt.Sprintf("operator-test-%s", rand.String(8))
104128
pkgName = fmt.Sprintf("package-test-%s", rand.String(8))
105-
106129
operator = &operatorsv1alpha1.Operator{
107130
ObjectMeta: metav1.ObjectMeta{
108131
Name: opName,
@@ -113,29 +136,21 @@ var _ = Describe("Reconcile Test", func() {
113136
}
114137
err = k8sClient.Create(ctx, operator)
115138
Expect(err).To(Not(HaveOccurred()))
116-
117-
or := controllers.OperatorReconciler{
118-
k8sClient,
119-
scheme.Scheme,
120-
}
121-
_, err = or.Reconcile(ctx, reconcile.Request{
122-
NamespacedName: types.NamespacedName{
123-
Name: opName,
124-
},
125-
})
126-
Expect(err).To(Not(HaveOccurred()))
127139
})
128140
AfterEach(func() {
129141
err = k8sClient.Delete(ctx, operator)
130142
Expect(err).To(Not(HaveOccurred()))
131143
})
132144
It("has all Conditions created", func() {
133145
op := &operatorsv1alpha1.Operator{}
134-
135-
err = k8sClient.Get(ctx, client.ObjectKey{
136-
Name: opName,
137-
}, op)
138-
Expect(err).To(Not(HaveOccurred()))
146+
opLookupKey := client.ObjectKey{Name: opName}
147+
Eventually(func() bool {
148+
err := k8sClient.Get(ctx, opLookupKey, op)
149+
if err != nil {
150+
return false
151+
}
152+
return len(op.Status.Conditions) > 0
153+
}, timeout, interval).Should(BeTrue())
139154

140155
// All defined condition Types MUST exist after reconciliation
141156
conds := op.Status.Conditions

internal/resolution/bundle_cache.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package resolution
2+
3+
import (
4+
"github.com/operator-framework/deppy/pkg/deppy"
5+
"github.com/operator-framework/deppy/pkg/deppy/input"
6+
)
7+
8+
var HardcodedEntitySource = input.NewCacheQuerier(map[deppy.Identifier]input.Entity{
9+
"operatorhub/prometheus/0.14.0": *input.NewEntity("operatorhub/prometheus/0.14.0", map[string]string{
10+
"olm.bundle.path": `"quay.io/operatorhubio/prometheus@sha256:c78cc60ad05445f423c66e37c464bc9f520f0c0741cfd351b4f839ae0b99bd4b"`,
11+
"olm.channel": "{\"channelName\":\"beta\",\"priority\":0}",
12+
"olm.gvk": "[{\"group\":\"monitoring.coreos.com\",\"kind\":\"Alertmanager\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Alertmanager\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Prometheus\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Prometheus\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"ServiceMonitor\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"ServiceMonitor\",\"version\":\"v1\"}]",
13+
"olm.package": "{\"packageName\":\"prometheus\",\"version\":\"0.14.0\"}",
14+
}),
15+
"operatorhub/prometheus/0.15.0": *input.NewEntity("operatorhub/prometheus/0.15.0", map[string]string{
16+
"olm.bundle.path": `"quay.io/operatorhubio/prometheus@sha256:0a5a122cef6fabebcb82122bb4f5c4fbfa205454d109987b8af71672c8ac5c0e"`,
17+
"olm.channel": "{\"channelName\":\"beta\",\"priority\":0,\"replaces\":\"prometheusoperator.0.14.0\"}",
18+
"olm.gvk": "[{\"group\":\"monitoring.coreos.com\",\"kind\":\"Alertmanager\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Alertmanager\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Prometheus\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Prometheus\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"ServiceMonitor\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"ServiceMonitor\",\"version\":\"v1\"}]",
19+
"olm.package": "{\"packageName\":\"prometheus\",\"version\":\"0.15.0\"}",
20+
}),
21+
"operatorhub/prometheus/0.22.2": *input.NewEntity("operatorhub/prometheus/0.22.2", map[string]string{
22+
"olm.bundle.path": `"quay.io/operatorhubio/prometheus@sha256:f24b92e70ffb3bf33cc2a142f8b7a6519d28c90aa5742ddd37ac4fcecb5e5a52"`,
23+
"olm.channel": "{\"channelName\":\"beta\",\"priority\":0,\"replaces\":\"prometheusoperator.0.15.0\"}",
24+
"olm.gvk": "[{\"group\":\"monitoring.coreos.com\",\"kind\":\"Alertmanager\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Alertmanager\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Prometheus\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Prometheus\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"PrometheusRule\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"PrometheusRule\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"ServiceMonitor\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"ServiceMonitor\",\"version\":\"v1\"}]",
25+
"olm.package": "{\"packageName\":\"prometheus\",\"version\":\"0.22.2\"}",
26+
}),
27+
"operatorhub/prometheus/0.27.0": *input.NewEntity("operatorhub/prometheus/0.27.0", map[string]string{
28+
"olm.bundle.path": `"quay.io/operatorhubio/prometheus@sha256:7aace7b24fa2587c61d37d8676e23ea24dce03f1751b94614c6af60fba364f63"`,
29+
"olm.channel": "{\"channelName\":\"beta\",\"priority\":0,\"replaces\":\"prometheusoperator.0.22.2\"}",
30+
"olm.gvk": "[{\"group\":\"monitoring.coreos.com\",\"kind\":\"Alertmanager\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Alertmanager\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Prometheus\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Prometheus\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"PrometheusRule\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"PrometheusRule\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"ServiceMonitor\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"ServiceMonitor\",\"version\":\"v1\"}]",
31+
"olm.package": "{\"packageName\":\"prometheus\",\"version\":\"0.27.0\"}",
32+
}),
33+
"operatorhub/prometheus/0.32.0": *input.NewEntity("operatorhub/prometheus/0.32.0", map[string]string{
34+
"olm.bundle.path": `"quay.io/operatorhubio/prometheus@sha256:14f75077f01feab351f7a046ccfcff6ad357bed2393048d0f6a41f6e64c63278"`,
35+
"olm.channel": "{\"channelName\":\"beta\",\"priority\":0,\"replaces\":\"prometheusoperator.0.27.0\"}",
36+
"olm.gvk": "[{\"group\":\"monitoring.coreos.com\",\"kind\":\"Alertmanager\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Alertmanager\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"PodMonitor\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"PodMonitor\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Prometheus\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Prometheus\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"PrometheusRule\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"PrometheusRule\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"ServiceMonitor\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"ServiceMonitor\",\"version\":\"v1\"}]",
37+
"olm.package": "{\"packageName\":\"prometheus\",\"version\":\"0.32.0\"}",
38+
}),
39+
"operatorhub/prometheus/0.37.0": *input.NewEntity("operatorhub/prometheus/0.37.0", map[string]string{
40+
"olm.bundle.path": `"quay.io/operatorhubio/prometheus@sha256:3e281e587de3d03011440685fc4fb782672beab044c1ebadc42788ce05a21c35"`,
41+
"olm.channel": "{\"channelName\":\"beta\",\"priority\":0,\"replaces\":\"prometheusoperator.0.32.0\"}",
42+
"olm.gvk": "[{\"group\":\"monitoring.coreos.com\",\"kind\":\"Alertmanager\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Alertmanager\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"PodMonitor\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"PodMonitor\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Prometheus\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Prometheus\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"PrometheusRule\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"PrometheusRule\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"ServiceMonitor\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"ServiceMonitor\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"ThanosRuler\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"ThanosRuler\",\"version\":\"v1\"}]",
43+
"olm.package": "{\"packageName\":\"prometheus\",\"version\":\"0.37.0\"}",
44+
}),
45+
"operatorhub/prometheus/0.47.0": *input.NewEntity("operatorhub/prometheus/0.47.0", map[string]string{
46+
"olm.bundle.path": `"quay.io/operatorhubio/prometheus@sha256:5b04c49d8d3eff6a338b56ec90bdf491d501fe301c9cdfb740e5bff6769a21ed"`,
47+
"olm.channel": "{\"channelName\":\"beta\",\"priority\":0,\"replaces\":\"prometheusoperator.0.37.0\"}",
48+
"olm.gvk": "[{\"group\":\"monitoring.coreos.com\",\"kind\":\"Alertmanager\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Alertmanager\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"AlertmanagerConfig\",\"version\":\"v1alpha1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"AlertmanagerConfig\",\"version\":\"v1alpha1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"PodMonitor\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"PodMonitor\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Probe\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Probe\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Prometheus\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"Prometheus\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"PrometheusRule\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"PrometheusRule\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"ServiceMonitor\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"ServiceMonitor\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"ThanosRuler\",\"version\":\"v1\"},{\"group\":\"monitoring.coreos.com\",\"kind\":\"ThanosRuler\",\"version\":\"v1\"}]",
49+
"olm.package": "{\"packageName\":\"prometheus\",\"version\":\"0.47.0\"}",
50+
}),
51+
})

0 commit comments

Comments
 (0)