Skip to content

Commit 35cb19e

Browse files
vaastavJonathanMace
authored andcommitted
Add wiring funcs for Kubernetes
1 parent 0a33a1b commit 35cb19e

File tree

3 files changed

+178
-0
lines changed

3 files changed

+178
-0
lines changed

plugins/kubernetes/ir.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package kubernetes
2+
3+
import "github.com/blueprint-uservices/blueprint/blueprint/pkg/ir"
4+
5+
// An IRNode representing a Kubernetes applicaiton deployment which is a collection of Kubernetes Pod + Service Deployment instances.
6+
type Application struct {
7+
AppName string
8+
Nodes []ir.IRNode
9+
Edges []ir.IRNode
10+
}
11+
12+
// Implements IRNode
13+
func (n *Application) Name() string {
14+
return n.AppName
15+
}
16+
17+
// Implements IRNode
18+
func (n *Application) String() string {
19+
return ir.PrettyPrintNamespace(n.AppName, "KubeApp", n.Edges, n.Nodes)
20+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Package kubepod is a plugin for instantiating multiple container instances in a single Kubernetes pod deployment.
2+
//
3+
// # Wiring Spec Usage
4+
//
5+
// To use the kubepod plugin in your wiring spec, you can declare a Kubernetes Pod Deployment, giving it a name and specifying which container instances to include
6+
//
7+
// kubepod.NewKubePod(spec, "my_pod", "my_container_1", "my_container_2")
8+
//
9+
// You can add containers to existing pods:
10+
//
11+
// kubepod.AddContainerToPod(spec, "my_pod", "my_container_3")
12+
//
13+
// To deploy an application-level service in a Kubernetes Pod, make sure you first deploy the service to a process (with the [goproc] plugin) and to a container image (with the [linuxcontainer] plugin)
14+
//
15+
// # Artifacts Generated
16+
//
17+
// During compilation, the plugin generates a `podName-deployment.yaml` file that instantiates the pod as a Kubernetes deployment and a `podName-service.yaml` file that converts the deployed pod into a Kubernetes service.
18+
//
19+
// # Running Artifacts
20+
//
21+
// You need to have a working kubernetes cluster and `kubectl` installed.
22+
// To deploy the pods to the cluster, use the following commands:
23+
//
24+
// kubectl apply -f podName-deployment.yaml
25+
// kubectl apply -f podName-service.yaml
26+
//
27+
// [linuxcontainer]: https://github.com/Blueprint-uServices/blueprint/tree/main/plugins/linuxcontainer
28+
// [goproc]: https://github.com/Blueprint-uServices/blueprint/tree/main/plugins/goproc
29+
package kubepod
30+
31+
import (
32+
"github.com/blueprint-uservices/blueprint/blueprint/pkg/coreplugins/namespaceutil"
33+
"github.com/blueprint-uservices/blueprint/blueprint/pkg/ir"
34+
"github.com/blueprint-uservices/blueprint/blueprint/pkg/wiring"
35+
)
36+
37+
// [AddContainerToPod] can be used by wiring specs to add more containers to a pod
38+
func AddContainerToPod(spec wiring.WiringSpec, podName string, containerName string) {
39+
namespaceutil.AddNodeTo[PodDeployment](spec, podName, containerName)
40+
}
41+
42+
// [NewKubePod] can be used by wiring specs to create a Kubernetes Pod that instantiates a single Kubernetes Pod consisting of multiple containers.
43+
//
44+
// Further containers can be added to the Pod by calling [AddContainerToPod].
45+
//
46+
// During compilation, generates the deployment.yaml and service.yaml files for the pod.
47+
//
48+
// Returns podName
49+
func NewKubePod(spec wiring.WiringSpec, podName string, containers ...string) string {
50+
51+
// If any children were provided in this call, add them to the pod via a property
52+
for _, containerName := range containers {
53+
AddContainerToPod(spec, podName, containerName)
54+
}
55+
56+
spec.Define(podName, &PodDeployment{}, func(ns wiring.Namespace) (ir.IRNode, error) {
57+
pod := &PodDeployment{PodName: podName}
58+
_, err := namespaceutil.InstantiateNamespace(ns, pod)
59+
return pod, err
60+
})
61+
62+
return podName
63+
}

plugins/kubernetes/wiring.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
// Package kubernetes is a plugin for instantiating multiple container instances in a Kubernetes cluster.
2+
//
3+
// # Wiring Spec Usage
4+
//
5+
// To use the kubernetes plugin in your wiring spec, you can declare a Kuberenetes application, giving it a name and specifying which containers to include. Each container will be deployed in a separate pod in the Kubernetes cluster.
6+
//
7+
// kubernetes.NewApplication(spec, "my_app", "my_container_1", "my_container_2")
8+
//
9+
// You can add more containers to an existing application:
10+
//
11+
// kubernetes.AddContainerToDeployment(spec, "my_app", "my_container_3")
12+
//
13+
// You can also deploy multiple containers in a single pod:
14+
//
15+
// kubernetes.AddPodToApplication(spec, "my_app", "my_container_4", "my_container_5")
16+
//
17+
// # Artifacts Generated
18+
//
19+
// During compilation, the plugin generates deployment.yaml and service.yaml files for each Pod.
20+
//
21+
// # Running Artifacts
22+
//
23+
// You need to have a working kubernetes cluster and `kubectl` installed.
24+
// To deploy the pods to the cluster, use the following commands:
25+
//
26+
// kubectl apply -f podName-deployment.yaml
27+
// kubectl apply -f podName-service.yaml
28+
//
29+
package kubernetes
30+
31+
import (
32+
"github.com/blueprint-uservices/blueprint/blueprint/pkg/coreplugins/namespaceutil"
33+
"github.com/blueprint-uservices/blueprint/blueprint/pkg/ir"
34+
"github.com/blueprint-uservices/blueprint/blueprint/pkg/wiring"
35+
"github.com/blueprint-uservices/blueprint/plugins/kubernetes/kubepod"
36+
)
37+
38+
// [AddContainerToApplication] can be used by wiring specs to add more containers to a Kubernetes application
39+
func AddContainerToApplication(spec wiring.WiringSpec, appName string, containerName string) {
40+
AddPodToApplication(spec, appName, containerName)
41+
}
42+
43+
// [AddPodToApplication] can be used by wiring specs to bundle multiple containers in a single Kubernetes Pod and add that pod to an application
44+
func AddPodToApplication(spec wiring.WiringSpec, appName string, containers ...string) {
45+
podName := kubepod.NewKubePod(spec, containers[0], containers...)
46+
namespaceutil.AddNodeTo[Application](spec, appName, podName)
47+
}
48+
49+
// [NewApplication] can be used by wiring specs to create a Kubernetes Application that instantiates a number of kubernetes pod deployments as services. For each provided container, a new pod deployment is created with that container added to the pod.
50+
//
51+
// Further pod deployments for containers can be generated by calling [AddContainerToApplication].
52+
//
53+
// If one wishes to bundle multiple containers into a single pod, then that can be done by calling [AddPodToApplication]. Note that the containers provided to that must not have already been added to the application before.
54+
//
55+
// During compilation, generates the various configuration files for generating pod deployments and services.
56+
//
57+
// Returns appName
58+
func NewApplication(spec wiring.WiringSpec, appName string, containers ...string) string {
59+
60+
// If any children were provided in this call, add them to the app via a property
61+
for _, containerName := range containers {
62+
AddContainerToApplication(spec, appName, containerName)
63+
}
64+
65+
spec.Define(appName, &Application{}, func(ns wiring.Namespace) (ir.IRNode, error) {
66+
application := &Application{AppName: appName}
67+
_, err := namespaceutil.InstantiateNamespace(ns, &applicationNamespace{application})
68+
return application, err
69+
})
70+
71+
return appName
72+
}
73+
74+
// A [wiring.NamespaceHandler] used to build kubernetes deployments
75+
type applicationNamespace struct {
76+
*Application
77+
}
78+
79+
// Implements [wiring.NamespaceHandler]
80+
func (application *Application) Accepts(nodeType any) bool {
81+
_, isPodDeploymentNode := nodeType.(kubepod.PodDeployment)
82+
return isPodDeploymentNode
83+
}
84+
85+
// Implements [wiring.NamespaceHandler]
86+
func (application *Application) AddEdge(name string, edge ir.IRNode) error {
87+
application.Edges = append(application.Edges, edge)
88+
return nil
89+
}
90+
91+
// Implements [wiring.NamespaceHandler]
92+
func (application *Application) AddNode(name string, node ir.IRNode) error {
93+
application.Nodes = append(application.Nodes, node)
94+
return nil
95+
}

0 commit comments

Comments
 (0)