Skip to content

Commit

Permalink
add server implementation
Browse files Browse the repository at this point in the history
Signed-off-by: Rewant Soni <resoni@redhat.com>
  • Loading branch information
rewantsoni committed Sep 4, 2024
1 parent 96050c1 commit bd6a164
Show file tree
Hide file tree
Showing 5 changed files with 329 additions and 19 deletions.
3 changes: 3 additions & 0 deletions controllers/util/k8sutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ const (
OwnerUIDIndexName = "ownerUID"

OdfInfoNamespacedNameClaimName = "odfinfo.odf.openshift.io"

// CephBlockPoolForbidMirroringLabel is used to blacklist cephBlockPool for mirroring
CephBlockPoolForbidMirroringLabel = "ocs.openshift.io/forbid-mirroring"
)

// GetWatchNamespace returns the namespace the operator should be watching for changes
Expand Down
18 changes: 17 additions & 1 deletion deploy/ocs-operator/manifests/provider-role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,26 @@ rules:
- apiGroups:
- ""
resources:
- configmaps
- secrets
- services
verbs:
- get
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- list
- create
- update
- delete
- apiGroups:
- ceph.rook.io
resources:
- cephfilesystemsubvolumegroups
- cephblockpoolradosnamespaces
- cephblockpools
verbs:
- get
- list
Expand Down Expand Up @@ -54,6 +64,12 @@ rules:
- list
- create
- delete
- apiGroups:
- ocs.openshift.io
resources:
- storageclusters
verbs:
- get
- apiGroups:
- operators.coreos.com
resources:
Expand Down
18 changes: 17 additions & 1 deletion rbac/provider-role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,26 @@ rules:
- apiGroups:
- ""
resources:
- configmaps
- secrets
- services
verbs:
- get
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- list
- create
- update
- delete
- apiGroups:
- ceph.rook.io
resources:
- cephfilesystemsubvolumegroups
- cephblockpoolradosnamespaces
- cephblockpools
verbs:
- get
- list
Expand Down Expand Up @@ -54,6 +64,12 @@ rules:
- list
- create
- delete
- apiGroups:
- ocs.openshift.io
resources:
- storageclusters
verbs:
- get
- apiGroups:
- operators.coreos.com
resources:
Expand Down
150 changes: 150 additions & 0 deletions services/provider/server/configmap.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package server

import (
"context"
"errors"
"fmt"
"sync"

corev1 "k8s.io/api/core/v1"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
)

var (
errTicketAlreadyExistsStorageClusterPeer = errors.New("onboarding ticket already used by another storageClusterPeer representation")
)

type ocsConfigMapManager struct {
client client.Client
namespace string
nameByTicket map[string]string
mutex sync.RWMutex
}

func newConfigMapManager(ctx context.Context, cl client.Client, namespace string) (*ocsConfigMapManager, error) {
configMaps := &corev1.ConfigMapList{}

//TODO: figure out a way to list only the configMaps for storageClusterPeer Representation
// we can use cached client to set up a indexer based on ticket annotation or prefix or use a label?
err := cl.List(ctx, configMaps, client.InNamespace(namespace))
if err != nil {
return nil, fmt.Errorf("failed to list storage consumers. %v", err)
}

nameByTicket := map[string]string{}

for _, configMap := range configMaps.Items {
if ticket, ok := configMap.GetAnnotations()[TicketAnnotation]; ok {
nameByTicket[ticket] = configMap.Name
}
}

return &ocsConfigMapManager{
client: cl,
namespace: namespace,
nameByTicket: nameByTicket,
}, nil
}

// Create creates a new storageClusterPeer representation resource, updates the cache and returns the representation UID
func (c *ocsConfigMapManager) Create(ctx context.Context, ticket, name, namespace string) error {

c.mutex.RLock()
if _, ok := c.nameByTicket[ticket]; ok {
c.mutex.RUnlock()
klog.Warning("onboarding ticket already in use")
return errTicketAlreadyExistsStorageClusterPeer
}
c.mutex.RUnlock()

configMapObj := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
Annotations: map[string]string{
TicketAnnotation: ticket,
},
},
}

err := c.client.Create(ctx, configMapObj)
if err != nil {
if kerrors.IsAlreadyExists(err) {
klog.Warningf("storageClusterPeer representation %q already exists", name)
return err
}
return fmt.Errorf("failed to create storageClusterPeer representation %q. %v", configMapObj.Name, err)
}

c.mutex.Lock()
c.nameByTicket[ticket] = configMapObj.Name
c.mutex.Unlock()

klog.Infof("successfully created storageClusterPeer representation %q", name)

return nil
}

// Delete deletes the storageClusterPeer representation resource using UID and updates the cache
func (c *ocsConfigMapManager) Delete(ctx context.Context, name, namespace string) error {

configMapObj := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
}

if err := c.client.Delete(ctx, configMapObj); err != nil {
if kerrors.IsNotFound(err) {
klog.Warningf("storageClusterPeer representation %q not found.", configMapObj.Name)
return nil
}
return fmt.Errorf("failed to delete storageClusterPeer representation %q. %v", configMapObj.Name, err)
}

klog.Infof("successfully deleted storageClusterPeer representation %q", configMapObj.Name)

return nil
}

func (c *ocsConfigMapManager) Enable(ctx context.Context, name, namespace string) error {
// Get storage cluster peer representation resource using name
configMapObj, err := c.GetByName(ctx, name, namespace)
if err != nil {
return err
}

if configMapObj.Data == nil {
configMapObj.Data = map[string]string{}
}
configMapObj.Data["enable"] = "true"
err = c.client.Update(ctx, configMapObj)
if err != nil {
klog.Errorf("failed to enable storageClusterPeer representation %v", err)
return fmt.Errorf("failed to update storageClusterPeer representation %q. %v", configMapObj.Name, err)
}

klog.Infof("successfully Enabled the storageClusterPeer representation %q", configMapObj.Name)
return nil
}

// GetByName returns a storageClusterPeer representation resource using the Name
func (c *ocsConfigMapManager) GetByName(ctx context.Context, representationName, namespace string) (*corev1.ConfigMap, error) {

configMapObj := &corev1.ConfigMap{}
if err := c.client.Get(ctx, types.NamespacedName{Name: representationName, Namespace: namespace}, configMapObj); err != nil {
klog.Errorf("Failed to get the storageClusterPeer representation configMap %s: %v", representationName, err)
return nil, err
}

return configMapObj, nil
}

func (c *ocsConfigMapManager) IsEnabled(configMap *corev1.ConfigMap) bool {
return configMap.Data["enable"] == "true"
}
Loading

0 comments on commit bd6a164

Please sign in to comment.