Skip to content

Commit 82f4792

Browse files
authored
Merge pull request #7288 from fabriziopandini/support-ipam-and-runtime-extension-providers
✨ Support IPAM and runtime extension providers
2 parents c6cbae8 + 2fb12b1 commit 82f4792

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+630
-529
lines changed

Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -612,8 +612,8 @@ docker-capd-build-all: $(addprefix docker-capd-build-,$(ALL_ARCH)) ## Build capd
612612
.PHONY: docker-build-test-extension
613613
docker-build-test-extension: ## Build the docker image for core controller manager
614614
DOCKER_BUILDKIT=1 docker build --build-arg builder_image=$(GO_CONTAINER_IMAGE) --build-arg goproxy=$(GOPROXY) --build-arg ARCH=$(ARCH) --build-arg ldflags="$(LDFLAGS)" . -t $(TEST_EXTENSION_IMG)-$(ARCH):$(TAG) --file ./test/extension/Dockerfile
615-
$(MAKE) set-manifest-image MANIFEST_IMG=$(TEST_EXTENSION_IMG)-$(ARCH) MANIFEST_TAG=$(TAG) TARGET_RESOURCE="./test/extension/config/default/extension_image_patch.yaml"
616-
$(MAKE) set-manifest-pull-policy TARGET_RESOURCE="./test/extension/config/default/extension_pull_policy.yaml"
615+
$(MAKE) set-manifest-image MANIFEST_IMG=$(TEST_EXTENSION_IMG)-$(ARCH) MANIFEST_TAG=$(TAG) TARGET_RESOURCE="./test/extension/config/default/manager_image_patch.yaml"
616+
$(MAKE) set-manifest-pull-policy TARGET_RESOURCE="./test/extension/config/default/manager_pull_policy.yaml"
617617

618618
.PHONY: e2e-framework
619619
e2e-framework: ## Builds the CAPI e2e framework
@@ -710,6 +710,7 @@ tilt-up: kind-cluster ## Start tilt and build kind cluster if needed.
710710
docker-build-e2e: ## Rebuild all Cluster API provider images to be used in the e2e tests
711711
$(MAKE) docker-build REGISTRY=gcr.io/k8s-staging-cluster-api PULL_POLICY=IfNotPresent
712712
$(MAKE) docker-capd-build REGISTRY=gcr.io/k8s-staging-cluster-api PULL_POLICY=IfNotPresent
713+
$(MAKE) docker-build-test-extension REGISTRY=gcr.io/k8s-staging-cluster-api PULL_POLICY=IfNotPresent
713714

714715
## --------------------------------------
715716
## Release

Tiltfile

Lines changed: 19 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -104,30 +104,30 @@ providers = {
104104
"internal",
105105
"third_party",
106106
],
107+
"label": "CAPD",
108+
# Add kubectl to the docker image, CAPD manager requires it.
107109
"additional_docker_helper_commands": "RUN curl -LO https://dl.k8s.io/release/{KUBE}/bin/linux/{ARCH}/kubectl && chmod +x ./kubectl && mv ./kubectl /usr/bin/kubectl".format(
108110
ARCH = os_arch,
109111
KUBE = kubernetes_version,
110112
),
111113
"additional_docker_build_commands": """
112114
COPY --from=tilt-helper /usr/bin/kubectl /usr/bin/kubectl
113115
""",
114-
"label": "CAPD",
115116
},
116-
}
117-
118-
# Create a data structure to hold information about addons.
119-
addons = {
120117
"test-extension": {
121-
"context": "./test/extension",
118+
"context": "test/extension",
122119
"image": "gcr.io/k8s-staging-cluster-api/test-extension",
123-
"container_name": "extension",
124-
"live_reload_deps": ["main.go", "handlers"],
120+
"live_reload_deps": [
121+
"main.go",
122+
"handlers",
123+
],
125124
"label": "test-extension",
126-
"resource_deps": ["capi_controller"],
125+
# Add the ExtensionConfig for this Runtime extension; given that the ExtensionConfig can be installed only when capi_controller
126+
# are up and running, it is required to set a resource_deps to ensure proper install order.
127127
"additional_resources": [
128128
"config/tilt/extensionconfig.yaml",
129-
"config/tilt/hookresponses-configmap.yaml",
130129
],
130+
"resource_deps": ["capi_controller"],
131131
},
132132
}
133133

