Skip to content

Commit e2a51ef

Browse files
committed
ci: add kind testing
1 parent ece85ed commit e2a51ef

File tree

8 files changed

+318
-74
lines changed

8 files changed

+318
-74
lines changed

.github/workflows/kind.yaml

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
name: Create Cluster with Registry
2+
3+
on:
4+
push: {}
5+
6+
jobs:
7+
setup-and-deploy:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- name: Checkout repository
11+
uses: actions/checkout@v3
12+
13+
- name: Set up Docker registry
14+
run: |
15+
docker network create kind || true
16+
docker run -d --network kind --name registry -p 5000:5000 registry:2
17+
18+
- name: Write config file
19+
run: |
20+
cat <<EOF > kind-config.yaml
21+
apiVersion: kind.x-k8s.io/v1alpha4
22+
kind: Cluster
23+
containerdConfigPatches:
24+
- |
25+
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:5000"]
26+
endpoint = ["http://registry:5000"]
27+
28+
kubeadmConfigPatches:
29+
- |
30+
kind: ClusterConfiguration
31+
apiServer:
32+
extraArgs:
33+
"service-node-port-range": "30000-30005"
34+
35+
nodes:
36+
- role: control-plane
37+
extraPortMappings:
38+
- containerPort: 80
39+
hostPort: 80
40+
- containerPort: 30000
41+
hostPort: 30000
42+
- containerPort: 30001
43+
hostPort: 30001
44+
- containerPort: 30002
45+
hostPort: 30002
46+
- containerPort: 30003
47+
hostPort: 30003
48+
- containerPort: 30004
49+
hostPort: 30004
50+
- containerPort: 30005
51+
hostPort: 30005
52+
EOF
53+
54+
- name: Set up Kind cluster
55+
uses: helm/kind-action@v1.7.0
56+
with:
57+
version: v0.20.0
58+
config: kind-config.yaml
59+
cluster_name: kind
60+
env:
61+
KIND_EXPERIMENTAL_DOCKER_NETWORK: kind
62+
63+
- name: Build and push CM
64+
run: |
65+
docker build \
66+
-t localhost:5000/ctferio/chall-manager:${{ github.sha }} \
67+
-f Dockerfile.chall-manager \
68+
.
69+
docker push localhost:5000/ctferio/chall-manager:${{ github.sha }}
70+
71+
- name: Build and push CMJ
72+
run: |
73+
docker build \
74+
-t localhost:5000/ctferio/chall-manager-janitor:${{ github.sha }} \
75+
-f Dockerfile.chall-manager-janitor \
76+
.
77+
docker push localhost:5000/ctferio/chall-manager-janitor:${{ github.sha }}
78+
79+
- name: Install Pulumi
80+
uses: pulumi/actions@v4
81+
82+
- name: Configure stack
83+
run: |
84+
pulumi login --local
85+
export PULUMI_CONFIG_PASSPHRASE=""
86+
87+
cd deploy
88+
pulumi stack init dev
89+
pulumi config set private-registry "localhost:5000/"
90+
pulumi config set tag ${{ github.sha }}
91+
pulumi config set pvc_access_mode ReadWriteOnce
92+
pulumi config set expose true
93+
pulumi up -y
94+
95+
URL="http://$(docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' kind-control-plane):$(pulumi stack output exposed_port)"
96+
echo $URL
97+
curl "${URL}/healthcheck"

deploy/Pulumi.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,14 @@ config:
3030
type: boolean
3131
description: If set to true, turns on the REST API Swagger UI. Do not activate in production. (Optional)
3232
default: false
33+
pvc_access_mode:
34+
type: string
35+
description: The access mode to use for the PVC. (Optional)
36+
default: ReadWriteMany
37+
expose:
38+
type: boolean
39+
description: Whether to expose to external networking the Chall-Manager service. DO NOT TURN ON IF YOU DON'T UNDERSTAND THE IMPACT.
40+
default: false
3341
otel.endpoint:
3442
type: string
3543
description: The OpenTelemetry Collector endpoint to set signals to. (Optional)

