Skip to content

Commit dc188ec

Browse files
committed
Implement cluster reconciler.
Closes #2.
1 parent 7e21582 commit dc188ec

File tree

12 files changed

+924
-123
lines changed

12 files changed

+924
-123
lines changed

Makefile

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ release-manifests: $(KUSTOMIZE) ## Builds the manifests to publish with a releas
5353
##@ Development
5454

5555
.PHONY: push-to-capi-lab
56-
push-to-capi-lab: build
56+
push-to-capi-lab: generate manifests build install deploy
5757
docker build -t $(IMG) -f Dockerfile.dev .
5858
kind --name metal-control-plane load docker-image capms-controller:latest
5959
kubectl --kubeconfig=$(KUBECONFIG) patch deployments.apps -n capms-system capms-controller-manager --patch='{"spec":{"template":{"spec":{"containers":[{"name": "manager","imagePullPolicy":"IfNotPresent","image":"$(IMG)"}]}}}}'
@@ -154,6 +154,10 @@ ifndef ignore-not-found
154154
ignore-not-found = false
155155
endif
156156

157+
# this is configured to work with the capi-lab
158+
export METAL_API_URL := "http://metal.172.17.0.1.nip.io:8080"
159+
export METAL_API_HMAC := "metal-admin"
160+
157161
.PHONY: install
158162
install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config.
159163
$(KUSTOMIZE) build config/crd | $(KUBECTL) apply -f -
@@ -165,11 +169,11 @@ uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified
165169
.PHONY: deploy
166170
deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
167171
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
168-
$(KUSTOMIZE) build config/default | $(KUBECTL) apply -f -
172+
$(KUSTOMIZE) build config/default | envsubst | $(KUBECTL) apply -f -
169173

170174
.PHONY: undeploy
171175
undeploy: kustomize ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
172-
$(KUSTOMIZE) build config/default | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f -
176+
$(KUSTOMIZE) build config/default | envsubst | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f -
173177

174178
##@ Dependencies
175179

api/v1alpha1/metalstackcluster_types.go

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,18 @@ package v1alpha1
1919
import (
2020
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2121

22+
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
2223
capierrors "sigs.k8s.io/cluster-api/errors"
24+
25+
fcmv2 "github.com/metal-stack/firewall-controller-manager/api/v2"
26+
)
27+
28+
const (
29+
// ClusterFinalizer allows to clean up resources associated with before removing it from the apiserver.
30+
ClusterFinalizer = "metal-stack.infrastructure.cluster.x-k8s.io/cluster"
31+
32+
ClusterNodeNetworkEnsured clusterv1.ConditionType = "ClusterNodeNetworkEnsured"
33+
ClusterFirewallDeploymentReady clusterv1.ConditionType = "ClusterFirewallDeploymentReady"
2334
)
2435

2536
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
@@ -32,10 +43,13 @@ type MetalStackClusterSpec struct {
3243
ControlPlaneEndpoint APIEndpoint `json:"controlPlaneEndpoint,omitempty"`
3344

3445
// ProjectID is the project id of the project in metal-stack in which the associated metal-stack resources are created
35-
ProjectID string `json:"projectID,omitempty"`
46+
ProjectID string `json:"projectID"`
3647

3748
// Partition is the data center partition in which the resources are created
38-
Partition string `json:"partition,omitempty"`
49+
Partition string `json:"partition"`
50+
51+
// Firewall describes the firewall for this cluster
52+
Firewall Firewall `json:"firewall"`
3953
}
4054

4155
// APIEndpoint represents a reachable Kubernetes API endpoint.
@@ -47,6 +61,31 @@ type APIEndpoint struct {
4761
Port int `json:"port"`
4862
}
4963