@@ -165,27 +165,6 @@ def load_provider_tiltfiles():
165165
provider_config["go_main"] = "main.go"
166166
providers[provider_name] = provider_config
167167

168-
# load_addon_tiltfiles looks for tilt-addon.[yaml|json] files in the repositories listed in "addon_repos" in tilt settings and loads their config.
169-
def load_addon_tiltfiles():
170-
addon_repos = settings.get("addon_repos", [])
171-
for repo in addon_repos:
172-
file = repo + "/tilt-addon.yaml" if os.path.exists(repo + "/tilt-addon.yaml") else repo + "/tilt-addon.json"
173-
if not os.path.exists(file):
174-
fail("Failed to load provider. No tilt-addon.{yaml|json} file found in " + repo)
175-
addon_details = read_yaml(file, default = {})
176-
if type(addon_details) != type([]):
177-
addon_details = [addon_details]
178-
for item in addon_details:
179-
addon_name = item["name"]
180-
addon_config = item["config"]
181-
if "context" in addon_config:
182-
addon_config["context"] = repo + "/" + addon_config["context"]
183-
else:
184-
addon_config["context"] = repo
185-
if "go_main" not in addon_config:
186-
addon_config["go_main"] = "main.go"
187-
addons[addon_name] = addon_config
188-
189168
tilt_helper_dockerfile_header = """
190169
# Tilt image
191170
FROM golang:1.19.0 as tilt-helper
@@ -312,7 +291,6 @@ def get_port_forwards(debug):
312291
# 2. Configures a docker build for the provider, with live updating of the manager binary
313292
# 3. Runs kustomize for the provider's config/default and applies it
314293
def enable_provider(name, debug):
315-
deployment_kind = "provider"
316294
p = providers.get(name)
317295
label = p.get("label")
318296

@@ -336,77 +314,26 @@ def enable_provider(name, debug):
336314
port_forwards = port_forwards,
337315
)
338316

317+
additional_objs = []
318+
p_resources = p.get("additional_resources", [])
319+
for resource in p_resources:
320+
k8s_yaml(p.get("context") + "/" + resource)
321+
additional_objs = additional_objs + decode_yaml_stream(read_file(p.get("context") + "/" + resource))
322+
339323
if p.get("kustomize_config", True):
340-
yaml = read_file("./.tiltbuild/yaml/{}.{}.yaml".format(name, deployment_kind))
324+
yaml = read_file("./.tiltbuild/yaml/{}.provider.yaml".format(name))
341325
k8s_yaml(yaml)
342326
objs = decode_yaml_stream(yaml)
343327
k8s_resource(
344328
workload = find_object_name(objs, "Deployment"),
345-
objects = [find_object_qualified_name(objs, "Provider")],
329+
objects = [find_object_qualified_name(objs, "Provider")] + find_all_objects_names(additional_objs),
346330
new_name = label.lower() + "_controller",
347331
labels = [label, "ALL.controllers"],
348332
port_forwards = port_forwards,
349333
links = links,
350-
resource_deps = ["provider_crd"],
351-
)
352-
353-
# Configures an addon by doing the following:
354-
#
355-
# 1. Enables a local_resource go build of the addon's manager binary
356-
# 2. Configures a docker build for the addon, with live updating of the binary
357-
# 3. Runs kustomize for the addons's config/default and applies it
358-
def enable_addon(name, debug):
359-
addon = addons.get(name)
360-
deployment_kind = "addon"
361-
label = addon.get("label")
362-
port_forwards, links = get_port_forwards(debug)
363-
364-
build_go_binary(
365-
context = addon.get("context"),
366-
reload_deps = addon.get("live_reload_deps"),
367-
debug = debug,
368-
go_main = addon.get("go_main", "main.go"),
369-
binary_name = "extension",
370-
label = label,
371-
)
372-
373-
build_docker_image(
374-
image = addon.get("image"),
375-
context = addon.get("context"),
376-
binary_name = "extension",
377-
additional_docker_helper_commands = addon.get("additional_docker_helper_commands", ""),
378-
additional_docker_build_commands = addon.get("additional_docker_build_commands", ""),
379-
port_forwards = port_forwards,
380-
)
381-
382-
additional_objs = []
383-
addon_resources = addon.get("additional_resources", [])
384-
for resource in addon_resources:
385-
k8s_yaml(addon.get("context") + "/" + resource)
386-
additional_objs = additional_objs + decode_yaml_stream(read_file(addon.get("context") + "/" + resource))
387-
388-
if addon.get("kustomize_config", True):
389-
yaml = read_file("./.tiltbuild/yaml/{}.{}.yaml".format(name, deployment_kind))
390-
objs = decode_yaml_stream(yaml)
391-
k8s_yaml(yaml)
392-
k8s_resource(
393-
workload = find_object_name(objs, "Deployment"),
394-
new_name = label.lower() + "_addon",
395-
labels = [label, "ALL.addons"],
396-
port_forwards = port_forwards,
397-
links = links,
398-
objects = find_all_objects_names(additional_objs),
399-
resource_deps = addon.get("resource_deps", {}),
334+
resource_deps = ["provider_crd"] + p.get("resource_deps", []),
400335
)
401336

402-
def enable_addons():
403-
for name in get_addons():
404-
enable_addon(name, settings.get("debug").get(name, {}))
405-
406-
def get_addons():
407-
user_enable_addons = settings.get("enable_addons", [])
408-
return {k: "" for k in user_enable_addons}.keys()
409-
410337
def find_object_name(objs, kind):
411338
for o in objs:
412339
if o["kind"] == kind:
@@ -634,8 +561,6 @@ include_user_tilt_files()
634561

635562
load_provider_tiltfiles()
636563

637-
load_addon_tiltfiles()
638-
639564
prepare_all()
640565

641566
deploy_provider_crds()
@@ -644,6 +569,4 @@ deploy_observability()
644569

645570
enable_providers()
646571

647-
enable_addons()
648-
649572
cluster_templates()

cmd/clusterctl/api/v1alpha3/labels.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ func ManifestLabel(name string, providerType ProviderType) string {
5050
return fmt.Sprintf("control-plane-%s", name)
5151
case InfrastructureProviderType:
5252
return fmt.Sprintf("infrastructure-%s", name)
53+
case IPAMProviderType:
54+
return fmt.Sprintf("ipam-%s", name)
55+
case RuntimeExtensionProviderType:
56+
return fmt.Sprintf("runtime-extension-%s", name)
5357
default:
5458
return name
5559
}

cmd/clusterctl/api/v1alpha3/provider_type.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ func (p *Provider) GetProviderType() ProviderType {
9292
CoreProviderType,
9393
BootstrapProviderType,
9494
InfrastructureProviderType,
95-
ControlPlaneProviderType:
95+
ControlPlaneProviderType,
96+
IPAMProviderType,
97+
RuntimeExtensionProviderType:
9698
return t
9799
default:
98100
return ProviderTypeUnknown
@@ -118,6 +120,14 @@ const (
118120
// control-plane capabilities.
119121
ControlPlaneProviderType = ProviderType("ControlPlaneProvider")
120122

123+
// IPAMProviderType is the type associated with codebases that provide
124+
// IPAM capabilities.
125+
IPAMProviderType = ProviderType("IPAMProvider")
126+
127+
// RuntimeExtensionProviderType is the type associated with codebases that provide
128+
// runtime extensions.
129+
RuntimeExtensionProviderType = ProviderType("RuntimeExtensionProvider")
130+
121131
// ProviderTypeUnknown is used when the type is unknown.
122132
ProviderTypeUnknown = ProviderType("")
123133
)
@@ -133,8 +143,12 @@ func (p ProviderType) Order() int {
133143
return 2
134144
case InfrastructureProviderType:
135145
return 3
136-
default:
146+
case IPAMProviderType:
137147
return 4
148+
case RuntimeExtensionProviderType:
149+
return 5
150+
default:
151+
return 99
138152
}
139153
}
140154

cmd/clusterctl/client/config/providers_client.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -361,14 +361,18 @@ func validateProvider(r Provider) error {
361361
case clusterctlv1.CoreProviderType,
362362
clusterctlv1.BootstrapProviderType,
363363
clusterctlv1.InfrastructureProviderType,
364-
clusterctlv1.ControlPlaneProviderType:
364+
clusterctlv1.ControlPlaneProviderType,
365+
clusterctlv1.IPAMProviderType,
366+
clusterctlv1.RuntimeExtensionProviderType:
365367
break
366368
default:
367-
return errors.Errorf("invalid provider type. Allowed values are [%s, %s, %s, %s]",
369+
return errors.Errorf("invalid provider type. Allowed values are [%s, %s, %s, %s, %s, %s]",
368370
clusterctlv1.CoreProviderType,
369371
clusterctlv1.BootstrapProviderType,
370372
clusterctlv1.InfrastructureProviderType,
371-
clusterctlv1.ControlPlaneProviderType)
373+
clusterctlv1.ControlPlaneProviderType,
374+
clusterctlv1.IPAMProviderType,
375+
clusterctlv1.RuntimeExtensionProviderType)
372376
}
373377
return nil
374378
}

cmd/clusterctl/client/delete.go

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,21 +30,24 @@ type DeleteOptions struct {
3030
// default rules for kubeconfig discovery will be used.
3131
Kubeconfig Kubeconfig
3232

33-
// CoreProvider version (e.g. cluster-api:v1.1.5) to add to the management cluster. If unspecified, the
34-
// cluster-api core provider's latest release is used.
33+
// CoreProvider version (e.g. cluster-api:v1.1.5) to delete from the management cluster.
3534
CoreProvider string
3635

37-
// BootstrapProviders and versions (e.g. kubeadm:v1.1.5) to add to the management cluster.
38-
// If unspecified, the kubeadm bootstrap provider's latest release is used.
36+
// BootstrapProviders and versions (e.g. kubeadm:v1.1.5) to delete from the management cluster.
3937
BootstrapProviders []string
4038

41-
// InfrastructureProviders and versions (e.g. aws:v0.5.0) to add to the management cluster.
39+
// InfrastructureProviders and versions (e.g. aws:v0.5.0) to delete from the management cluster.
4240
InfrastructureProviders []string
4341

44-
// ControlPlaneProviders and versions (e.g. kubeadm:v1.1.5) to add to the management cluster.
45-
// If unspecified, the kubeadm control plane provider latest release is used.
42+
// ControlPlaneProviders and versions (e.g. kubeadm:v1.1.5) to delete from the management cluster.
4643
ControlPlaneProviders []string
4744

45+
// IPAMProviders and versions (e.g. infoblox:v0.0.1) to delete from the management cluster.
46+
IPAMProviders []string
47+
48+
// RuntimeExtensionProviders and versions (e.g. test:v0.0.1) to delete from the management cluster.
49+
RuntimeExtensionProviders []string
50+
4851
// DeleteAll set for deletion of all the providers.
4952
DeleteAll bool
5053

@@ -109,6 +112,16 @@ func (c *clusterctlClient) Delete(options DeleteOptions) error {
109112
return err
110113
}
111114

115+
providers, err = appendProviders(providers, clusterctlv1.IPAMProviderType, options.IPAMProviders...)
116+
if err != nil {
117+
return err
118+
}
119+
120+
providers, err = appendProviders(providers, clusterctlv1.RuntimeExtensionProviderType, options.RuntimeExtensionProviders...)
121+
if err != nil {
122+
return err
123+
}
124+
112125
for _, provider := range providers {
113126
// Try to detect the namespace where the provider lives
114127
provider.Namespace, err = clusterClient.ProviderInventory().GetProviderNamespace(provider.ProviderName, provider.GetProviderType())

cmd/clusterctl/client/init.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ type InitOptions struct {
5353
// If unspecified, the kubeadm control plane provider latest release is used.
5454
ControlPlaneProviders []string
5555

56+
// IPAMProviders and versions (e.g. infoblox:v0.0.1) to add to the management cluster.
57+
IPAMProviders []string
58+
59+
// RuntimeExtensionProviders and versions (e.g. test:v0.0.1) to add to the management cluster.
60+
RuntimeExtensionProviders []string
61+
5662
// TargetNamespace defines the namespace where the providers should be deployed. If unspecified, each provider
5763
// will be installed in a provider's default namespace.
5864
TargetNamespace string
@@ -227,6 +233,14 @@ func (c *clusterctlClient) setupInstaller(cluster cluster.Client, options InitOp
227233
return nil, err
228234
}
229235

236+
if err := c.addToInstaller(addOptions, clusterctlv1.IPAMProviderType, options.IPAMProviders...); err != nil {
237+
return nil, err
238+
}
239+
240+
if err := c.addToInstaller(addOptions, clusterctlv1.RuntimeExtensionProviderType, options.RuntimeExtensionProviders...); err != nil {
241+
return nil, err
242+
}
243+
230244
return installer, nil
231245
}
232246

cmd/clusterctl/client/upgrade.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,12 @@ type ApplyUpgradeOptions struct {
109109
// InfrastructureProviders instance and versions (e.g. capa-system/aws:v0.5.0) to upgrade to. This field can be used as alternative to Contract.
110110
InfrastructureProviders []string
111111

112+
// IPAMProviders instance and versions (e.g. ipam-system/infoblox:v0.0.1) to upgrade to. This field can be used as alternative to Contract.
113+
IPAMProviders []string
114+
115+
// RuntimeExtensionProviders instance and versions (e.g. runtime-extension-system/test:v0.0.1) to upgrade to. This field can be used as alternative to Contract.
116+
RuntimeExtensionProviders []string
117+
112118
// WaitProviders instructs the upgrade apply command to wait till the providers are successfully upgraded.
113119
WaitProviders bool
114120

@@ -155,7 +161,9 @@ func (c *clusterctlClient) ApplyUpgrade(options ApplyUpgradeOptions) error {
155161
isCustomUpgrade := options.CoreProvider != "" ||
156162
len(options.BootstrapProviders) > 0 ||
157163
len(options.ControlPlaneProviders) > 0 ||
158-
len(options.InfrastructureProviders) > 0
164+
len(options.InfrastructureProviders) > 0 ||
165+
len(options.IPAMProviders) > 0 ||
166+
len(options.RuntimeExtensionProviders) > 0
159167

160168
opts := cluster.UpgradeOptions{
161169
WaitProviders: options.WaitProviders,
@@ -185,6 +193,14 @@ func (c *clusterctlClient) ApplyUpgrade(options ApplyUpgradeOptions) error {
185193
if err != nil {
186194
return err
187195
}
196+
upgradeItems, err = addUpgradeItems(upgradeItems, clusterctlv1.IPAMProviderType, options.IPAMProviders...)
197+
if err != nil {
198+
return err
199+
}
200+
upgradeItems, err = addUpgradeItems(upgradeItems, clusterctlv1.RuntimeExtensionProviderType, options.RuntimeExtensionProviders...)
201+
if err != nil {
202+
return err
203+
}
188204

189205
// Execute the upgrade using the custom upgrade items
190206
return clusterClient.ProviderUpgrader().ApplyCustomPlan(opts, upgradeItems...)

0 commit comments

Comments
 (0)