Skip to content

Commit 78a983e

Browse files
committed
fix(ENTESB-18466): Flag operator as non-upgradeable
* When operator is installed via OLM, a separate OperatorCondition CR is created which can be updated with an "upgradeable" condition flagging whether the OLM can upgrade the operator * Turn off upgradeable state when * operator is initializing * operator is upgrading * Turn on upgradeable state when * operator has started * operator has completed an upgrade * Finds the OperatorCondition using the deployment name, deployment owner (CSV) and the CSV name (OperatorCondition has same name as the CSV). * Adds conditions tests but cannot completely implement due to operator-framework/operator-lib#103
1 parent 53d5231 commit 78a983e

File tree

14 files changed

+460
-16
lines changed

14 files changed

+460
-16
lines changed

install/operator/config/dev/operator/kustomization.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ patchesStrategicMerge:
44
- ./env-var-patch.yaml
55
- ./annotation-patch.gen.yaml
66
- ./image-stream-patch.gen.yaml
7+
- ./patch-image-pull-policy-always.yaml
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# ---------------------------------------------------------------------------
2+
# Licensed to the Apache Software Foundation (ASF) under one or more
3+
# contributor license agreements. See the NOTICE file distributed with
4+
# this work for additional information regarding copyright ownership.
5+
# The ASF licenses this file to You under the Apache License, Version 2.0
6+
# (the "License"); you may not use this file except in compliance with
7+
# the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
# ---------------------------------------------------------------------------
17+
18+
apiVersion: apps/v1
19+
kind: Deployment
20+
metadata:
21+
name: syndesis-operator
22+
spec:
23+
template:
24+
spec:
25+
containers:
26+
- name: syndesis-operator
27+
imagePullPolicy: Always

install/operator/pkg/generator/assets/install/cluster_role_olm.yml.tmpl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
- operatorgroups
6363
- subscriptions
6464
- installplans
65+
- operatorconditions
6566
verbs: [ create, delete, update, get, list, watch ]
6667
- apiGroups:
6768
- operators.coreos.com

install/operator/pkg/syndesis/action/checkupdates.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import (
88

99
synapi "github.com/syndesisio/syndesis/install/operator/pkg/apis/syndesis/v1beta3"
1010
"github.com/syndesisio/syndesis/install/operator/pkg/syndesis/clienttools"
11+
"github.com/syndesisio/syndesis/install/operator/pkg/syndesis/olm"
12+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1113
"sigs.k8s.io/controller-runtime/pkg/manager"
1214
)
1315

@@ -39,7 +41,7 @@ func (a checkUpdatesAction) Execute(ctx context.Context, syndesis *synapi.Syndes
3941
// Everything fine
4042
return nil
4143
} else {
42-
return a.setPhaseToUpgrading(ctx, syndesis)
44+
return a.setPhaseToUpgrading(ctx, syndesis, operatorNamespace)
4345
}
4446
}
4547

