Skip to content

Commit

Permalink
Merge branch 'main' into update-ubi-dependencies
Browse files Browse the repository at this point in the history
Signed-off-by: Rodrigo Bassil <rodrigo.bassil@dell.com>
  • Loading branch information
rodrigobassil committed Jun 11, 2024
2 parents a8dafa5 + 35b9b82 commit 8ca068c
Show file tree
Hide file tree
Showing 4 changed files with 171 additions and 1 deletion.
9 changes: 9 additions & 0 deletions controllers/acc_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@ const (

// AccInitContainerImage - tag for init container image
AccInitContainerImage string = "<ACC_INIT_CONTAINER_IMAGE>"

// BrownfieldManifest - manifest for brownfield role/rolebinding creation
BrownfieldManifest string = "brownfield-onboard.yaml"
)

// ApexConnectivityClientReconciler reconciles a ApexConnectivityClient object
Expand Down Expand Up @@ -438,6 +441,8 @@ func applyAccConfigVersionAnnotations(ctx context.Context, instance *csmv1.ApexC

// DeployApexConnectivityClient - perform deployment
func DeployApexConnectivityClient(ctx context.Context, isDeleting bool, operatorConfig utils.OperatorConfig, cr csmv1.ApexConnectivityClient, ctrlClient crclient.Client) error {
log := logger.GetLogger(ctx)

YamlString := ""
ModifiedYamlString := ""
deploymentPath := fmt.Sprintf("%s/clientconfig/%s/%s/%s", operatorConfig.ConfigDirectory, csmv1.DreadnoughtClient, cr.Spec.Client.ConfigVersion, AccManifest)
Expand Down Expand Up @@ -465,6 +470,10 @@ func DeployApexConnectivityClient(ctx context.Context, isDeleting bool, operator
}
}

if err = utils.CreateBrownfieldRbac(ctx, operatorConfig, cr, ctrlClient); err != nil {
log.Error(err, "error creating role/rolebindings")
}

return nil
}

