Skip to content

Commit cc8e282

Browse files
committed
(feat) upgrade SveltosApplier
Initial manual deployment of SveltosApplier is required in the managed cluster. Following this, the classifier ensures automatic upgrades as needed. The upgrade process is handled by passing SveltosApplier resources through ConfigurationGroups to the managed cluster, which then applies these resources to self-upgrade.
1 parent ca4d474 commit cc8e282

File tree

7 files changed

+395
-4
lines changed

7 files changed

+395
-4
lines changed

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,8 @@ sveltos-applier:
448448
@echo "Downloading sveltos applier yaml"
449449
$(eval digest :=$(call get-digest-sveltos-applier))
450450
@echo "image digest is $(get-digest-sveltos-applier)"
451+
curl -L -H "Authorization: token $$GITHUB_PAT" https://raw.githubusercontent.com/projectsveltos/sveltos-applier/main/manifest/manifest.yaml -o ./pkg/agent/sveltos-applier.yaml
452+
cd pkg/agent; go generate
451453
curl -L -H "Authorization: token $$GITHUB_PAT" https://raw.githubusercontent.com/projectsveltos/sveltos-applier/main/manifest/manifest.yaml -o ./test/pullmode-sveltosapplier.yaml
452454
sed -i '' -e "s#image: docker.io/projectsveltos/sveltos-applier:${TAG}#image: docker.io/projectsveltos/sveltos-applier@${digest}#g" ./test/pullmode-sveltosapplier.yaml
453455
sed -i '' -e "s#cluster-namespace=#cluster-namespace=default#g" ./test/pullmode-sveltosapplier.yaml

controllers/classifier_deployer.go

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ type feature struct {
6666
}
6767