64+
// Firewall defines parameters for the firewall creation along with configuration for the firewall-controller.
65+
type Firewall struct {
66+
// Size is the machine size of the firewall.
67+
// An update on this field requires the recreation of the physical firewall and can therefore lead to traffic interruption for the cluster.
68+
Size string `json:"size"`
69+
// Image is the os image of the firewall.
70+
// An update on this field requires the recreation of the physical firewall and can therefore lead to traffic interruption for the cluster.
71+
Image string `json:"image"`
72+
// AdditionalNetworks are the networks to which this firewall is connected.
73+
// An update on this field requires the recreation of the physical firewall and can therefore lead to traffic interruption for the cluster.
74+
// +optional
75+
AdditionalNetworks []string `json:"networks,omitempty"`
76+
77+
// RateLimits allows configuration of rate limit rules for interfaces.
78+
// +optional
79+
RateLimits []fcmv2.RateLimit `json:"rateLimits,omitempty"`
80+
// EgressRules contains egress rules configured for this firewall.
81+
// +optional
82+
EgressRules []fcmv2.EgressRuleSNAT `json:"egressRules,omitempty"`
83+
84+
// LogAcceptedConnections if set to true, also log accepted connections in the droptailer log.
85+
// +optional
86+
LogAcceptedConnections *bool `json:"logAcceptedConnections,omitempty"`
87+
}
88+
5089
// MetalStackClusterStatus defines the observed state of MetalStackCluster.
5190
type MetalStackClusterStatus struct {
5291
// FailureReason indicates that there is a fatal problem reconciling the
@@ -62,6 +101,10 @@ type MetalStackClusterStatus struct {
62101

63102
// Ready denotes that the cluster is ready.
64103
Ready bool `json:"ready"`
104+
105+
// Conditions defines current service state of the Metal3Cluster.
106+
// +optional
107+
Conditions clusterv1.Conditions `json:"conditions,omitempty"`
65108
}
66109

67110
// +kubebuilder:object:root=true
@@ -88,3 +131,13 @@ type MetalStackClusterList struct {
88131
func init() {
89132
SchemeBuilder.Register(&MetalStackCluster{}, &MetalStackClusterList{})
90133
}
134+
135+
// GetConditions returns the list of conditions.
136+
func (c *MetalStackCluster) GetConditions() clusterv1.Conditions {
137+
return c.Status.Conditions
138+
}
139+
140+
// SetConditions will set the given conditions.
141+
func (c *MetalStackCluster) SetConditions(conditions clusterv1.Conditions) {
142+
c.Status.Conditions = conditions
143+
}

api/v1alpha1/metalstackmachine_types.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ import (
2020
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2121
)
2222

23+
const (
24+
// MachineFinalizer allows to clean up resources associated with before removing it from the apiserver.
25+
MachineFinalizer = "metal-stack.infrastructure.cluster.x-k8s.io/machine"
26+
)
27+
2328
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
2429
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
2530

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 48 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/main.go

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package main
1818

1919
import (
2020
"crypto/tls"
21+
"errors"
2122
"flag"
2223
"os"
2324

@@ -37,6 +38,9 @@ import (
3738

3839
infrastructurev1alpha1 "github.com/metal-stack/cluster-api-provider-metal-stack/api/v1alpha1"
3940
"github.com/metal-stack/cluster-api-provider-metal-stack/internal/controller"
41+
fcmv2 "github.com/metal-stack/firewall-controller-manager/api/v2"
42+
metalgo "github.com/metal-stack/metal-go"
43+
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
4044
// +kubebuilder:scaffold:imports
4145
)
4246

@@ -47,6 +51,8 @@ var (
4751

4852
func init() {
4953
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
54+
utilruntime.Must(clusterv1.AddToScheme(scheme))
55+
utilruntime.Must(fcmv2.AddToScheme(scheme))
5056

5157
utilruntime.Must(infrastructurev1alpha1.AddToScheme(scheme))
5258
// +kubebuilder:scaffold:scheme
@@ -77,6 +83,12 @@ func main() {
7783

7884
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
7985

86+
metalClient, err := newMetalClient()
87+
if err != nil {
88+
setupLog.Error(err, "unable to initialize metal-api client")
89+
os.Exit(1)
90+
}
91+
8092
// if the enable-http2 flag is false (the default), http/2 should be disabled
8193
// due to its vulnerabilities. More specifically, disabling http/2 will
8294
// prevent from being vulnerable to the HTTP/2 Stream Cancellation and
@@ -144,9 +156,12 @@ func main() {
144156
os.Exit(1)
145157
}
146158

159+
ctx := ctrl.SetupSignalHandler()
160+
147161
if err = (&controller.MetalStackClusterReconciler{
148-
Client: mgr.GetClient(),
149-
Scheme: mgr.GetScheme(),
162+
MetalClient: metalClient,
163+
Client: mgr.GetClient(),
164+
Scheme: mgr.GetScheme(),
150165
}).SetupWithManager(mgr); err != nil {
151166
setupLog.Error(err, "unable to create controller", "controller", "MetalStackCluster")
152167
os.Exit(1)
@@ -170,8 +185,22 @@ func main() {
170185
}
171186

172187
setupLog.Info("starting manager")
173-
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
188+
if err := mgr.Start(ctx); err != nil {
174189
setupLog.Error(err, "problem running manager")
175190
os.Exit(1)
176191
}
177192
}
193+
194+
func newMetalClient() (metalgo.Client, error) {
195+
url := os.Getenv("METAL_API_URL")
196+
if url == "" {
197+
return nil, errors.New("METAL_API_URL environment variable must be set")
198+
}
199+
200+
hmac := os.Getenv("METAL_API_HMAC")
201+
if url == "" {
202+
return nil, errors.New("METAL_API_HMAC environment variable must be set")
203+
}
204+
205+
return metalgo.NewDriver(url, "", hmac)
206+
}

0 commit comments

Comments
 (0)