deploy/main.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,13 @@ func main() {
3030
PrivateRegistry: pulumi.String(cfg.PrivateRegistry),
3131
Replicas: pulumi.Int(cfg.Replicas),
3232
Swagger: cfg.Swagger,
33-
EtcdReplicas: nil,
34-
JanitorCron: nil,
35-
Otel: nil,
33+
PVCAccessModes: pulumi.ToStringArray([]string{
34+
cfg.PVCAccessMode,
35+
}),
36+
Expose: cfg.Expose,
37+
EtcdReplicas: nil,
38+
JanitorCron: nil,
39+
Otel: nil,
3640
}
3741
if cfg.Etcd != nil {
3842
args.EtcdReplicas = pulumi.IntPtr(cfg.Etcd.Replicas)
@@ -53,6 +57,7 @@ func main() {
5357
}
5458

5559
ctx.Export("endpoint", cm.Endpoint)
60+
ctx.Export("exposed_port", cm.ExposedPort)
5661

5762
return nil
5863
})
@@ -67,6 +72,8 @@ type (
6772
Replicas int `json:"replicas"`
6873
Janitor *JanitorConfig `json:"janitor"`
6974
Swagger bool `json:"swagger"`
75+
PVCAccessMode string `json:"pvc_access_mode"`
76+
Expose bool `json:"expose"`
7077
Otel *OtelConfig `json:"otel"`
7178
}
7279

@@ -92,6 +99,8 @@ func loadConfig(ctx *pulumi.Context) *Config {
9299
PrivateRegistry: cfg.Get("private-registry"),
93100
Replicas: cfg.GetInt("replicas"),
94101
Swagger: cfg.GetBool("swagger"),
102+
PVCAccessMode: cfg.Get("pvc_access_mode"),
103+
Expose: cfg.GetBool("expose"),
95104
}
96105

97106
var etcdC EtcdConfig

deploy/services/chall-manager.go

Lines changed: 87 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package services
22

33
import (
4+
"fmt"
5+
"strconv"
46
"strings"
57

68
"github.com/ctfer-io/chall-manager/deploy/common"
79
"github.com/ctfer-io/chall-manager/deploy/services/parts"
10+
corev1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/core/v1"
11+
v1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/meta/v1"
812
netwv1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/networking/v1"
913
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
1014
)
@@ -19,13 +23,17 @@ type (
1923
cm *parts.ChallManager
2024
cmj *parts.ChallManagerJanitor
2125

26+
// Exposure
27+
svc *corev1.Service
28+
2229
// Interface & ports network policies
2330
cmToEtcd *netwv1.NetworkPolicy
2431
cmjToCm *netwv1.NetworkPolicy
2532

2633
// Outputs
2734

28-
Endpoint pulumi.StringOutput
35+
Endpoint pulumi.StringOutput
36+
ExposedPort pulumi.IntPtrOutput
2937
}
3038