6868
const (
69+
sveltosApplier = "sveltos-applier"
70+
6971
sveltosAgent = "sveltos-agent"
7072
sveltosAgentFeatureLabelKey = "feature"
7173
sveltosAgentClusterNamespaceLabel = "cluster-namespace"
@@ -540,6 +542,16 @@ func deployClassifierInCluster(ctx context.Context, c client.Client,
540542
if err != nil {
541543
return err
542544
}
545+
546+
// Initially, a user needs to manually deploy SveltosApplier in a managed cluster. After this initial
547+
// deployment, the classifier will automatically handle any necessary upgrades. The SveltosApplier
548+
// resources are passed to the SveltosApplier running in the managed cluster via ConfigurationGroups.
549+
// The SveltosApplier then applies these resources, effectively upgrading itself.
550+
err = upgradeSveltosApplierInManagedCluster(ctx, clusterNamespace, clusterName, applicant,
551+
clusterType, logger)
552+
if err != nil {
553+
return err
554+
}
543555
}
544556

545557
err = deployCRDs(ctx, clusterNamespace, clusterName, applicant, clusterType, isPullMode, logger)
@@ -1396,6 +1408,22 @@ func prepareSveltosAgentYAML(agentYAML, clusterNamespace, clusterName, mode stri
13961408
return agentYAML
13971409
}
13981410

1411+
func prepareSveltosApplierYAML(agentYAML, clusterNamespace, clusterName string,
1412+
clusterType libsveltosv1beta1.ClusterType) string {
1413+
1414+
agentYAML = strings.ReplaceAll(agentYAML, "cluster-namespace=", fmt.Sprintf("cluster-namespace=%s", clusterNamespace))
1415+
agentYAML = strings.ReplaceAll(agentYAML, "cluster-name=", fmt.Sprintf("cluster-name=%s", clusterName))
1416+
agentYAML = strings.ReplaceAll(agentYAML, "cluster-type=", fmt.Sprintf("cluster-type=%s", clusterType))
1417+
agentYAML = strings.ReplaceAll(agentYAML, "v=5", "v=0")
1418+
1419+
registry := GetSveltosAgentRegistry()
1420+
if registry != "" {
1421+
agentYAML = replaceRegistry(agentYAML, registry)
1422+
}
1423+
1424+
return agentYAML
1425+
}
1426+
13991427
// createSveltosAgentNamespaceInManagedCluster creates the namespace where sveltos-agent will
14001428
// store all its reports
14011429
func createSveltosAgentNamespaceInManagedCluster(ctx context.Context, c client.Client,
@@ -1488,6 +1516,18 @@ func deploySveltosAgentInManagedCluster(ctx context.Context, remoteRestConfig *r
14881516
remoteRestConfig, agentYAML, nil, patches, isPullMode, logger)
14891517
}
14901518

1519+
func upgradeSveltosApplierInManagedCluster(ctx context.Context, clusterNamespace, clusterName, classifierName string,
1520+
clusterType libsveltosv1beta1.ClusterType, logger logr.Logger) error {
1521+
1522+
logger.V(logs.LogDebug).Info("upgrade sveltos-applier in the managed cluster")
1523+
1524+
agentYAML := string(agent.GetSveltosApplierAML())
1525+
agentYAML = prepareSveltosApplierYAML(agentYAML, clusterNamespace, clusterName, clusterType)
1526+
1527+
return deploySveltosApplierResources(ctx, clusterNamespace, clusterName, classifierName,
1528+
agentYAML, logger)
1529+
}
1530+
14911531
func deploySveltosAgentInManagementCluster(ctx context.Context, restConfig *rest.Config, c client.Client,
14921532
clusterNamespace, clusterName, classifierName, mode string, clusterType libsveltosv1beta1.ClusterType,
14931533
patches []libsveltosv1beta1.Patch, logger logr.Logger) error {
@@ -1527,7 +1567,7 @@ func deploySveltosAgentResources(ctx context.Context, clusterNamespace, clusterN
15271567
for i := range elements {
15281568
policy, err := k8s_utils.GetUnstructured([]byte(elements[i]))
15291569
if err != nil {
1530-
logger.V(logs.LogInfo).Info(fmt.Sprintf("failed to parse classifier agent yaml: %v", err))
1570+
logger.V(logs.LogInfo).Info(fmt.Sprintf("failed to parse sveltos agent yaml: %v", err))
15311571
return err
15321572
}
15331573

@@ -1588,6 +1628,34 @@ func deploySveltosAgentResources(ctx context.Context, clusterNamespace, clusterN
15881628
return nil
15891629
}
15901630

1631+
func deploySveltosApplierResources(ctx context.Context, clusterNamespace, clusterName, cliassifierName string,
1632+
agentYAML string, logger logr.Logger) error {
1633+
1634+
resources := make(map[string][]unstructured.Unstructured)
1635+
index := sveltosApplier
1636+
resources[index] = []unstructured.Unstructured{}
1637+
1638+
elements, err := deployer.CustomSplit(agentYAML)
1639+
if err != nil {
1640+
return err
1641+
}
1642+
for i := range elements {
1643+
policy, err := k8s_utils.GetUnstructured([]byte(elements[i]))
1644+
if err != nil {
1645+
logger.V(logs.LogInfo).Info(fmt.Sprintf("failed to parse sveltos applier yaml: %v", err))
1646+
return err
1647+
}
1648+
1649+
var referencedUnstructured []*unstructured.Unstructured
1650+
referencedUnstructured = append(referencedUnstructured, policy)
1651+
1652+
resources[index] = append(resources[index], convertPointerSliceToValueSlice(referencedUnstructured)...)
1653+
}
1654+
1655+
return pullmode.StageResourcesForDeployment(ctx, getManagementClusterClient(), clusterNamespace, clusterName,
1656+
libsveltosv1beta1.ClassifierKind, cliassifierName, libsveltosv1beta1.FeatureClassifier, resources, true, logger)
1657+
}
1658+
15911659
func deploySveltosAgentPatchedResources(ctx context.Context, restConfig *rest.Config,
15921660
referencedUnstructured []*unstructured.Unstructured, logger logr.Logger) error {
15931661

generator.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,9 @@ func main() {
9191
sveltosAgentFile := "../../pkg/agent/sveltos-agent.yaml"
9292
generate(sveltosAgentFile, "sveltos-agent", "sveltosAgent")
9393

94-
driftDetectionManagerInMgmtClusterFile := "../../pkg/agent/sveltos-agent-in-mgmt-cluster.yaml"
95-
generate(driftDetectionManagerInMgmtClusterFile, "sveltos-agent-in-mgmt-cluster", "sveltosAgentInMgmtCluster")
94+
sveltosAgentInMgmtClusterFile := "../../pkg/agent/sveltos-agent-in-mgmt-cluster.yaml"
95+
generate(sveltosAgentInMgmtClusterFile, "sveltos-agent-in-mgmt-cluster", "sveltosAgentInMgmtCluster")
9696

97+
sveltosApplierFile := "../../pkg/agent/sveltos-applier.yaml"
98+
generate(sveltosApplierFile, "sveltos-applier", "sveltosApplier")
9799
}

pkg/agent/agent.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,7 @@ func GetSveltosAgentYAML() []byte {
2525
func GetSveltosAgentInMgmtClusterYAML() []byte {
2626
return sveltosAgentInMgmtClusterYAML
2727
}
28+
29+
func GetSveltosApplierAML() []byte {
30+
return sveltosApplierYAML
31+
}

pkg/agent/sveltos-applier.go

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
// Generated by *go generate* - DO NOT EDIT
2+
/*
3+
Copyright 2022-23. projectsveltos.io. All rights reserved.
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
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+
package agent
18+
19+
var sveltosApplierYAML = []byte(`apiVersion: v1
20+
kind: Namespace
21+
metadata:
22+
labels:
23+
app.kubernetes.io/name: sveltos-applier
24+
name: projectsveltos
25+
---
26+
apiVersion: v1
27+
kind: ServiceAccount
28+
metadata:
29+
labels:
30+
app.kubernetes.io/name: sveltos-applier
31+
name: sveltos-applier-manager
32+
namespace: projectsveltos
33+
---
34+
apiVersion: rbac.authorization.k8s.io/v1
35+
kind: ClusterRole
36+
metadata:
37+
name: sveltos-applier-manager-role
38+
rules:
39+
- apiGroups:
40+
- '*'
41+
resources:
42+
- '*'
43+
verbs:
44+
- '*'
45+
---
46+
apiVersion: rbac.authorization.k8s.io/v1
47+
kind: ClusterRoleBinding
48+
metadata:
49+
labels:
50+
app.kubernetes.io/name: sveltos-applier
51+
name: sveltos-applier-manager-rolebinding
52+
roleRef:
53+
apiGroup: rbac.authorization.k8s.io
54+
kind: ClusterRole
55+
name: sveltos-applier-manager-role
56+
subjects:
57+
- kind: ServiceAccount
58+
name: sveltos-applier-manager
59+
namespace: projectsveltos
60+
---
61+
apiVersion: v1
62+
kind: Service
63+
metadata:
64+
labels:
65+
app.kubernetes.io/name: sveltos-applier
66+
name: sveltos-applier-metrics-service
67+
namespace: projectsveltos
68+
spec:
69+
ports:
70+
- name: https
71+
port: 8443
72+
protocol: TCP
73+
targetPort: 8443
74+
selector:
75+
app.kubernetes.io/name: sveltos-applier
76+
---
77+
apiVersion: apps/v1
78+
kind: Deployment
79+
metadata:
80+
labels:
81+
app.kubernetes.io/name: sveltos-applier
82+
name: sveltos-applier-manager
83+
namespace: projectsveltos
84+
spec:
85+
replicas: 1
86+
selector:
87+
matchLabels:
88+
app.kubernetes.io/name: sveltos-applier
89+
template:
90+
metadata:
91+
annotations:
92+
kubectl.kubernetes.io/default-container: controller
93+
labels:
94+
app.kubernetes.io/name: sveltos-applier
95+
spec:
96+
containers:
97+
- args:
98+
- --diagnostics-address=:8443
99+
- --cluster-namespace=
100+
- --cluster-name=
101+
- --cluster-type=
102+
- --secret-with-kubeconfig=
103+
- --v=5
104+
- --version=main
105+
command:
106+
- /manager
107+
env:
108+
- name: GOMEMLIMIT
109+
valueFrom:
110+
resourceFieldRef:
111+
resource: limits.memory
112+
- name: GOMAXPROCS
113+
valueFrom:
114+
resourceFieldRef:
115+
resource: limits.cpu
116+
- name: NAMESPACE
117+
valueFrom:
118+
fieldRef:
119+
fieldPath: metadata.namespace
120+
image: docker.io/projectsveltos/sveltos-applier:main
121+
livenessProbe:
122+
failureThreshold: 3
123+
httpGet:
124+
path: /healthz
125+
port: healthz
126+
scheme: HTTP
127+
initialDelaySeconds: 15
128+
periodSeconds: 20
129+
name: controller
130+
ports:
131+
- containerPort: 8443
132+
name: metrics
133+
protocol: TCP
134+
- containerPort: 9440
135+
name: healthz
136+
protocol: TCP
137+
readinessProbe:
138+
failureThreshold: 3
139+
httpGet:
140+
path: /readyz
141+
port: healthz
142+
scheme: HTTP
143+
initialDelaySeconds: 5
144+
periodSeconds: 10
145+
resources:
146+
limits:
147+
cpu: 500m
148+
memory: 512Mi
149+
requests:
150+
cpu: 200m
151+
memory: 512Mi
152+
securityContext:
153+
allowPrivilegeEscalation: false
154+
capabilities:
155+
drop:
156+
- ALL
157+
seccompProfile:
158+
type: RuntimeDefault
159+
volumeMounts: []
160+
securityContext:
161+
runAsNonRoot: true
162+
seccompProfile:
163+
type: RuntimeDefault
164+
serviceAccountName: sveltos-applier-manager
165+
terminationGracePeriodSeconds: 10
166+
volumes: []
167+
`)

0 commit comments

Comments
 (0)