Expand Down
48 changes: 48 additions & 0 deletions controllers/acc_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ import (
"testing"
"time"

clienttesting "k8s.io/client-go/testing"
"k8s.io/client-go/util/workqueue"

csmv1 "github.com/dell/csm-operator/api/v1"
"github.com/dell/csm-operator/pkg/logger"
deploymentpkg "github.com/dell/csm-operator/pkg/resources/deployment"
"github.com/dell/csm-operator/pkg/utils"
"github.com/dell/csm-operator/tests/shared"
"github.com/dell/csm-operator/tests/shared/clientgoclient"
Expand All @@ -37,6 +39,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/tools/record"

Expand All @@ -45,6 +48,11 @@ import (
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
"sigs.k8s.io/controller-runtime/pkg/reconcile"

apiv1 "k8s.io/apimachinery/pkg/apis/meta/v1"
configv1 "k8s.io/client-go/applyconfigurations/apps/v1"
corev12 "k8s.io/client-go/applyconfigurations/core/v1"
v1 "k8s.io/client-go/applyconfigurations/meta/v1"
)

var (
Expand Down Expand Up @@ -163,6 +171,12 @@ func (suite *AccControllerTestSuite) TestReconcileAcc() {
suite.runFakeAccManager("", true)
}

func (suite *AccControllerTestSuite) TestAccConnectivityClient() {
csm := shared.MakeAcc(accName, suite.namespace, accConfigVersion)
csm.Spec.Client.CSMClientType = csmv1.DreadnoughtClient
csm.Spec.Client.Common.Image = "image"
}

func (suite *AccControllerTestSuite) TestAccConnectivityClientConnectionTarget() {
csm := shared.MakeAcc(accName, suite.namespace, accConfigVersion)
csm.Spec.Client.CSMClientType = csmv1.DreadnoughtClient
Expand Down Expand Up @@ -713,3 +727,37 @@ func (suite *AccControllerTestSuite) debugAccFakeObjects() {
accUnittestLogger.Info("found fake object ", "object", fmt.Sprintf("%#v", o))
}
}

func TestSyncDeployment(t *testing.T) {
labels := make(map[string]string, 1)
labels["*-8-csm"] = "/*-csm"
deployment := configv1.DeploymentApplyConfiguration{
ObjectMetaApplyConfiguration: &v1.ObjectMetaApplyConfiguration{Name: &[]string{"csm"}[0], Namespace: &[]string{"default"}[0]},
Spec: &configv1.DeploymentSpecApplyConfiguration{Template: &corev12.PodTemplateSpecApplyConfiguration{
ObjectMetaApplyConfiguration: &v1.ObjectMetaApplyConfiguration{Labels: labels},
}},
}
k8sClient := fake.NewSimpleClientset()
csmName = "csm"
containers := make([]corev1.Container, 0)
containers = append(containers, corev1.Container{Name: "fake-container", Image: "fake-image"})
create, err := k8sClient.AppsV1().Deployments("default").Create(context.Background(), &appsv1.Deployment{
ObjectMeta: apiv1.ObjectMeta{
Name: csmName,
Namespace: "default",
},
Spec: appsv1.DeploymentSpec{
Template: corev1.PodTemplateSpec{
ObjectMeta: apiv1.ObjectMeta{},
Spec: corev1.PodSpec{Containers: containers},
},
},
}, apiv1.CreateOptions{})
assert.NoError(t, err)
assert.NotNil(t, create)
k8sClient.PrependReactor("patch", "deployments", func(_ clienttesting.Action) (bool, runtime.Object, error) {
return true, nil, fmt.Errorf("fake error")
})
err = deploymentpkg.SyncDeployment(context.Background(), deployment, k8sClient, csmName)
assert.Error(t, err)
}
5 changes: 5 additions & 0 deletions controllers/csm_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -879,6 +879,11 @@ func (r *ContainerStorageModuleReconciler) SyncCSM(ctx context.Context, cr csmv1
}

}
// If dell connectivity client is deployed, create role/rolebindings in the csm namespaces
if err = utils.CheckAccAndCreateRbac(ctx, operatorConfig, ctrlClient); err != nil {
return err
}

return nil
}

