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

Create a CSV webhook #516

Open
wants to merge 7 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 Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ COPY vendor/ vendor/
# Copy the project source
COPY api/ api/
COPY controllers/ controllers/
COPY webhook/ webhook/
COPY pkg/ pkg/
COPY config/ config/
COPY metrics/ metrics/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.openshift.io/serving-cert-secret-name: webhook-server-cert
creationTimestamp: null
name: odf-operator-webhook-service
spec:
ports:
- name: https
port: 443
protocol: TCP
targetPort: 9443
selector:
app.kubernetes.io/name: odf-operator
status:
loadBalancer: {}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ metadata:
categories: Storage
console.openshift.io/plugins: '["odf-console"]'
containerImage: quay.io/ocs-dev/odf-operator:latest
createdAt: "2024-11-21T13:20:34Z"
createdAt: "2025-01-15T08:04:37Z"
description: OpenShift Data Foundation provides a common control plane for storage
solutions on OpenShift Container Platform.
features.operators.openshift.io/token-auth-aws: "true"
Expand Down Expand Up @@ -372,23 +372,6 @@ spec:
control-plane: controller-manager
spec:
containers:
- args:
- --secure-listen-address=0.0.0.0:8443
- --upstream=http://127.0.0.1:8080/
- --logtostderr=true
- --v=0
image: registry.redhat.io/openshift4/ose-kube-rbac-proxy:v4.11.0
name: kube-rbac-proxy
ports:
- containerPort: 8443
name: https
resources: {}
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
- args:
- --health-probe-bind-address=:8081
- --metrics-bind-address=127.0.0.1:8080
Expand All @@ -413,6 +396,10 @@ spec:
initialDelaySeconds: 15
periodSeconds: 20
name: manager
ports:
- containerPort: 9443
name: webhook-server
protocol: TCP
readinessProbe:
httpGet:
path: /readyz
Expand All @@ -433,6 +420,27 @@ spec:
drop:
- ALL
readOnlyRootFilesystem: true
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
name: cert
readOnly: true
- args:
- --secure-listen-address=0.0.0.0:8443
- --upstream=http://127.0.0.1:8080/
- --logtostderr=true
- --v=0
image: registry.redhat.io/openshift4/ose-kube-rbac-proxy:v4.11.0
name: kube-rbac-proxy
ports:
- containerPort: 8443
name: https
resources: {}
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
securityContext:
runAsNonRoot: true
serviceAccountName: odf-operator-controller-manager
Expand All @@ -442,6 +450,11 @@ spec:
key: node.ocs.openshift.io/storage
operator: Equal
value: "true"
volumes:
- name: cert
secret:
defaultMode: 420
secretName: webhook-server-cert
- label:
app: odf-console
name: odf-console
Expand Down
1 change: 1 addition & 0 deletions config/default/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ namePrefix: odf-operator-
# endpoint w/o any authn/z, please comment the following line.
patchesStrategicMerge:
- manager_auth_proxy_patch.yaml
- manager_webhook_patch.yaml
Copy link
Contributor

Choose a reason for hiding this comment

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

why is this required?


# Mount the controller config file for loading manager configurations
# through a ComponentConfig type
Expand Down
1 change: 1 addition & 0 deletions config/manager/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
resources:
- manager.yaml
- webhook_service.yaml

