yesod-mirror/k8s/configs/base.libsonnet

350 lines
9.3 KiB
Jsonnet
Raw Normal View History

local baseKube = import "k8s/configs/k.libsonnet";
local tanka = import "tanka-util/main.libsonnet";
local helm = tanka.helm.new(std.thisFile);
local baseKubeCompat = {
_Object(apiVersion, kind, name):: {
local this = self,
apiVersion: apiVersion,
kind: kind,
metadata: {
name: name,
labels: { name: std.join("-", std.split(this.metadata.name, ":")) },
annotations: {},
},
},
};
local splitThisFilePath = std.split(std.thisFile, "/");
local workspaceRoot = std.join('/', splitThisFilePath[:std.length(splitThisFilePath)-3]);
local workspaceRootLength = std.length(workspaceRoot);
{
helm: helm,
// Returns array of values from given object. Does not include hidden fields.
objectValues(o):: [o[field] for field in std.objectFields(o)],
asWorkspacePath(fullPath):
local isPrefixed = std.startsWith(fullPath,workspaceRoot);
if !isPrefixed then error fullPath + "is not prefixed by workspace root \"" + workspaceRoot + "\"" else
fullPath[workspaceRootLength+1 :],
errNeedField(name): error name + " must be defined",
SimpleFieldStruct(requiredFields): {
[requiredField]: $.errNeedField(requiredField)
for requiredField in requiredFields
},
simpleFieldStruct: $.SimpleFieldStruct,
Context: $.SimpleFieldStruct([
"helm"
]),
NewContext(helm): $.Context {
helm: helm
},
List(): {
apiVersion: "v1",
kind: "List",
items_:: {},
items: $.objectValues(self.items_),
},
#################
# Support utils #
#################
# For use in SERVICE.metadata.annotations position
# TODO(acmcarther): move this into
PrometheusScrapeable(port): {
"prometheus.io/scrape": "true",
"prometheus.io/port": std.toString(port),
},
NameVal(name, value): {
name: name,
value: value,
},
SvcUtil: {
# For use in SERVICE.spec.ports position
TCPServicePort(name, port): {
name: name,
port: port,
protocol: "TCP",
},
# For use in SERVICE.spec.ports position
UDPServicePort(name, port): {
name: name,
port: port,
protocol: "UDP",
},
# For use in SERVICE.spec
BasicHttpClusterIpSpec(internalPort): {
type: "ClusterIP",
ports: [
$.SvcUtil.TCPServicePort("http", 80) {
targetPort: internalPort
},
],
},
# For use in SERVICE.spec
BasicNodePortSpec(internalPort, nodePort): {
type: "NodePort",
ports: [
$.SvcUtil.TCPServicePort("tcp", internalPort) {
targetPort: internalPort,
nodePort: nodePort,
},
$.SvcUtil.UDPServicePort("udp", internalPort) {
targetPort: internalPort,
nodePort: nodePort,
},
],
}
},
DeployUtil: {
# For use in DEPLOYMENT.spec.template.spec.containers
VolumeMount(name, mountPath): {
name: name,
mountPath: mountPath,
},
# For use in DEPLOYMENT.spec.template.spec.volumes
VolumeClaimRef(name, claimName): {
name: name,
persistentVolumeClaim: {
claimName: claimName,
},
},
# For use in DEPLOYMENT.spec.template.spec.containers.ports
ContainerPort(name, port): {
name: name,
containerPort: port,
},
ContainerTCPPort(name, port): {
name: name,
containerPort: port,
protocol: "TCP",
},
# For use in DEPLOYMENT.spec.strategy
SimpleRollingUpdate(): {
type: "RollingUpdate",
rollingUpdate: {
maxUnavailable: 1,
},
},
# For use in DEPLOYMENT.spec.template.spec.*Probe
SimpleProbe(webPort, delaySeconds): {
httpGet: {
path: "/",
port: webPort,
},
initialDelaySeconds: delaySeconds,
},
},
##########################
# Kube object definition #
##########################
Namespace(name): baseKubeCompat._Object("v1", "Namespace", name),
StorageClass(name): baseKubeCompat._Object("storage.k8s.io/v1", "StorageClass", name) {
},
RecoverableSimplePvc(namespace, name, storageClass, quantity, recoverySpec): {
pv: if recoverySpec == null then {} else $.SimplePv(namespace, storageClass, quantity, recoverySpec.volumeName) {
spec+: {
nfs: {
path: recoverySpec.nfsPath,
server: recoverySpec.nfsServer,
}
}
},
pvc: $.SimplePvc(namespace, name, storageClass, quantity) {
spec+: {
volumeName: if recoverySpec == null then null else recoverySpec.volumeName,
}
}
},
RecoverableSimpleManyPvc(namespace, name, storageClass, quantity, recoverySpec): {
pv: if recoverySpec == null then {} else $.SimpleManyPv(namespace, storageClass, quantity, recoverySpec.volumeName) {
spec+: {
nfs: {
path: recoverySpec.nfsPath,
server: recoverySpec.nfsServer,
}
}
},
pvc: $.SimpleManyPvc(namespace, name, storageClass, quantity) {
spec+: {
volumeName: if recoverySpec == null then null else recoverySpec.volumeName,
}
}
},
# N.B. Actual storage must still be defined.
SimplePv(namespace, storageClass, quantity, name): baseKubeCompat._Object("v1", "PersistentVolume", name) {
metadata+: {
namespace: namespace,
},
spec+: {
storageClassName: storageClass,
volumeMode: "Filesystem",
persistentVolumeReclaimPolicy: "Delete",
capacity: {
storage: quantity,
},
accessModes: ["ReadWriteOnce"],
},
},
SimpleManyPv(namespace, storageClass, quantity, name): $.SimplePv(namespace, storageClass, quantity, name) {
spec+: {
accessModes: ["ReadWriteMany"],
},
},
SimplePvc(namespace, name, storageClass, quantity): baseKubeCompat._Object("v1", "PersistentVolumeClaim", name) {
metadata+: {
namespace: namespace,
},
spec: {
storageClassName: storageClass,
resources: {
requests: {
storage: quantity,
},
},
accessModes: ["ReadWriteOnce"],
},
},
SimpleManyPvc(namespace, name, storageClass, quantity): $.SimplePvc(namespace, name, storageClass, quantity) {
spec+: {
accessModes: ["ReadWriteMany"],
},
},
Role(namespace, name): baseKubeCompat._Object("rbac.authorization.k8s.io/v1", "Role", name) {
metadata+: {
namespace: namespace,
},
},
RoleBinding(namespace, name): baseKubeCompat._Object("rbac.authorization.k8s.io/v1", "RoleBinding", name) {
metadata+: {
namespace: namespace,
},
},
ConfigMap(namespace, name): baseKubeCompat._Object("v1", "ConfigMap", name) {
metadata+: {
namespace: namespace,
},
},
ClusterRole(name): baseKubeCompat._Object("rbac.authorization.k8s.io/v1", "ClusterRole", name) {
},
ClusterRoleBinding(name): baseKubeCompat._Object("rbac.authorization.k8s.io/v1", "ClusterRoleBinding", name) {
},
DaemonSet(namespace, name): baseKubeCompat._Object("apps/v1", "DaemonSet", name) {
metadata+: {
namespace: namespace,
},
},
ServiceAccount(namespace, name): baseKubeCompat._Object("v1", "ServiceAccount", name) {
metadata+: {
namespace: namespace,
},
},
Service(namespace, name): baseKubeCompat._Object("v1", "Service", name) {
metadata+: {
namespace: namespace,
},
# TODO(acmcarther): Figure out how to make this more useful
},
Deployment(namespace, name): baseKubeCompat._Object("apps/v1", "Deployment", name) {
metadata+: {
namespace: namespace,
},
},
StatefulSet(namespace, name): baseKubeCompat._Object("apps/v1", "StatefulSet", name) {
metadata+: {
namespace: namespace,
},
},
Ingress(namespace, name): baseKubeCompat._Object("networking.k8s.io/v1", "Ingress", name) {
metadata+: {
namespace: namespace,
},
},
Secret(namespace, name): baseKubeCompat._Object("v1", "Secret", name) {
metadata+: {
namespace: namespace,
},
},
CronJob(namespace, name): baseKubeCompat._Object("batch/v1", "CronJob", name) {
metadata+: {
namespace: namespace,
},
},
Endpoints(namespace, name): baseKubeCompat._Object("v1", "Endpoints", name) {
metadata+: {
namespace: namespace,
},
},
EndpointSlice(namespace, name): baseKubeCompat._Object("discovery.k8s.io/v1", "EndpointSlice", name) {
metadata+: {
namespace: namespace,
},
},
ApiService(name): baseKubeCompat._Object("apiregistration.k8s.io/v1", "APIService", name) {},
IngressClass(name): baseKubeCompat._Object("networking.k8s.io/v1", "IngressClass", name) {},
ClusterIssuer(namespace, name): baseKubeCompat._Object("cert-manager.io/v1", "ClusterIssuer", name) {
metadata+: {
namespace: namespace,
},
},
# Provides "curried" functions with namespace pre-bound
UsingNamespace(namespace): {
Endpoints(name): $.Endpoints(namespace, name),
EndpointSlice(name): $.EndpointSlice(namespace, name),
SimplePvc(name, storageClass, quantity): $.SimplePvc(namespace, name, storageClass, quantity),
SimpleManyPvc(name, storageClass, quantity): $.SimpleManyPvc(namespace, name, storageClass, quantity),
ServiceAccount(name): $.ServiceAccount(namespace, name),
Service(name): $.Service(namespace, name),
Deployment(name): $.Deployment(namespace, name),
CronJob(name): $.CronJob(namespace, name),
StatefulSet(name): $.StatefulSet(namespace, name),
Ingress(name): $.Ingress(namespace, name),
ConfigMap(name): $.ConfigMap(namespace, name),
},
}