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

KRV-21705: Support on-boarding of brownfield clusters #565

Closed
wants to merge 9 commits into from
Closed
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
9 changes: 9 additions & 0 deletions controllers/acc_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,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 +467,13 @@ func DeployApexConnectivityClient(ctx context.Context, isDeleting bool, operator
}
}

// brownfield scenario
log.Info("Starting the brownfield cluster onboarding")
BrownfieldCR := "brownfield-deployment.yaml"
brownfieldManifestFilePath := fmt.Sprintf("%s/clientconfig/%s/%s/%s", operatorConfig.ConfigDirectory, csmv1.DreadnoughtClient, cr.Spec.Client.ConfigVersion, BrownfieldCR)
if err = utils.BrownfieldOnboard(ctx, brownfieldManifestFilePath, cr, ctrlClient); err != nil {
log.Error(err, "brownfield cluster onboarding failed")
}
return nil
}

Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ require (
github.com/prometheus/common v0.42.0 // indirect
github.com/prometheus/procfs v0.9.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/objx v0.5.2 // indirect
go.uber.org/multierr v1.11.0 // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/oauth2 v0.7.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: connectivity-client-docker-k8s
namespace: <ExistingNameSpace>
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["list","get", "create", "update", "delete","watch"]
- apiGroups: ["storage.dell.com"]
resources: ["containerstoragemodules"]
verbs: ["create", "delete"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "create", "delete", "update"]
- apiGroups: ["mobility.storage.dell.com"]
resources: ["backups"]
verbs: ["create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: connectivity-client-docker-k8s
namespace: <ExistingNameSpace>
subjects:
- kind: ServiceAccount
name: connectivity-client-docker-k8s
namespace: <ClientNameSpace>
roleRef:
kind: Role
name: connectivity-client-docker-k8s
apiGroup: rbac.authorization.k8s.io
91 changes: 90 additions & 1 deletion pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (
"strconv"
"strings"

"sigs.k8s.io/controller-runtime/pkg/log"

csmv1 "github.com/dell/csm-operator/api/v1"
"github.com/dell/csm-operator/pkg/logger"
goYAML "gopkg.in/yaml.v3"
Expand Down Expand Up @@ -139,6 +141,9 @@ const (
PodmonNodeComponent = "podmon-node"
// ApplicationMobilityNamespace - application-mobility
ApplicationMobilityNamespace = "application-mobility"
// BrownfieldNamespace
ExistingNamespace = "<ExistingNameSpace>"
ClientNamespace = "<ClientNameSpace>"
)

// SplitYaml divides a big bytes of yaml files in individual yaml files.
Expand Down Expand Up @@ -1116,6 +1121,91 @@ func DetermineUnitTestRun(ctx context.Context) bool {
return unitTestRun
}

func BrownfieldOnboard(ctx context.Context, path string, cr csmv1.ApexConnectivityClient, ctrlClient crclient.Client) error {
log := logger.GetLogger(ctx)

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

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

yamlFile := string(buf)

for _, ns := range namespace {

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
}

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

list := &csmv1.ContainerStorageModuleList{}

if err := ctrlClient.List(ctx, list); err != nil {
return nil, fmt.Errorf("list csm resources: %w", err)
}
for _, csmResource := range list.Items {
namespaceMap[csmResource.Namespace] = struct{}{}
fmt.Printf("namespace is %s\n", csmResource.Namespace)
}

// Convert set to slice
var namespaces []string
for namespace := range namespaceMap {
namespaces = append(namespaces, namespace)
}

return namespaces, nil
}

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.", "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
}

// IsValidUpgrade will check if upgrade of module/driver is allowed
func IsValidUpgrade[T csmv1.CSMComponentType](ctx context.Context, oldVersion, newVersion string, csmComponentType T, operatorConfig OperatorConfig) (bool, error) {
log := logger.GetLogger(ctx)
Expand Down Expand Up @@ -1171,7 +1261,6 @@ func getUpgradeInfo[T csmv1.CSMComponentType](ctx context.Context, operatorConfi
log.Errorw("getUpgradeInfo yaml marshall failed", "Error", err.Error())
return "", err
}

// Example return value: "v2.2.0"
return upgradePath.MinUpgradePath, nil
}
Loading