Expand Down
110 changes: 109 additions & 1 deletion pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import (
t1 "k8s.io/apimachinery/pkg/types"
confv1 "k8s.io/client-go/applyconfigurations/apps/v1"
acorev1 "k8s.io/client-go/applyconfigurations/core/v1"
"sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/yaml"

Expand Down Expand Up @@ -139,6 +140,12 @@ const (
PodmonNodeComponent = "podmon-node"
// ApplicationMobilityNamespace - application-mobility
ApplicationMobilityNamespace = "application-mobility"
// ExistingNamespace - existing namespace
ExistingNamespace = "<ExistingNameSpace>"
// ClientNamespace - client namespace
ClientNamespace = "<ClientNameSpace>"
// BrownfieldManifest - brownfield-onboard.yaml
BrownfieldManifest = "brownfield-onboard.yaml"
)

// SplitYaml divides a big bytes of yaml files in individual yaml files.
Expand Down Expand Up @@ -1202,7 +1209,39 @@ func getUpgradeInfo[T csmv1.CSMComponentType](ctx context.Context, operatorConfi
return upgradePath.MinUpgradePath, nil
}

func getNamespaces(ctx context.Context, ctrlClient crclient.Client) ([]string, error) {
// BrownfieldOnboard will onboard the brownfield cluster
func BrownfieldOnboard(ctx context.Context, path string, cr csmv1.ApexConnectivityClient, ctrlClient crclient.Client) error {
logInstance := logger.GetLogger(ctx)

namespaces, err := GetNamespaces(ctx, ctrlClient)
if err != nil {
logInstance.Error(err, "Failed to get namespaces")
return err
}

manifestFile, err := os.ReadFile(filepath.Clean(path))
if err != nil {
logInstance.Error(err, "Failed to read manifest file")
return err
}

yamlFile := string(manifestFile)

for _, ns := range namespaces {

yamlFile := strings.ReplaceAll(yamlFile, ExistingNamespace, ns)
yamlFile = strings.ReplaceAll(yamlFile, ClientNamespace, cr.Namespace)

err := CreateObjects(ctx, yamlFile, ctrlClient)
if err != nil {
return err
}
}
return nil
}

// GetNamespaces returns the list of namespaces in the cluster
func GetNamespaces(ctx context.Context, ctrlClient crclient.Client) ([]string, error) {
// Set to store unique namespaces
namespaceMap := make(map[string]struct{})

Expand All @@ -1223,3 +1262,72 @@ func getNamespaces(ctx context.Context, ctrlClient crclient.Client) ([]string, e

return namespaces, nil
}

// CreateObjects creates the objects in the cluster
func CreateObjects(ctx context.Context, yamlFile string, ctrlClient crclient.Client) error {
deployObjects, err := GetModuleComponentObj([]byte(yamlFile))
if err != nil {
return err
}
for _, obj := range deployObjects {
log.FromContext(ctx).Info("namespace of parsed object is", "object", obj.GetNamespace())

found := obj.DeepCopyObject().(crclient.Object)
err := ctrlClient.Get(ctx, crclient.ObjectKey{Namespace: obj.GetNamespace(), Name: obj.GetName()}, found)
if err != nil && k8serror.IsNotFound(err) {
log.FromContext(ctx).Info("Creating a new object", "object", obj.GetObjectKind().GroupVersionKind().String())
err := ctrlClient.Create(ctx, obj)
if err != nil {
return err
}
} else if err != nil {
log.FromContext(ctx).Info("Unknown error trying to retrieve the object.", "Error", err.Error())
return err
} else {
log.FromContext(ctx).Info("Updating Object", "object", obj.GetObjectKind().GroupVersionKind().String())
err = ctrlClient.Update(ctx, obj)
if err != nil {
return err
}
}
}
return nil
}

// CheckAccAndCreateRbac checks if the dell connectivity client exists and creates the role and rolebindings
func CheckAccAndCreateRbac(ctx context.Context, operatorConfig OperatorConfig, ctrlClient crclient.Client) error {
logInstance := logger.GetLogger(ctx)
accList := &csmv1.ApexConnectivityClientList{}
if err := ctrlClient.List(ctx, accList); err != nil {
logInstance.Info("dell connectivity client not found")
} else if len(accList.Items) <= 0 {
logInstance.Info("dell connectivity client not found")
} else {
logInstance.Info("dell connectivity client found")
cr := new(csmv1.ApexConnectivityClient)
accConfigVersion := accList.Items[0].Spec.Client.ConfigVersion
brownfieldManifestFilePath := fmt.Sprintf("%s/clientconfig/%s/%s/%s", operatorConfig.ConfigDirectory,
csmv1.DreadnoughtClient, accConfigVersion, BrownfieldManifest)
if err = BrownfieldOnboard(ctx, brownfieldManifestFilePath, *cr, ctrlClient); err != nil {
logInstance.Error(err, "error creating role/rolebindings")
return err
}
}
return nil
}

// CreateBrownfieldRbac creates the role and rolebindings
func CreateBrownfieldRbac(ctx context.Context, operatorConfig OperatorConfig, cr csmv1.ApexConnectivityClient, ctrlClient crclient.Client) error {
logInstance := logger.GetLogger(ctx)
csmList := &csmv1.ContainerStorageModuleList{}
err := ctrlClient.List(ctx, csmList)
if err == nil && len(csmList.Items) > 0 {
logInstance.Info("Found existing csm installations. Proceeding to create role/rolebindings")
brownfieldManifestFilePath := fmt.Sprintf("%s/clientconfig/%s/%s/%s", operatorConfig.ConfigDirectory, csmv1.DreadnoughtClient, cr.Spec.Client.ConfigVersion, BrownfieldManifest)
if err = BrownfieldOnboard(ctx, brownfieldManifestFilePath, cr, ctrlClient); err != nil {
logInstance.Error(err, "error creating role/rolebindings")
return err
}
}
return nil
}

0 comments on commit 8ca068c

Please sign in to comment.