You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

246 lines
5.9 KiB

package controllers
import (
"strings"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
networkv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/util/intstr"
myAppsv1 "mashibing.com/pkg/mashibing-deployment/api/v1"
)
var IngressClassName = "nginx"
var PathTypePrefix = networkv1.PathTypePrefix
func NewDeployment(md *myAppsv1.MsbDeployment) appsv1.Deployment {
// 1. 创建基本的deployment
// 1.1 创建只含有metadata信息的对象
deploy := newBaseDeployment(md)
// 2. 创建附加的对象
// 2.1 在基本的deployment中添加其他的对象
deploy.Spec.Replicas = &md.Spec.Replicas
deploy.Spec.Selector = &metav1.LabelSelector{MatchLabels: newLabels(md)}
deploy.Spec.Template.ObjectMeta = metav1.ObjectMeta{Labels: newLabels(md)}
deploy.Spec.Template.Spec.Containers = []corev1.Container{
newBaseContainer(md),
}
return deploy
}
func NewIngress(md *myAppsv1.MsbDeployment) networkv1.Ingress {
ig := newBaseIngress(md)
ig.Spec.IngressClassName = &IngressClassName
ig.Spec.Rules = []networkv1.IngressRule{
newIngressRule(md),
}
if md.Spec.Expose.Tls {
ig.Spec.TLS = []networkv1.IngressTLS{
newIngressTLS(md),
}
}
return ig
}
func NewService(md *myAppsv1.MsbDeployment) corev1.Service {
svc := newBaseService(md)
svc.Spec.Selector = newLabels(md)
servicePort := newServicePort(md)
switch strings.ToLower(md.Spec.Expose.Mode) {
case myAppsv1.ModeIngress:
svc.Spec.Ports = []corev1.ServicePort{servicePort}
case myAppsv1.ModeNodePort:
svc.Spec.Type = corev1.ServiceTypeNodePort
servicePort.NodePort = md.Spec.Expose.NodePort
svc.Spec.Ports = []corev1.ServicePort{servicePort}
default:
return corev1.Service{}
}
return svc
}
// NewIssuer 实现创建issuer资源对象
func NewIssuer(md *myAppsv1.MsbDeployment) (*unstructured.Unstructured, error) {
if md.Spec.Expose.Mode != myAppsv1.ModeIngress ||
!md.Spec.Expose.Tls {
return nil, nil
}
// Sample
//apiVersion: cert-manager.io/v1
//kind: Issuer
//metadata:
// name: selfsigned-issuer
//spec:
// selfSigned: {}
return &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "cert-manager.io/v1",
"kind": "Issuer",
"metadata": map[string]interface{}{
"name": md.Name,
"namespace": md.Namespace,
},
"spec": map[string]interface{}{
"selfSigned": map[string]interface{}{},
},
},
}, nil
}
// NewCert 实现创建certificate资源
func NewCert(md *myAppsv1.MsbDeployment) (*unstructured.Unstructured, error) {
if md.Spec.Expose.Mode != myAppsv1.ModeIngress ||
!md.Spec.Expose.Tls {
return nil, nil
}
// Sample
//apiVersion: cert-manager.io/v1
//kind: Certificate
//metadata:
// name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml
// namespace: system
//spec:
// dnsNames:
// - <spec.expose.ingressDomain>
// issuerRef:
// kind: Issuer
// name: selfsigned-issuer
// secretName: webhook-server-cert
return &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "cert-manager.io/v1",
"kind": "Certificate",
"metadata": map[string]interface{}{
"name": md.Name,
"namespace": md.Namespace,
},
"spec": map[string]interface{}{
"dnsNames": []interface{}{
md.Spec.Expose.IngressDomain,
},
"issuerRef": map[string]interface{}{
"kind": "Issuer",
"name": md.Name,
},
"secretName": md.Name,
},
},
}, nil
}
func newBaseContainer(md *myAppsv1.MsbDeployment) corev1.Container {
c := corev1.Container{
Name: md.Name,
Image: md.Spec.Image,
Ports: []corev1.ContainerPort{
{
ContainerPort: md.Spec.Port,
},
},
}
if len(md.Spec.StartCmd) != 0 {
c.Command = md.Spec.StartCmd
}
if len(md.Spec.Args) != 0 {
c.Args = md.Spec.Args
}
if len(md.Spec.Environments) != 0 {
c.Env = md.Spec.Environments
}
return c
}
func newBaseDeployment(md *myAppsv1.MsbDeployment) appsv1.Deployment {
return appsv1.Deployment{
TypeMeta: metav1.TypeMeta{
Kind: "Deployment",
APIVersion: "apps/v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: md.Name,
Namespace: md.Namespace,
Labels: newLabels(md),
},
}
}
func newServicePort(md *myAppsv1.MsbDeployment) corev1.ServicePort {
return corev1.ServicePort{
Protocol: corev1.ProtocolTCP,
Port: md.Spec.Expose.ServicePort,
TargetPort: intstr.IntOrString{
Type: intstr.Int,
IntVal: md.Spec.Port,
},
}
}
func newBaseService(md *myAppsv1.MsbDeployment) corev1.Service {
return corev1.Service{
TypeMeta: metav1.TypeMeta{
Kind: "Service",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: md.Name,
Namespace: md.Namespace,
},
}
}
func newIngressTLS(md *myAppsv1.MsbDeployment) networkv1.IngressTLS {
return networkv1.IngressTLS{
Hosts: []string{md.Spec.Expose.IngressDomain},
SecretName: md.Name,
}
}
func newIngressRule(md *myAppsv1.MsbDeployment) networkv1.IngressRule {
return networkv1.IngressRule{
Host: md.Spec.Expose.IngressDomain,
IngressRuleValue: networkv1.IngressRuleValue{
HTTP: &networkv1.HTTPIngressRuleValue{
Paths: []networkv1.HTTPIngressPath{
{
PathType: &PathTypePrefix,
Path: "/",
Backend: networkv1.IngressBackend{
Service: &networkv1.IngressServiceBackend{
Name: md.Name,
Port: networkv1.ServiceBackendPort{
Number: md.Spec.Expose.ServicePort,
},
},
},
},
},
},
},
}
}
func newBaseIngress(md *myAppsv1.MsbDeployment) networkv1.Ingress {
return networkv1.Ingress{
TypeMeta: metav1.TypeMeta{
Kind: "Ingress",
APIVersion: "networking.k8s.io/v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: md.Name,
Namespace: md.Namespace,
},
}
}
func newLabels(md *myAppsv1.MsbDeployment) map[string]string {
return map[string]string{"app": md.Name}
}