Skip to content

Commit

Permalink
This commit makes it possible to:
Browse files Browse the repository at this point in the history
- Deploy IPAM with clusterctl
- Reconsile CAPI's ipaddressclaims with this managers ippools

Signed-off-by: peppi-lotta <[email protected]>
  • Loading branch information
peppi-lotta committed Sep 26, 2024
1 parent 910a3b2 commit 2f06f8b
Show file tree
Hide file tree
Showing 16 changed files with 2,396 additions and 420 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ ARG BUILD_IMAGE=docker.io/golang:1.22.6@sha256:d5e49f92b9566b0ddfc59a0d9d85cd8a8
ARG BASE_IMAGE=gcr.io/distroless/static:nonroot@sha256:9ecc53c269509f63c69a266168e4a687c7eb8c0cfd753bd8bfcaa4f58a90876f

# Build the manager binary on golang image
FROM $BUILD_IMAGE as builder
FROM $BUILD_IMAGE AS builder
WORKDIR /workspace

# Run this with docker build --build_arg $(go env GOPROXY) to override the goproxy
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Deploys IPAM CRDs and deploys IPAM controllers
Runs IPAM controller locally

```sh
kubectl scale -n capm3-system \
kubectl scale -n ipam-system \
deployment.v1.apps/metal3-ipam-controller-manager --replicas 0
make run
```
Expand Down
7 changes: 3 additions & 4 deletions config/default/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

# Adds namespace to all resources. Keep it in capm3-system, as it is a
# dependency for CAPM3
namespace: capm3-system
# Adds namespace to all resources.
namespace: ipam-system

namePrefix: ipam-

labels:
- includeSelectors: true
pairs:
cluster.x-k8s.io/provider: infrastructure-metal3
cluster.x-k8s.io/provider: ipam-metal3

