Skip to content

Commit 67f88ed

Browse files
committed
feat: Make addon provider configurable
1 parent 41d9cc8 commit 67f88ed

File tree

13 files changed

+231
-21
lines changed

13 files changed

+231
-21
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ clusterctl generate cluster capi-quickstart \
2525
--control-plane-machine-count=1 \
2626
--worker-machine-count=1 | \
2727
gojq --yaml-input --yaml-output --slurp \
28-
'.[] | (select( .kind=="Cluster").metadata.labels += {"capi-runtime-extensions.d2iq-labs.com/cni": "calico"})' \
28+
'.[] | (select( .kind=="Cluster").metadata.labels += {"capi-runtime-extensions.d2iq-labs.com/cni": "calico"})' | \
2929
kubectl apply -f -
3030
```
3131

charts/capi-runtime-extensions/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,14 @@ A Helm chart for capi-runtime-extensions
2525

2626
| Key | Type | Default | Description |
2727
|-----|------|---------|-------------|
28+
| addons.provider | string | `"ClusterResourceSet"` | |
2829
| certificate.issuer.kind | string | `"Issuer"` | |
29-
| certificate.issuer.name | string | `nil` | |
30+
| certificate.issuer.name | string | `""` | |
3031
| certificate.issuer.selfSigned | bool | `true` | |
3132
| env | object | `{}` | |
3233
| image.pullPolicy | string | `"IfNotPresent"` | |
3334
| image.repository | string | `"ghcr.io/d2iq-labs/capi-runtime-extensions"` | |
34-
| image.tag | string | `nil` | |
35+
| image.tag | string | `""` | |
3536
| imagePullSecrets | list | `[]` | Optional secrets used for pulling the container image |
3637
| nodeSelector | object | `{}` | |
3738
| priorityClassName | string | `""` | Optional priority class to be used for the pod. |
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
{
2+
"$schema": "http://json-schema.org/schema#",
3+
"type": "object",
4+
"properties": {
5+
"addons": {
6+
"type": "object",
7+
"properties": {
8+
"provider": {
9+
"type": "string",
10+
"enum": ["ClusterResourceSet", "FluxHelmRelease"]
11+
}
12+
}
13+
},
14+
"certificate": {
15+
"type": "object",
16+
"properties": {
17+
"issuer": {
18+
"type": "object",
19+
"properties": {
20+
"kind": {
21+
"type": "string",
22+
"enum": ["Issuer", "ClusterIssuer"],
23+
"default": "Issuer"
24+
},
25+
"name": {
26+
"type": "string"
27+
},
28+
"selfSigned": {
29+
"type": "boolean"
30+
}
31+
}
32+
}
33+
}
34+
},
35+
"env": {
36+
"type": "object"
37+
},
38+
"image": {
39+
"type": "object",
40+
"properties": {
41+
"pullPolicy": {
42+
"type": "string",
43+
"default": "IfNotPresent"
44+
},
45+
"repository": {
46+
"type": "string"
47+
},
48+
"tag": {
49+
"type": "string"
50+
}
51+
}
52+
},
53+
"imagePullSecrets": {
54+
"type": "array"
55+
},
56+
"nodeSelector": {
57+
"type": "object"
58+
},
59+
"priorityClassName": {
60+
"type": "string"
61+
},
62+
"resources": {
63+
"type": "object",
64+
"properties": {
65+
"limits": {
66+
"type": "object",
67+
"properties": {
68+
"cpu": {
69+
"type": "string"
70+
},
71+
"memory": {
72+
"type": "string"
73+
}
74+
}
75+
},
76+
"requests": {
77+
"type": "object",
78+
"properties": {
79+
"cpu": {
80+
"type": "string"
81+
},
82+
"memory": {
83+
"type": "string"
84+
}
85+
}
86+
}
87+
}
88+
},
89+
"securityContext": {
90+
"type": "object",
91+
"properties": {
92+
"runAsUser": {
93+
"type": "integer"
94+
}
95+
}
96+
},
97+
"service": {
98+
"type": "object",
99+
"properties": {
100+
"annotations": {
101+
"type": "object"
102+
},
103+
"port": {
104+
"type": "integer"
105+
},
106+
"type": {
107+
"type": "string"
108+
}
109+
}
110+
},
111+
"tolerations": {
112+
"type": "array"
113+
}
114+
}
115+
}

charts/capi-runtime-extensions/values.yaml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
# Copyright 2023 D2iQ, Inc. All rights reserved.
22
# SPDX-License-Identifier: Apache-2.0
33

4+
addons:
5+
provider: ClusterResourceSet
6+
47
image:
58
repository: ghcr.io/d2iq-labs/capi-runtime-extensions
6-
tag:
9+
tag: ""
710
pullPolicy: IfNotPresent
811

912
# -- Optional secrets used for pulling the container image
@@ -13,7 +16,7 @@ imagePullSecrets: []
1316
certificate:
1417
issuer:
1518
selfSigned: true
16-
name:
19+
name: ""
1720
kind: Issuer
1821

1922
env: {}

cmd/capi-runtime-extensions/flags.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2023 D2iQ, Inc. All rights reserved.
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package main
5+
6+
import (
7+
"fmt"
8+
9+
"github.com/spf13/pflag"
10+
11+
"github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers/lifecycle"
12+
)
13+
14+
type addonProviderValue lifecycle.AddonProvider
15+
16+
func (v addonProviderValue) String() string {
17+
return string(v)
18+
}
19+
20+
func (v *addonProviderValue) Set(value string) error {
21+
switch lifecycle.AddonProvider(value) {
22+
case lifecycle.ClusterResourceSetAddonProvider, lifecycle.FluxHelmReleaseAddonProvider:
23+
break
24+
default:
25+
return fmt.Errorf(
26+
"invalid addon provider: %q (must be one of %v)",
27+
value,
28+
[]string{
29+
string(lifecycle.ClusterResourceSetAddonProvider),
30+
string(lifecycle.FluxHelmReleaseAddonProvider),
31+
},
32+
)
33+
}
34+
35+
*v = addonProviderValue(value)
36+
37+
return nil
38+
}
39+
40+
func (*addonProviderValue) Type() string {
41+
return "addonProvider"
42+
}
43+
44+
func newAddonProviderValue(val lifecycle.AddonProvider, p *lifecycle.AddonProvider) pflag.Value {
45+
*p = val
46+
return (*addonProviderValue)(p)
47+
}

cmd/capi-runtime-extensions/main.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package main
55

66
import (
77
"flag"
8+
"fmt"
89
"net/http"
910
"os"
1011
"time"
@@ -31,6 +32,7 @@ var (
3132
profilerAddress string
3233
webhookPort int
3334
webhookCertDir string
35+
addonProvider lifecycle.AddonProvider
3436
logOptions = logs.NewOptions()
3537
)
3638

@@ -49,6 +51,18 @@ func InitFlags(fs *pflag.FlagSet) {
4951

5052
fs.StringVar(&webhookCertDir, "webhook-cert-dir", "/tmp/k8s-webhook-server/serving-certs/",
5153
"Webhook cert dir, only used when webhook-port is specified.")
54+
55+
fs.Var(newAddonProviderValue(
56+
lifecycle.ClusterResourceSetAddonProvider, &addonProvider),
57+
"addon-provider",
58+
fmt.Sprintf(
59+
"addon provider (one of %v)",
60+
[]string{
61+
string(lifecycle.ClusterResourceSetAddonProvider),
62+
string(lifecycle.FluxHelmReleaseAddonProvider),
63+
},
64+
),
65+
)
5266
}
5367

5468
func main() {
@@ -114,7 +128,7 @@ func main() {
114128
}
115129

116130
// Create the ExtensionHandlers for the lifecycle hooks
117-
lifecycleExtensionHandlers := lifecycle.NewExtensionHandlers(client)
131+
lifecycleExtensionHandlers := lifecycle.NewExtensionHandlers(addonProvider, client)
118132

119133
// Register extension handlers.
120134
if err := webhookServer.AddExtensionHandler(server.ExtensionHandler{

hack/addons/update-calico-manifests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,4 @@ curl -fsSL "https://docs.projectcalico.org/archive/${CALICO_VERSION}/manifests/t
3333

3434
kubectl create configmap tigera-operator --dry-run=client --output yaml \
3535
--from-file "${CALICO_CNI_ASSETS_DIR}/tigera-operator.json" \
36-
>"${GIT_REPO_ROOT}/pkg/addons/templates/cni/tigera-operator-configmap.yaml"
36+
>"${GIT_REPO_ROOT}/pkg/addons/clusterresourcesets/templates/cni/tigera-operator-configmap.yaml"

pkg/addons/cni.go renamed to pkg/addons/clusterresourcesets/cni.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2023 D2iQ, Inc. All rights reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
package addons
4+
package clusterresourcesets
55

66
import (
77
_ "embed" // embedding as []byte does not import the package.

pkg/addons/crs.go renamed to pkg/addons/clusterresourcesets/crs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright 2023 D2iQ, Inc. All rights reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4-
package addons
4+
package clusterresourcesets
55

66
import (
77
"fmt"

pkg/addons/templates/cni/tigera-operator-configmap.yaml renamed to pkg/addons/clusterresourcesets/templates/cni/tigera-operator-configmap.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Copyright 2023 D2iQ, Inc. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
14
apiVersion: v1
25
data:
36
tigera-operator.json: |

pkg/handlers/lifecycle/handlers.go

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,38 @@ package lifecycle
55

66
import (
77
"context"
8+
"fmt"
89

10+
"sigs.k8s.io/cluster-api/api/v1beta1"
911
runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1"
1012
ctrl "sigs.k8s.io/controller-runtime"
1113
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
1214

13-
"github.com/d2iq-labs/capi-runtime-extensions/pkg/addons"
15+
"github.com/d2iq-labs/capi-runtime-extensions/pkg/addons/clusterresourcesets"
1416
k8sclient "github.com/d2iq-labs/capi-runtime-extensions/pkg/k8s/client"
1517
)
1618

19+
type AddonProvider string
20+
21+
const (
22+
ClusterResourceSetAddonProvider AddonProvider = "ClusterResourceSet"
23+
FluxHelmReleaseAddonProvider AddonProvider = "FluxHelmRelease"
24+
)
25+
1726
// ExtensionHandlers provides a common struct shared across the lifecycle hook handlers.
1827
type ExtensionHandlers struct {
19-
client ctrlclient.Client
28+
addonProvider AddonProvider
29+
client ctrlclient.Client
2030
}
2131

2232
// NewExtensionHandlers returns a ExtensionHandlers for the lifecycle hooks handlers.
23-
func NewExtensionHandlers(client ctrlclient.Client) *ExtensionHandlers {
33+
func NewExtensionHandlers(
34+
addonProvider AddonProvider,
35+
client ctrlclient.Client,
36+
) *ExtensionHandlers {
2437
return &ExtensionHandlers{
25-
client: client,
38+
addonProvider: addonProvider,
39+
client: client,
2640
}
2741
}
2842

@@ -45,18 +59,18 @@ func (m *ExtensionHandlers) DoAfterControlPlaneInitialized(
4559

4660
genericResourcesClient := k8sclient.NewGenericResourcesClient(m.client, log)
4761

48-
// Create CNI ClusterResourceSet and let the CAPI controller reconcile it
49-
objs, err := addons.CNIForCluster(&request.Cluster)
50-
if err != nil {
51-
response.Status = runtimehooksv1.ResponseStatusFailure
52-
response.Message = err.Error()
53-
return
62+
var err error
63+
switch m.addonProvider {
64+
case ClusterResourceSetAddonProvider:
65+
err = applyCNICRS(ctx, &request.Cluster, genericResourcesClient)
66+
case FluxHelmReleaseAddonProvider:
67+
// TODO Apply flux helm releases
68+
default:
69+
err = fmt.Errorf("unsupported provider: %q", m.addonProvider)
5470
}
55-
err = genericResourcesClient.Apply(ctx, objs)
5671
if err != nil {
5772
response.Status = runtimehooksv1.ResponseStatusFailure
5873
response.Message = err.Error()
59-
return
6074
}
6175
}
6276

@@ -77,3 +91,16 @@ func (m *ExtensionHandlers) DoBeforeClusterDelete(
7791
log := ctrl.LoggerFrom(ctx)
7892
log.Info("BeforeClusterDelete is called")
7993
}
94+
95+
func applyCNICRS(
96+
ctx context.Context,
97+
cluster *v1beta1.Cluster,
98+
genericResourcesClient *k8sclient.GenericResourcesClient,
99+
) error {
100+
// Create CNI ClusterResourceSet and let the CAPI controller reconcile it.
101+
objs, err := clusterresourcesets.CNIForCluster(cluster)
102+
if err != nil {
103+
return err
104+
}
105+
return genericResourcesClient.Apply(ctx, objs)
106+
}

0 commit comments

Comments
 (0)