Skip to content

Commit 2b36dc4

Browse files
authored
Allow defaulting annotations for LB services (#2)
Used to inject `service.beta.kubernetes.io/exoscale-loadbalancer-service-instancepool-id`. The annotation is required for the LB service to work. The CCM deployment is moved to a subdir to allow separating the files in the setup process.
1 parent d6275b5 commit 2b36dc4

21 files changed

+264
-2
lines changed

class/defaults.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,5 @@ parameters:
1616

1717
nodeSelector:
1818
node-role.kubernetes.io/control-plane: ""
19+
20+
serviceLoadBalancerDefaultAnnotations: {}

class/exoscale-cloud-controller-manager.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,8 @@ parameters:
1616
- input_paths:
1717
- ${_base_directory}/component/main.jsonnet
1818
input_type: jsonnet
19-
output_path: exoscale-cloud-controller-manager/
19+
output_path: exoscale-cloud-controller-manager/manager
20+
- input_paths:
21+
- ${_base_directory}/component/service-loadbalancer-default-annotations.jsonnet
22+
input_type: jsonnet
23+
output_path: exoscale-cloud-controller-manager/support
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
local esp = import 'espejote.libsonnet';
2+
local defaultAnnotations = import 'service-loadbalancer-default-annotations/annotations.json';
3+
4+
local lbServices = std.filter(
5+
function(s) std.get(s.spec, 'type') == 'LoadBalancer',
6+
esp.context().services
7+
);
8+
9+
local defaultedAnnotationsForService = function(s) {
10+
[if !std.objectHas(std.get(s.metadata, 'annotations', {}), k) then k]: defaultAnnotations[k]
11+
for k in std.objectFields(defaultAnnotations)
12+
};
13+
14+
local annotationPatchForService = function(s) {
15+
apiVersion: s.apiVersion,
16+
kind: s.kind,
17+
metadata: {
18+
name: s.metadata.name,
19+
namespace: s.metadata.namespace,
20+
annotations: defaultedAnnotationsForService(s),
21+
},
22+
};
23+
24+
std.filter(
25+
function(p) p.metadata.annotations != {},
26+
std.map(
27+
annotationPatchForService,
28+
lbServices,
29+
),
30+
)
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
local esp = import 'lib/espejote.libsonnet';
2+
local kap = import 'lib/kapitan.libjsonnet';
3+
local kube = import 'lib/kube.libjsonnet';
4+
5+
local inv = kap.inventory();
6+
local params = inv.parameters.exoscale_cloud_controller_manager;
7+
8+
local namespace = params.namespace;
9+
10+
local sa = kube.ServiceAccount('service-loadbalancer-default-annotations-manager') {
11+
metadata+: {
12+
namespace: namespace,
13+
},
14+
};
15+
16+
local cr = kube.ClusterRole('espejote:service-loadbalancer-default-annotations') {
17+
rules: [
18+
{
19+
apiGroups: [ '' ],
20+
resources: [ 'services' ],
21+
verbs: [ 'get', 'list', 'watch', 'update', 'patch' ],
22+
},
23+
],
24+
};
25+
26+
local crb = kube.ClusterRoleBinding('espejote:service-loadbalancer-default-annotations') {
27+
roleRef_: cr,
28+
subjects_: [ sa ],
29+
};
30+
31+
local jsonnetlib = esp.jsonnetLibrary('service-loadbalancer-default-annotations', namespace) {
32+
spec: {
33+
data: {
34+
'annotations.json': std.manifestJson(params.serviceLoadBalancerDefaultAnnotations),
35+
},
36+
},
37+
};
38+
39+
local managedresource =
40+
assert std.member(inv.applications, 'espejote') : 'The serviceLoadBalancerDefaultAnnotations patch depends on espejote';
41+
esp.managedResource('service-loadbalancer-default-annotations', namespace) {
42+
metadata+: {
43+
annotations: {
44+
'syn.tools/description': |||
45+
This ManagedResource adds default annotations to all services with `spec.type: LoadBalancer`.
46+
Annotations are taken from a JsonnetLibrary with the same name.
47+
The JsonnetLibrary contains a file `annotations.json` with the annotations to be added.
48+
If an annotation is already set on the service, it will not be overridden.
49+
|||,
50+
},
51+
},
52+
spec: {
53+
serviceAccountRef: { name: sa.metadata.name },
54+
context: [
55+
{
56+
name: 'services',
57+
resource: {
58+
apiVersion: 'v1',
59+
kind: 'Service',
60+
namespace: '',
61+
},
62+
},
63+
],
64+
triggers: [
65+
{
66+
name: 'service',
67+
watchContextResource: {
68+
name: 'services',
69+
},
70+
},
71+
],
72+
template: importstr 'espejote-templates/service-loadbalancer-default-annotations.jsonnet',
73+
},
74+
};
75+
76+
if std.length(params.serviceLoadBalancerDefaultAnnotations) > 0 then
77+
{
78+
'50_service_loadbalancer_default_annotations_rbac': [ namespace, sa, cr, crb ],
79+
'50_service_loadbalancer_default_annotations_managedresource': [ jsonnetlib, managedresource ],
80+
}
81+
else
82+
{}

docs/modules/ROOT/pages/references/parameters.adoc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,20 @@ default:: `{node-role.kubernetes.io/control-plane: ""}`
4444

4545
The node selector for the cloud-controller-manager deployment.
4646
Change this if you don't want to run the cloud-controller-manager on your cluster's control plane nodes.
47+
48+
== `serviceLoadBalancerDefaultAnnotations`
49+
50+
[horizontal]
51+
type:: dictionary
52+
default:: `{}`
53+
example::
54+
+
55+
[source,yaml]
56+
----
57+
serviceLoadBalancerDefaultAnnotations:
58+
service.beta.kubernetes.io/exoscale-loadbalancer-service-instancepool-id: 7026DCCB-39B4-451B-AB38-EB527CC836A4
59+
----
60+
61+
Creates an espejote `ManagedResource` adding default annotations to Services with `spec.type: LoadBalancer`.
62+
63+
Can be used to inject the `service.beta.kubernetes.io/exoscale-loadbalancer-service-instancepool-id` annotation which is required to create a LoadBalancer on Exoscale.

tests/defaults.yml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
1-
# Overwrite parameters here
1+
applications:
2+
- espejote
23

34
parameters:
45
facts:
56
cloud: exoscale
67
region: ch-gva-2
8+
9+
kapitan:
10+
dependencies:
11+
- type: https
12+
source: https://raw.githubusercontent.com/projectsyn/component-espejote/v0.2.0/lib/espejote.libsonnet
13+
output_path: vendor/lib/espejote.libsonnet
14+
15+
exoscale_cloud_controller_manager:
16+
serviceLoadBalancerDefaultAnnotations:
17+
service.beta.kubernetes.io/exoscale-loadbalancer-service-instancepool-id: 7026dccb-39b4-451b-ab38-eb527cc836a4

0 commit comments

Comments
 (0)