generatorOptions:
disableNameSuffixHash: true
Expand Down
15 changes: 15 additions & 0 deletions config/manager/webhook_service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.openshift.io/serving-cert-secret-name: webhook-server-cert
name: webhook-service
namespace: system
spec:
ports:
- name: https
port: 443
protocol: TCP
targetPort: 9443
selector:
app.kubernetes.io/name: odf-operator
55 changes: 39 additions & 16 deletions controllers/clusterversion_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package controllers
import (
"context"
"fmt"
"time"

configv1 "github.com/openshift/api/config/v1"
"k8s.io/apimachinery/pkg/api/errors"
Expand All @@ -37,8 +38,9 @@ import (
// ClusterVersionReconciler reconciles a ClusterVersion object
type ClusterVersionReconciler struct {
client.Client
Scheme *runtime.Scheme
ConsolePort int
Scheme *runtime.Scheme
ConsolePort int
OperatorNamespace string
}

//+kubebuilder:rbac:groups=config.openshift.io,resources=clusterversions,verbs=get;list;watch;create;update;patch;delete
Expand All @@ -58,7 +60,28 @@ func (r *ClusterVersionReconciler) Reconcile(ctx context.Context, req ctrl.Reque
if err := r.Client.Get(context.TODO(), req.NamespacedName, &instance); err != nil {
return ctrl.Result{}, err
}
if err := r.ensureConsolePlugin(instance.Status.Desired.Version); err != nil {

if err := r.ensureOdfConsoleConfigMapAndService(); err != nil {
logger.Error(err, "Could not ensure configmap and service for odf-console deployment")
return ctrl.Result{}, err
}

csvList, err := util.GetNamespaceCSVs(ctx, r.Client, r.OperatorNamespace)
if err != nil {
return ctrl.Result{}, err
}

// Check if it is upgrade from 4.17 to 4.18
// The new CSVs won't exists while upgrading
// They will exists only after new operator has created a new subscription
if !util.AreMultipleOdfOperatorCsvsPresent(csvList) {
if err := util.ValidateCSVsPresent(csvList, EssentialCSVs...); err != nil {
logger.Error(err, "Could not ensure CSVs presence")
return ctrl.Result{Requeue: true, RequeueAfter: time.Second * 2}, nil
}
}

if err := r.ensureConsolePluginAndCLIDownload(instance.Status.Desired.Version); err != nil {
logger.Error(err, "Could not ensure compatibility for ODF consolePlugin")
return ctrl.Result{}, err
}
Expand All @@ -69,12 +92,7 @@ func (r *ClusterVersionReconciler) Reconcile(ctx context.Context, req ctrl.Reque
// SetupWithManager sets up the controller with the Manager.
func (r *ClusterVersionReconciler) SetupWithManager(mgr ctrl.Manager) error {
err := mgr.Add(manager.RunnableFunc(func(context.Context) error {
clusterVersion, err := util.DetermineOpenShiftVersion(r.Client)
if err != nil {
return err
}

return r.ensureConsolePlugin(clusterVersion)
return r.ensureOdfConsoleConfigMapAndService()
}))
if err != nil {
return err
Expand All @@ -85,15 +103,10 @@ func (r *ClusterVersionReconciler) SetupWithManager(mgr ctrl.Manager) error {
Complete(r)
}

func (r *ClusterVersionReconciler) ensureConsolePlugin(clusterVersion string) error {
func (r *ClusterVersionReconciler) ensureOdfConsoleConfigMapAndService() error {
logger := log.FromContext(context.TODO())
// The base path to where the request are sent
basePath := console.GetBasePath(clusterVersion)
nginxConf := console.NginxConf

// Customer portal link (CLI Tool download)
portalLink := console.CUSTOMER_PORTAL_LINK

// Get ODF console Deployment
odfConsoleDeployment := console.GetDeployment(OperatorNamespace)
err := r.Client.Get(context.TODO(), types.NamespacedName{
Expand Down Expand Up @@ -126,9 +139,19 @@ func (r *ClusterVersionReconciler) ensureConsolePlugin(clusterVersion string) er
return err
}

return nil
}

func (r *ClusterVersionReconciler) ensureConsolePluginAndCLIDownload(clusterVersion string) error {
logger := log.FromContext(context.TODO())
// The base path to where the request are sent
basePath := console.GetBasePath(clusterVersion)
// Customer portal link (CLI Tool download)
portalLink := console.CUSTOMER_PORTAL_LINK

// Create/Update ODF console ConsolePlugin
odfConsolePlugin := console.GetConsolePluginCR(r.ConsolePort, OperatorNamespace)
_, err = controllerutil.CreateOrUpdate(context.TODO(), r.Client, odfConsolePlugin, func() error {
_, err := controllerutil.CreateOrUpdate(context.TODO(), r.Client, odfConsolePlugin, func() error {
if odfConsolePlugin.Spec.Backend.Service != nil {
if currentBasePath := odfConsolePlugin.Spec.Backend.Service.BasePath; currentBasePath != basePath {
logger.Info(fmt.Sprintf("Set the BasePath for odf-console plugin as '%s'", basePath))
Expand Down
8 changes: 8 additions & 0 deletions controllers/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,14 @@ const (
OdfSubscriptionPackage = "odf-operator"
)

var (
EssentialCSVs = []string{
OcsSubscriptionStartingCSV,
RookSubscriptionStartingCSV,
NoobaaSubscriptionStartingCSV,
}
)

func GetEnvOrDefault(env string) string {
if val := os.Getenv(env); val != "" {
return val
Expand Down
2 changes: 1 addition & 1 deletion controllers/delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func TestDeleteResources(t *testing.T) {
assert.NoError(t, err)
}

err = fakeReconciler.deleteResources(fakeStorageSystem, fakeReconciler.Log)
err = fakeReconciler.deleteResources(fakeStorageSystem, fakeLogger)
assert.True(t, (tc.expectedError == (err != nil)))

// verify resource does not exist
Expand Down
6 changes: 3 additions & 3 deletions controllers/quickstarts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func TestEnsureQuickStarts(t *testing.T) {
}

fakeReconciler := GetFakeStorageSystemReconciler(t)
err := fakeReconciler.ensureQuickStarts(fakeReconciler.Log)
err := fakeReconciler.ensureQuickStarts(fakeLogger)
assert.NoError(t, err)
for _, c := range cases {
qs := consolev1.ConsoleQuickStart{}
Expand Down Expand Up @@ -143,7 +143,7 @@ func TestDeleteQuickStarts(t *testing.T) {

fakeReconciler := GetFakeStorageSystemReconciler(t)

err := fakeReconciler.ensureQuickStarts(fakeReconciler.Log)
err := fakeReconciler.ensureQuickStarts(fakeLogger)
assert.NoError(t, err)

var quickstarts []consolev1.ConsoleQuickStart = getActualQuickStarts(t, cases, fakeReconciler)
Expand All @@ -156,7 +156,7 @@ func TestDeleteQuickStarts(t *testing.T) {
for i := range tc.deleteStorageSystems {
err := fakeReconciler.Client.Delete(context.TODO(), &tc.deleteStorageSystems[i])
assert.NoError(t, err)
err = fakeReconciler.deleteResources(&tc.deleteStorageSystems[i], fakeReconciler.Log)
err = fakeReconciler.deleteResources(&tc.deleteStorageSystems[i], fakeLogger)
assert.NoError(t, err)
}
quickstarts = getActualQuickStarts(t, cases, fakeReconciler)
Expand Down
17 changes: 12 additions & 5 deletions controllers/storagesystem_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import (
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/predicate"
"sigs.k8s.io/controller-runtime/pkg/reconcile"

Expand All @@ -46,10 +47,11 @@ const (

// StorageSystemReconciler reconciles a StorageSystem object
type StorageSystemReconciler struct {
client.Client
Log logr.Logger
Scheme *runtime.Scheme
Recorder *EventReporter
ctx context.Context
Client client.Client
Scheme *runtime.Scheme
Recorder *EventReporter
OperatorNamespace string
}

//+kubebuilder:rbac:groups=odf.openshift.io,resources=storagesystems,verbs=get;list;watch;create;update;patch;delete
Expand All @@ -68,7 +70,7 @@ type StorageSystemReconciler struct {
// For more details, check Reconcile and its Result here:
// - https://pkg.go.dev/sigs.k8s.io/[email protected]/pkg/reconcile
func (r *StorageSystemReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
logger := r.Log.WithValues("instance", req.NamespacedName)
logger := log.FromContext(ctx)

instance := &odfv1alpha1.StorageSystem{}
err := r.Client.Get(context.TODO(), req.NamespacedName, instance)
Expand Down Expand Up @@ -156,6 +158,11 @@ func (r *StorageSystemReconciler) reconcile(instance *odfv1alpha1.StorageSystem,
return ctrl.Result{}, err
}

err = ensureWebhook(r.ctx, r.Client, logger, r.OperatorNamespace)
if err != nil {
return ctrl.Result{}, err
}

err = r.ensureSubscriptions(instance, logger)
if err != nil {
return ctrl.Result{}, err
Expand Down
5 changes: 4 additions & 1 deletion controllers/storagesystem_controller_fake.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ import (
odfv1alpha1 "github.com/red-hat-storage/odf-operator/api/v1alpha1"
)

var (
fakeLogger = ctrl.Log.WithName("test-controllers").WithName("StorageSystem")
)

func GetFakeStorageSystem(kind odfv1alpha1.StorageKind) *odfv1alpha1.StorageSystem {
return &odfv1alpha1.StorageSystem{
ObjectMeta: metav1.ObjectMeta{
Expand All @@ -53,7 +57,6 @@ func GetFakeStorageSystemReconciler(t *testing.T, objs ...runtime.Object) *Stora
scheme := createFakeScheme(t)
fakeStorageSystemReconciler := &StorageSystemReconciler{
Client: fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(objs...).Build(),
Log: ctrl.Log.WithName("controllers").WithName("StorageSystem"),
Scheme: scheme,
Recorder: NewEventReporter(record.NewFakeRecorder(1024)),
}
Expand Down
Loading
Loading