3139
// ChallManagerArgs contains all the parametrization of a Chall-Manager
@@ -47,7 +55,11 @@ type (
4755
JanitorCron pulumi.StringPtrInput
4856
janitorCron pulumi.StringOutput
4957

50-
Swagger bool
58+
// PVCAccessModes defines the access modes supported by the PVC.
59+
PVCAccessModes pulumi.StringArrayInput
60+
pvcAccessModes pulumi.StringArrayOutput
61+
62+
Swagger, Expose bool
5163

5264
Otel *common.OtelArgs
5365
}
@@ -62,19 +74,41 @@ const (
6274
//
6375
// It is not made to be exposed to outer world (outside of the cluster).
6476
func NewChallManager(ctx *pulumi.Context, name string, args *ChallManagerArgs, opts ...pulumi.ResourceOption) (*ChallManager, error) {
77+
cm := &ChallManager{}
78+
args, err := cm.validate(args)
79+
if err != nil {
80+
return nil, err
81+
}
82+
if err := ctx.RegisterComponentResource("ctfer-io:chall-manager", name, cm, opts...); err != nil {
83+
return nil, err
84+
}
85+
opts = append(opts, pulumi.Parent(cm))
86+
if err := cm.provision(ctx, args, opts...); err != nil {
87+
return nil, err
88+
}
89+
if err := cm.outputs(ctx); err != nil {
90+
return nil, err
91+
}
92+
return cm, nil
93+
}
94+
95+
func (cm *ChallManager) validate(args *ChallManagerArgs) (*ChallManagerArgs, error) {
6596
if args == nil {
6697
args = &ChallManagerArgs{}
6798
}
99+
68100
if args.Tag == nil || args.Tag == pulumi.String("") {
69101
args.tag = pulumi.String("dev").ToStringOutput()
70102
} else {
71103
args.tag = args.Tag.ToStringPtrOutput().Elem()
72104
}
105+
73106
if args.JanitorCron == nil || args.JanitorCron == pulumi.String("") {
74107
args.janitorCron = pulumi.String(defaultCron).ToStringOutput()
75108
} else {
76109
args.janitorCron = args.JanitorCron.ToStringPtrOutput().Elem()
77110
}
111+
78112
if args.PrivateRegistry == nil {
79113
args.privateRegistry = pulumi.String("").ToStringOutput()
80114
} else {
@@ -92,23 +126,22 @@ func NewChallManager(ctx *pulumi.Context, name string, args *ChallManagerArgs, o
92126
return str
93127
}).(pulumi.StringOutput)
94128
}
129+
95130
if args.Replicas == nil {
96131
args.replicas = pulumi.Int(1).ToIntOutput()
97132
} else {
98133
args.replicas = args.Replicas.ToIntPtrOutput().Elem()
99134
}
100135

101-
cm := &ChallManager{}
102-
if err := ctx.RegisterComponentResource("ctfer-io:chall-manager", name, cm, opts...); err != nil {
103-
return nil, err
104-
}
105-
opts = append(opts, pulumi.Parent(cm))
106-
if err := cm.provision(ctx, args, opts...); err != nil {
107-
return nil, err
136+
if args.PVCAccessModes == nil {
137+
args.pvcAccessModes = pulumi.ToStringArray([]string{
138+
"ReadWriteMany",
139+
}).ToStringArrayOutput()
140+
} else {
141+
args.pvcAccessModes = args.PVCAccessModes.ToStringArrayOutput()
108142
}
109-
cm.outputs()
110143

111-
return cm, nil
144+
return args, nil
112145
}
113146

114147
func (cm *ChallManager) provision(ctx *pulumi.Context, args *ChallManagerArgs, opts ...pulumi.ResourceOption) (err error) {
@@ -149,9 +182,10 @@ func (cm *ChallManager) provision(ctx *pulumi.Context, args *ChallManagerArgs, o
149182
}
150183
return 1 // default replicas to 1
151184
}).(pulumi.IntOutput),
152-
Etcd: nil,
153-
Swagger: args.Swagger,
154-
Otel: nil,
185+
Etcd: nil,
186+
Swagger: args.Swagger,
187+
PVCAccessModes: args.pvcAccessModes,
188+
Otel: nil,
155189
}
156190
if args.EtcdReplicas != nil {
157191
cmArgs.Etcd = &parts.ChallManagerEtcdArgs{
@@ -172,6 +206,34 @@ func (cm *ChallManager) provision(ctx *pulumi.Context, args *ChallManagerArgs, o
172206
return
173207
}
174208

209+
if args.Expose {
210+
cm.svc, err = corev1.NewService(ctx, "cm-exposed", &corev1.ServiceArgs{
211+
Metadata: v1.ObjectMetaArgs{
212+
Labels: cm.cm.PodLabels,
213+
Namespace: args.Namespace,
214+
},
215+
Spec: corev1.ServiceSpecArgs{
216+
Type: pulumi.String("NodePort"),
217+
Selector: cm.cm.PodLabels,
218+
Ports: corev1.ServicePortArray{
219+
corev1.ServicePortArgs{
220+
Port: cm.cm.Endpoint.ApplyT(func(edp string) int {
221+
// On bootstrap there is no valid URL, but port is assigned
222+
pts := strings.Split(edp, ":")
223+
p := pts[len(pts)-1]
224+
port, _ := strconv.Atoi(p)
225+
fmt.Printf("port: %v\n", port)
226+
return port
227+
}).(pulumi.IntOutput),
228+
},
229+
},
230+
},
231+
}, opts...)
232+
if err != nil {
233+
return
234+
}
235+
}
236+
175237
// Deploy janitor
176238
var cmjOtel *common.OtelArgs
177239
if args.Otel != nil {
@@ -294,6 +356,16 @@ func (cm *ChallManager) provision(ctx *pulumi.Context, args *ChallManagerArgs, o
294356
return
295357
}
296358

297-
func (cm *ChallManager) outputs() {
359+
func (cm *ChallManager) outputs(ctx *pulumi.Context) error {
298360
cm.Endpoint = cm.cm.Endpoint
361+
if cm.svc != nil {
362+
cm.ExposedPort = cm.svc.Spec.ApplyT(func(spec corev1.ServiceSpec) *int {
363+
return spec.Ports[0].NodePort
364+
}).(pulumi.IntPtrOutput)
365+
}
366+
367+
return ctx.RegisterResourceOutputs(cm, pulumi.Map{
368+
"endpoint": cm.Endpoint,
369+
"exposed_port": cm.ExposedPort,
370+
})
299371
}

0 commit comments

Comments
 (0)