@@ -48,7 +50,19 @@ func (a checkUpdatesAction) Execute(ctx context.Context, syndesis *synapi.Syndes
4850
* needed to avoid race conditions where k8s wasn't able to update or
4951
* kubernetes didn't change the object yet
5052
*/
51-
func (a checkUpdatesAction) setPhaseToUpgrading(ctx context.Context, syndesis *synapi.Syndesis) (err error) {
53+
func (a checkUpdatesAction) setPhaseToUpgrading(ctx context.Context, syndesis *synapi.Syndesis, operatorNamespace string) (err error) {
54+
55+
// Declare an upgradeable Condition as false if applicable
56+
state := olm.ConditionState{
57+
Status: metav1.ConditionFalse,
58+
Reason: "Upgrading",
59+
Message: "Operator is upgrading the components",
60+
}
61+
err = olm.SetUpgradeCondition(ctx, a.clientTools, operatorNamespace, state)
62+
if err != nil {
63+
a.log.Error(err, "Failed to set the upgrade condition on the operator")
64+
}
65+
5266
target := syndesis.DeepCopy()
5367
target.Status.Phase = synapi.SyndesisPhaseUpgrading
5468
target.Status.TargetVersion = a.operatorVersion

install/operator/pkg/syndesis/action/initialize.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@ import (
77

88
synapi "github.com/syndesisio/syndesis/install/operator/pkg/apis/syndesis/v1beta3"
99
"github.com/syndesisio/syndesis/install/operator/pkg/syndesis/clienttools"
10+
"github.com/syndesisio/syndesis/install/operator/pkg/syndesis/olm"
1011
"sigs.k8s.io/controller-runtime/pkg/client"
1112
"sigs.k8s.io/controller-runtime/pkg/manager"
13+
14+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1215
)
1316

1417
// Initializes a Syndesis resource with no status and starts the installation process
@@ -45,6 +48,17 @@ func (a *initializeAction) Execute(ctx context.Context, syndesis *synapi.Syndesi
4548
target.Status.Description = "Cannot install two Syndesis resources in the same namespace"
4649
a.log.Error(nil, "Cannot initialize Syndesis resource because its a duplicate", "name", syndesis.Name)
4750
} else {
51+
// Declare an upgradeable Condition as false if applicable
52+
state := olm.ConditionState{
53+
Status: metav1.ConditionFalse,
54+
Reason: "Initializing",
55+
Message: "Operator is installing",
56+
}
57+
err = olm.SetUpgradeCondition(ctx, a.clientTools, operatorNamespace, state)
58+
if err != nil {
59+
a.log.Error(err, "Failed to set the upgrade condition on the operator")
60+
}
61+
4862
syndesisVersion := pkg.DefaultOperatorTag
4963
target.Status.Phase = synapi.SyndesisPhaseInstalling
5064
target.Status.Reason = synapi.SyndesisStatusReasonMissing

install/operator/pkg/syndesis/action/startup.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
synpkg "github.com/syndesisio/syndesis/install/operator/pkg"
99
synapi "github.com/syndesisio/syndesis/install/operator/pkg/apis/syndesis/v1beta3"
1010
"github.com/syndesisio/syndesis/install/operator/pkg/syndesis/clienttools"
11+
"github.com/syndesisio/syndesis/install/operator/pkg/syndesis/olm"
1112
corev1 "k8s.io/api/core/v1"
1213
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1314
"k8s.io/apimachinery/pkg/labels"
@@ -71,6 +72,17 @@ func (a *startupAction) Execute(ctx context.Context, syndesis *synapi.Syndesis,
7172
}
7273

7374
if ready {
75+
// Declare the operator upgradeable, if applicable
76+
state := olm.ConditionState{
77+
Status: metav1.ConditionTrue,
78+
Reason: "Started",
79+
Message: "Operator and components have been successfully started",
80+
}
81+
err = olm.SetUpgradeCondition(ctx, a.clientTools, operatorNamespace, state)
82+
if err != nil {
83+
a.log.Error(err, "Failed to set the upgrade condition on the operator")
84+
}
85+
7486
target := syndesis.DeepCopy()
7587
target.Status.Phase = synapi.SyndesisPhaseInstalled
7688
target.Status.Reason = synapi.SyndesisStatusReasonMissing

install/operator/pkg/syndesis/action/upgrade.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"time"
66

77
"github.com/syndesisio/syndesis/install/operator/pkg/syndesis/clienttools"
8+
"github.com/syndesisio/syndesis/install/operator/pkg/syndesis/olm"
89
"github.com/syndesisio/syndesis/install/operator/pkg/syndesis/upgrade"
910

1011
"github.com/syndesisio/syndesis/install/operator/pkg"
@@ -75,7 +76,7 @@ func (a *upgradeAction) Execute(ctx context.Context, syndesis *synapi.Syndesis,
7576
} else if syndesis.Status.Phase == synapi.SyndesisPhasePostUpgradeRunSucceed {
7677
// We land here only if the install phase after upgrading finished correctly
7778
a.log.Info("syndesis resource post upgrade ran successfully", "name", syndesis.Name, "previous version", syndesis.Status.Version, "target version", targetVersion)
78-
return a.completeUpgrade(ctx, syndesis, targetVersion)
79+
return a.completeUpgrade(ctx, syndesis, targetVersion, operatorNamespace)
7980
} else if syndesis.Status.Phase == synapi.SyndesisPhasePostUpgradeRun {
8081
// If the first run of the install action failed, we land here. We need to retry
8182
// this few times to consider the cases where install action return error due to
@@ -103,7 +104,18 @@ func (a *upgradeAction) Execute(ctx context.Context, syndesis *synapi.Syndesis,
103104
* needed to avoid race conditions where k8s wasn't yet able to update or
104105
* kubernetes didn't change the object yet
105106
*/
106-
func (a *upgradeAction) completeUpgrade(ctx context.Context, syndesis *synapi.Syndesis, newVersion string) (err error) {
107+
func (a *upgradeAction) completeUpgrade(ctx context.Context, syndesis *synapi.Syndesis, newVersion string, operatorNamespace string) (err error) {
108+
// Declare the operator upgradeable, if applicable
109+
state := olm.ConditionState{
110+
Status: metav1.ConditionTrue,
111+
Reason: "CompletedUpgrade",
112+
Message: "Operator component state has been upgraded",
113+
}
114+
err = olm.SetUpgradeCondition(ctx, a.clientTools, operatorNamespace, state)
115+
if err != nil {
116+
a.log.Error(err, "Failed to set the upgrade condition on the operator")
117+
}
118+
107119
target := syndesis.DeepCopy()
108120
target.Status.Phase = synapi.SyndesisPhaseInstalled
109121
target.Status.TargetVersion = ""

install/operator/pkg/syndesis/clienttools/clienttools.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
olmapiv1 "github.com/operator-framework/api/pkg/operators/v1"
2323
olmapiv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
2424
olmapiv1alpha2 "github.com/operator-framework/api/pkg/operators/v1alpha2"
25+
olmapiv2 "github.com/operator-framework/api/pkg/operators/v2"
2526
olmcli "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned"
2627
olmpkgsvr "github.com/operator-framework/operator-lifecycle-manager/pkg/package-server/apis/operators/v1"
2728
"github.com/syndesisio/syndesis/install/operator/pkg/util"
@@ -74,6 +75,7 @@ func (ck *ClientTools) GetScheme() *runtime.Scheme {
7475
olmapiv1alpha2.SchemeBuilder.AddToScheme(ck.scheme)
7576
olmapiv1alpha1.SchemeBuilder.AddToScheme(ck.scheme)
7677
olmapiv1.SchemeBuilder.AddToScheme(ck.scheme)
78+
olmapiv2.AddToScheme(ck.scheme)
7779
olmpkgsvr.SchemeBuilder.AddToScheme(ck.scheme)
7880
projectv1.AddToScheme(ck.scheme)
7981
}

install/operator/pkg/syndesis/configuration/configuration.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,26 @@ func GetProperties(ctx context.Context, file string, clientTools *clienttools.Cl
420420
return configuration, nil
421421
}
422422

423+
// Load the configuration and return the name of this product
424+
func GetProductName(file string) (string, error) {
425+
configuration := &Config{}
426+
if err := configuration.loadFromFile(file); err != nil {
427+
return "", err
428+
}
429+
430+
return configuration.ProductName, nil
431+
}
432+
433+
// Load the configuration and return the name of this product
434+
func GetVersion(file string) (string, error) {
435+
configuration := &Config{}
436+
if err := configuration.loadFromFile(file); err != nil {
437+
return "", err
438+
}
439+
440+
return configuration.Version, nil
441+
}
442+
423443
// Load configuration from config file. Config file is expected to be a yaml
424444
// The returned configuration is parsed to JSON and returned as a Config object
425445
func (config *Config) loadFromFile(file string) error {

install/operator/pkg/syndesis/configuration/configuration_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,26 @@ func Test_loadFromFile(t *testing.T) {
105105
}
106106
}
107107

108+
func Test_getProductName(t *testing.T) {
109+
configFile := "../../../build/conf/config-test.yaml"
110+
name, err := GetProductName(configFile)
111+
assert.NoError(t, err)
112+
113+
andOrName := func() bool {
114+
return name == "syndesis" || name == "fuse-online"
115+
}
116+
117+
assert.Condition(t, andOrName)
118+
}
119+
120+
func Test_getVersion(t *testing.T) {
121+
configFile := "../../../build/conf/config-test.yaml"
122+
version, err := GetVersion(configFile)
123+
assert.NoError(t, err)
124+
125+
assert.Equal(t, "7.7.0", version)
126+
}
127+
108128
func Test_setConfigFromEnv(t *testing.T) {
109129
tests := []struct {
110130
name string

0 commit comments

Comments
 (0)