resources:
- ../rbac
Expand Down
7 changes: 7 additions & 0 deletions config/manager/manager.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
apiVersion: v1
kind: Namespace
metadata:
labels:
control-plane: controller-manager
name: system
---
apiVersion: apps/v1
kind: Deployment
metadata:
Expand Down
40 changes: 40 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,46 @@ rules:
- clusters/status
verbs:
- get
- apiGroups:
- ipam.cluster.x-k8s.io
resources:
- ipaddressclaims
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- ipam.cluster.x-k8s.io
resources:
- ipaddressclaims/status
verbs:
- get
- patch
- update
- apiGroups:
- ipam.cluster.x-k8s.io
resources:
- ipaddresses
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- ipam.cluster.x-k8s.io
resources:
- ipaddresses/status
verbs:
- get
- patch
- update
- apiGroups:
- ipam.metal3.io
resources:
Expand Down
39 changes: 37 additions & 2 deletions controllers/ippool_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
capipamv1 "sigs.k8s.io/cluster-api/exp/ipam/api/v1beta1"
"sigs.k8s.io/cluster-api/util/annotations"
"sigs.k8s.io/cluster-api/util/patch"
"sigs.k8s.io/cluster-api/util/predicates"
Expand Down Expand Up @@ -55,6 +56,10 @@ type IPPoolReconciler struct {
// +kubebuilder:rbac:groups=ipam.metal3.io,resources=ipclaims/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=ipam.metal3.io,resources=ipaddresses,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=ipam.metal3.io,resources=ipaddresses/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=ipam.cluster.x-k8s.io,resources=ipaddressclaims,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=ipam.cluster.x-k8s.io,resources=ipaddressclaims/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=ipam.cluster.x-k8s.io,resources=ipaddresses,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=ipam.cluster.x-k8s.io,resources=ipaddresses/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=clusters,verbs=get;list;watch
// +kubebuilder:rbac:groups=cluster.x-k8s.io,resources=clusters/status,verbs=get
// +kubebuilder:rbac:groups="",resources=events,verbs=get;list;watch;create;update;patch
Expand Down Expand Up @@ -96,7 +101,7 @@ func (r *IPPoolReconciler) Reconcile(ctx context.Context, req ctrl.Request) (_ c
ipamv1IPPool.ObjectMeta.Labels = make(map[string]string)
}
ipamv1IPPool.ObjectMeta.Labels[clusterv1.ClusterNameLabel] = *ipamv1IPPool.Spec.ClusterName
ipamv1IPPool.ObjectMeta.Labels[clusterv1.ProviderNameLabel] = "infrastructure-metal3"
ipamv1IPPool.ObjectMeta.Labels[clusterv1.ProviderNameLabel] = "ipam-metal3"

// Fetch the Cluster. Ignore an error if the deletion timestamp is set
err = r.Client.Get(ctx, key, cluster)
Expand Down Expand Up @@ -170,7 +175,7 @@ func (r *IPPoolReconciler) reconcileDelete(ctx context.Context,
}

// SetupWithManager will add watches for this controller.
func (r *IPPoolReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager, options controller.Options) error {
func (r *IPPoolReconciler) SetupWithManagerForIPClaim(ctx context.Context, mgr ctrl.Manager, options controller.Options) error {
return ctrl.NewControllerManagedBy(mgr).
For(&ipamv1.IPPool{}).
WithOptions(options).
Expand All @@ -182,6 +187,19 @@ func (r *IPPoolReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manage
Complete(r)
}

// SetupWithManager will add watches for this controller.
func (r *IPPoolReconciler) SetupWithManagerForIPAddressClaim(ctx context.Context, mgr ctrl.Manager, options controller.Options) error {
return ctrl.NewControllerManagedBy(mgr).
For(&ipamv1.IPPool{}).
WithOptions(options).
Watches(
&capipamv1.IPAddressClaim{},
handler.EnqueueRequestsFromMapFunc(r.IPAddressClaimToIPPool),
).
WithEventFilter(predicates.ResourceNotPausedAndHasFilterLabel(ctrl.LoggerFrom(ctx), r.WatchFilterValue)).
Complete(r)
}

// IPClaimToIPPool will return a reconcile request for a
// Metal3DataTemplate if the event is for a
// IPClaim and that IPClaim references a Metal3DataTemplate.
Expand All @@ -205,6 +223,23 @@ func (r *IPPoolReconciler) IPClaimToIPPool(_ context.Context, obj client.Object)
return []ctrl.Request{}
}

func (r *IPPoolReconciler) IPAddressClaimToIPPool(_ context.Context, obj client.Object) []ctrl.Request {
if ipac, ok := obj.(*capipamv1.IPAddressClaim); ok {
if ipac.Spec.PoolRef.Name != "" {
namespace := ipac.Namespace
return []ctrl.Request{
{
NamespacedName: types.NamespacedName{
Name: ipac.Spec.PoolRef.Name,
Namespace: namespace,
},
},
}
}
}
return []ctrl.Request{}
}

func checkRequeueError(err error, errMessage string) (ctrl.Result, error) {
if err == nil {
return ctrl.Result{}, nil
Expand Down
60 changes: 60 additions & 0 deletions controllers/ippool_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/utils/ptr"
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
capipamv1 "sigs.k8s.io/cluster-api/exp/ipam/api/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
Expand Down Expand Up @@ -407,4 +408,63 @@ var _ = Describe("IPPool controller", func() {
},
),
)

type TestCaseK8SIPACToM3IPP struct {
IPAddressClaim *capipamv1.IPAddressClaim
ExpectRequest bool
}

DescribeTable("IPAddressClaim To IPPool tests",
func(tc TestCaseK8SIPACToM3IPP) {
r := IPPoolReconciler{}
obj := client.Object(tc.IPAddressClaim)
reqs := r.IPAddressClaimToIPPool(context.Background(), obj)

if tc.ExpectRequest {
Expect(len(reqs)).To(Equal(1), "Expected 1 request, found %d", len(reqs))

req := reqs[0]
Expect(req.NamespacedName.Name).To(Equal(tc.IPAddressClaim.Spec.PoolRef.Name),
"Expected name %s, found %s", tc.IPAddressClaim.Spec.PoolRef.Name, req.NamespacedName.Name)
} else {
Expect(len(reqs)).To(Equal(0), "Expected 0 request, found %d", len(reqs))

}
},
Entry("No IPPool in Spec",
TestCaseK8SIPACToM3IPP{
IPAddressClaim: &capipamv1.IPAddressClaim{
ObjectMeta: testObjectMeta,
Spec: capipamv1.IPAddressClaimSpec{},
},
ExpectRequest: false,
},
),
Entry("IPPool in Spec, with namespace",
TestCaseK8SIPACToM3IPP{
IPAddressClaim: &capipamv1.IPAddressClaim{
ObjectMeta: testObjectMeta,
Spec: capipamv1.IPAddressClaimSpec{
PoolRef: corev1.TypedLocalObjectReference{
Name: "abc",
},
},
},
ExpectRequest: true,
},
),
Entry("IPPool in Spec, no namespace",
TestCaseK8SIPACToM3IPP{
IPAddressClaim: &capipamv1.IPAddressClaim{
ObjectMeta: testObjectMeta,
Spec: capipamv1.IPAddressClaimSpec{
PoolRef: corev1.TypedLocalObjectReference{
Name: "abc",
},
},
},
ExpectRequest: true,
},
),
)
})
9 changes: 9 additions & 0 deletions controllers/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
ipamv1 "github.com/metal3-io/ip-address-manager/api/v1alpha1"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
capipamv1 "sigs.k8s.io/cluster-api/exp/ipam/api/v1beta1"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"
Expand All @@ -57,6 +58,7 @@ func init() {
_ = apiextensionsv1.AddToScheme(scheme.Scheme)
_ = clusterv1.AddToScheme(scheme.Scheme)
_ = ipamv1.AddToScheme(scheme.Scheme)
_ = capipamv1.AddToScheme(scheme.Scheme)
}

func setupScheme() *runtime.Scheme {
Expand All @@ -70,6 +72,10 @@ func setupScheme() *runtime.Scheme {
panic(err)
}

if err := capipamv1.AddToScheme(s); err != nil {
panic(err)
}

return s
}
func TestAPIs(t *testing.T) {
Expand All @@ -94,6 +100,9 @@ var _ = BeforeSuite(func() {
err = ipamv1.AddToScheme(scheme.Scheme)
Expect(err).NotTo(HaveOccurred())

err = capipamv1.AddToScheme(scheme.Scheme)
Expect(err).NotTo(HaveOccurred())

err = apiextensionsv1.AddToScheme(scheme.Scheme)
Expect(err).NotTo(HaveOccurred())

Expand Down
29 changes: 27 additions & 2 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ as follows :
An IPClaim is an object representing a request for an IP address allocation.
Example pool:
Example IPClaim:
```yaml
apiVersion: ipam.metal3.io/v1alpha1
Expand All @@ -78,7 +78,7 @@ The *spec* field contains the following :
An IPAddress is an object representing an IP address allocation.
Example pool:
Example IPAddress:
```yaml
apiVersion: ipam.metal3.io/v1alpha1
Expand Down Expand Up @@ -110,3 +110,28 @@ The *spec* field contains the following :
You can find CR examples in the
[Metal3-io dev env project](https://github.com/metal3-io/metal3-dev-env)
## CAPI
[Cluster-api](https://github.com/kubernetes-sigs/cluster-api) has
created it own ip-address-manager:
[ipam-provider-in-cluster](https://github.com/kubernetes-sigs/cluster-api-ipam-provider-in-cluster)
and support for other IPAMs. This IPAM can be deployed and used
as an IPAM provider for CAPI.
Deploying an ippool like the example pool will be able to reconsile (metal3)ipclaims into (metal3)ipaddresses and (capi)ipaddressclaims into (capi)ipaddresses.
### IPAddressClaim
### IpAddress
### Set up via clusterctl
Since it's not added to the built-in list of providers yet, you'll need to add the following to your ```$XDG_CONFIG_HOME/cluster-api/clusterctl.yaml``` if you want to install it using ```clusterctl init --ipam metal3```:

```
providers:
- name: metal3
url: file:///home/ipam/ipam-metal3/v1.0.0/ipam-components.yaml
type: IPAMProvider
```
2 changes: 1 addition & 1 deletion examples/generate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ OUTPUT_DIR=${OUTPUT_DIR:-${SOURCE_DIR}/_out}

# Cluster.
export CLUSTER_NAME="${CLUSTER_NAME:-test1}"
export NAMESPACE="${NAMESPACE:-capm3-system}"
export NAMESPACE="${NAMESPACE:-ipam-system}"

# Outputs.
COMPONENTS_CERT_MANAGER_GENERATED_FILE=${OUTPUT_DIR}/cert-manager.yaml
Expand Down
10 changes: 10 additions & 0 deletions examples/ippool/ippool.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,13 @@ spec:
pool:
name: pool1
namespace: ${NAMESPACE}
---
apiVersion: ipam.cluster.x-k8s.io/v1beta1
kind: IPAddressClaim
metadata:
name: ${CLUSTER_NAME}-controlplane-template-1-provisioning-pool
spec:
poolRef:
apiGroup: ipam.metal3.io
kind: IPPool
name: pool1
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ apiVersion: apps/v1
kind: Deployment
metadata:
name: ipam-controller-manager
namespace: capm3-system
namespace: ipam-system
spec:
template:
spec:
Expand Down
Loading

0 comments on commit 2f06f8b

Please sign in to comment.