Skip to content
This repository was archived by the owner on Mar 4, 2024. It is now read-only.

Commit 48d6ea3

Browse files
committed
EVEREST-633 Update subscription on install calls
1 parent 5850a60 commit 48d6ea3

File tree

3 files changed

+123
-46
lines changed

3 files changed

+123
-46
lines changed

pkg/install/install.go

+25-11
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"errors"
2323
"fmt"
2424
"net/url"
25+
"os"
2526
"strings"
2627

2728
"github.com/AlecAivazis/survey/v2"
@@ -82,6 +83,8 @@ const (
8283
monitoringNamespace = "everest-monitoring"
8384
// EverestMonitoringNamespaceEnvVar is the name of the environment variable that holds the monitoring namespace.
8485
EverestMonitoringNamespaceEnvVar = "MONITORING_NAMESPACE"
86+
// disableTelemetryEnvVar is the name of the environment variable that disables telemetry.
87+
disableTelemetryEnvVar = "DISABLE_TELEMETRY"
8588
)
8689

8790
type (
@@ -471,6 +474,11 @@ func (o *Install) installOperator(ctx context.Context, channel, operatorName, na
471474

472475
o.l.Infof("Installing %s operator", operatorName)
473476

477+
disableTelemetry, ok := os.LookupEnv(disableTelemetryEnvVar)
478+
if !ok || disableTelemetry != "true" {
479+
disableTelemetry = "false"
480+
}
481+
474482
params := kubernetes.InstallOperatorRequest{
475483
Namespace: namespace,
476484
Name: operatorName,
@@ -479,21 +487,27 @@ func (o *Install) installOperator(ctx context.Context, channel, operatorName, na
479487
CatalogSourceNamespace: catalogSourceNamespace,
480488
Channel: channel,
481489
InstallPlanApproval: v1alpha1.ApprovalManual,
482-
}
483-
if len(o.config.Namespaces) != 0 && operatorName == everestOperatorName {
484-
params.TargetNamespaces = o.config.Namespaces
485-
params.SubscriptionConfig = &v1alpha1.SubscriptionConfig{
490+
SubscriptionConfig: &v1alpha1.SubscriptionConfig{
486491
Env: []corev1.EnvVar{
487492
{
488-
Name: kubernetes.EverestDBNamespacesEnvVar,
489-
Value: strings.Join(o.config.Namespaces, ","),
490-
},
491-
{
492-
Name: EverestMonitoringNamespaceEnvVar,
493-
Value: monitoringNamespace,
493+
Name: disableTelemetryEnvVar,
494+
Value: disableTelemetry,
494495
},
495496
},
496-
}
497+
},
498+
}
499+
if operatorName == everestOperatorName {
500+
params.TargetNamespaces = o.config.Namespaces
501+
params.SubscriptionConfig.Env = append(params.SubscriptionConfig.Env, []corev1.EnvVar{
502+
{
503+
Name: EverestMonitoringNamespaceEnvVar,
504+
Value: monitoringNamespace,
505+
},
506+
{
507+
Name: kubernetes.EverestDBNamespacesEnvVar,
508+
Value: strings.Join(o.config.Namespaces, ","),
509+
},
510+
}...)
497511
}
498512

499513
if err := o.kubeClient.InstallOperator(ctx, params); err != nil {

pkg/kubernetes/client/client.go

+16
Original file line numberDiff line numberDiff line change
@@ -1192,6 +1192,22 @@ func (c *Client) CreateSubscription(ctx context.Context, namespace string, subsc
11921192
return sub, nil
11931193
}
11941194

1195+
// UpdateSubscription updates an OLM subscription.
1196+
func (c *Client) UpdateSubscription(ctx context.Context, namespace string, subscription *v1alpha1.Subscription) (*v1alpha1.Subscription, error) {
1197+
operatorClient, err := versioned.NewForConfig(c.restConfig)
1198+
if err != nil {
1199+
return nil, errors.Join(err, errors.New("cannot create an operator client instance"))
1200+
}
1201+
sub, err := operatorClient.
1202+
OperatorsV1alpha1().
1203+
Subscriptions(namespace).
1204+
Update(ctx, subscription, metav1.UpdateOptions{})
1205+
if err != nil {
1206+
return sub, err
1207+
}
1208+
return sub, nil
1209+
}
1210+
11951211
// CreateSubscriptionForCatalog creates an OLM subscription.
11961212
func (c *Client) CreateSubscriptionForCatalog(ctx context.Context, namespace, name, catalogNamespace, catalog,
11971213
packageName, channel, startingCSV string, approval v1alpha1.Approval,

pkg/kubernetes/kubernetes.go

+82-35
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import (
2626
"io/fs"
2727
"log"
2828
"net/http"
29-
"os"
3029
"strings"
3130
"time"
3231

@@ -87,7 +86,6 @@ const (
8786
databaseClusterAPIVersion = "everest.percona.com/v1alpha1"
8887
restartAnnotationKey = "everest.percona.com/restart"
8988
managedByKey = "everest.percona.com/managed-by"
90-
disableTelemetryEnvVar = "DISABLE_TELEMETRY"
9189
// ContainerStateWaiting represents a state when container requires some
9290
// operations being done in order to complete start up.
9391
ContainerStateWaiting ContainerState = "waiting"
@@ -629,47 +627,96 @@ type InstallOperatorRequest struct {
629627
SubscriptionConfig *olmv1alpha1.SubscriptionConfig
630628
}
631629

630+
func mergeSubscriptionConfig(sub *olmv1alpha1.SubscriptionConfig, cfg *olmv1alpha1.SubscriptionConfig) *olmv1alpha1.SubscriptionConfig {
631+
if sub == nil {
632+
sub = &olmv1alpha1.SubscriptionConfig{Env: []corev1.EnvVar{}}
633+
}
634+
635+
if cfg == nil {
636+
return sub
637+
}
638+
639+
for _, e := range cfg.Env {
640+
found := false
641+
for i, se := range sub.Env {
642+
if e.Name == se.Name {
643+
found = true
644+
// If the environment variable is not the namespaces, just override it
645+
if e.Name != EverestDBNamespacesEnvVar {
646+
sub.Env[i].Value = e.Value
647+
break
648+
}
649+
650+
// Merge the namespaces
651+
subNamespaces := strings.Split(se.Value, ",")
652+
cfgNamespaces := strings.Split(e.Value, ",")
653+
namespacesMap := map[string]struct{}{}
654+
for _, ns := range subNamespaces {
655+
namespacesMap[ns] = struct{}{}
656+
}
657+
for _, ns := range cfgNamespaces {
658+
namespacesMap[ns] = struct{}{}
659+
}
660+
namespaces := []string{}
661+
for ns := range namespacesMap {
662+
namespaces = append(namespaces, ns)
663+
}
664+
sub.Env[i].Value = strings.Join(namespaces, ",")
665+
666+
break
667+
}
668+
}
669+
if !found {
670+
sub.Env = append(sub.Env, e)
671+
}
672+
}
673+
674+
return sub
675+
}
676+
632677
// InstallOperator installs an operator via OLM.
633678
func (k *Kubernetes) InstallOperator(ctx context.Context, req InstallOperatorRequest) error { //nolint:funlen
634-
disableTelemetry, ok := os.LookupEnv(disableTelemetryEnvVar)
635-
if !ok || disableTelemetry != "true" {
636-
disableTelemetry = "false"
637-
}
638-
config := &olmv1alpha1.SubscriptionConfig{Env: []corev1.EnvVar{}}
639-
if req.SubscriptionConfig != nil {
640-
config = req.SubscriptionConfig
679+
subscription, err := k.client.GetSubscription(ctx, req.Namespace, req.Name)
680+
if err != nil && !apierrors.IsNotFound(err) {
681+
return errors.Join(err, errors.New("cannot get subscription"))
641682
}
642-
config.Env = append(config.Env, corev1.EnvVar{
643-
Name: disableTelemetryEnvVar,
644-
Value: disableTelemetry,
645-
})
646-
subscription := &olmv1alpha1.Subscription{
647-
TypeMeta: metav1.TypeMeta{
648-
Kind: olmv1alpha1.SubscriptionKind,
649-
APIVersion: olmv1alpha1.SubscriptionCRDAPIVersion,
650-
},
651-
ObjectMeta: metav1.ObjectMeta{
652-
Namespace: req.Namespace,
653-
Name: req.Name,
654-
},
655-
Spec: &olmv1alpha1.SubscriptionSpec{
656-
CatalogSource: req.CatalogSource,
657-
CatalogSourceNamespace: req.CatalogSourceNamespace,
658-
Package: req.Name,
659-
Channel: req.Channel,
660-
StartingCSV: req.StartingCSV,
661-
InstallPlanApproval: req.InstallPlanApproval,
662-
Config: config,
663-
},
683+
if apierrors.IsNotFound(err) {
684+
subscription = &olmv1alpha1.Subscription{
685+
TypeMeta: metav1.TypeMeta{
686+
Kind: olmv1alpha1.SubscriptionKind,
687+
APIVersion: olmv1alpha1.SubscriptionCRDAPIVersion,
688+
},
689+
ObjectMeta: metav1.ObjectMeta{
690+
Namespace: req.Namespace,
691+
Name: req.Name,
692+
},
693+
Spec: &olmv1alpha1.SubscriptionSpec{
694+
CatalogSource: req.CatalogSource,
695+
CatalogSourceNamespace: req.CatalogSourceNamespace,
696+
Package: req.Name,
697+
Channel: req.Channel,
698+
StartingCSV: req.StartingCSV,
699+
InstallPlanApproval: req.InstallPlanApproval,
700+
},
701+
}
664702
}
665-
subs, err := k.client.CreateSubscription(ctx, req.Namespace, subscription)
666-
if err != nil {
667-
return errors.Join(err, errors.New("cannot create a subscription to install the operator"))
703+
704+
subscription.Spec.Config = mergeSubscriptionConfig(subscription.Spec.Config, req.SubscriptionConfig)
705+
if apierrors.IsNotFound(err) {
706+
_, err := k.client.CreateSubscription(ctx, req.Namespace, subscription)
707+
if err != nil {
708+
return errors.Join(err, errors.New("cannot create a subscription to install the operator"))
709+
}
710+
} else {
711+
_, err := k.client.UpdateSubscription(ctx, req.Namespace, subscription)
712+
if err != nil {
713+
return errors.Join(err, errors.New("cannot update a subscription to install the operator"))
714+
}
668715
}
669716

670717
err = wait.PollUntilContextTimeout(ctx, pollInterval, pollDuration, false, func(ctx context.Context) (bool, error) {
671718
k.l.Debugf("Polling subscription %s/%s", req.Namespace, req.Name)
672-
subs, err = k.client.GetSubscription(ctx, req.Namespace, req.Name)
719+
subs, err := k.client.GetSubscription(ctx, req.Namespace, req.Name)
673720
if err != nil {
674721
return false, errors.Join(err, fmt.Errorf("cannot get an install plan for the operator subscription: %q", req.Name))
675722
}

0 commit comments

Comments
 (0)