shardingsphere-operator/pkg/kubernetes/deployment/builder.go (181 lines of code) (raw):
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package deployment
import (
"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/kubernetes/metadata"
"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/kubernetes/pod"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
)
// DeploymentBuilder returns a deployment builder
type DeploymentBuilder interface {
metadata.MetadataBuilder
pod.PodSpecBuilder
SetSelectors(selectors *metav1.LabelSelector) DeploymentBuilder
SetReplicas(r *int32) DeploymentBuilder
SetRollingUpdateStrategy(maxUnavailable, maxSurge int) DeploymentBuilder
SetPodTemplateMetadata(obj *metav1.ObjectMeta) DeploymentBuilder
SetPodTemplateSpec(tpl *corev1.PodTemplateSpec) DeploymentBuilder
BuildDeployment() *appsv1.Deployment
}
// NewDeploymentBuilder creates a new DeploymentBuilder
func NewDeploymentBuilder() DeploymentBuilder {
return &deploymentBuilder{
deployment: &appsv1.Deployment{},
PodSpecBuilder: pod.NewPodBuilder(),
MetadataBuilder: metadata.NewMetadataBuilder(),
}
}
type deploymentBuilder struct {
deployment *appsv1.Deployment
pod.PodSpecBuilder
metadata.MetadataBuilder
}
// SetLabelsAndSelectors sets labels and selectors to Deployment labels, spec.selectors
// and spec.template.labels
func (d *deploymentBuilder) SetSelectors(selectors *metav1.LabelSelector) DeploymentBuilder {
d.deployment.Spec.Selector = selectors
return d
}
// SetReplicas sets Deployment replicas
func (d *deploymentBuilder) SetReplicas(r *int32) DeploymentBuilder {
d.deployment.Spec.Replicas = r
return d
}
func (d *deploymentBuilder) SetRollingUpdateStrategy(maxUnavailable, maxSurge int) DeploymentBuilder {
if d.deployment.Spec.Strategy.RollingUpdate == nil {
d.deployment.Spec.Strategy.RollingUpdate = &appsv1.RollingUpdateDeployment{}
}
ms := intstr.FromInt(maxSurge)
mu := intstr.FromInt(maxUnavailable)
d.deployment.Spec.Strategy.RollingUpdate.MaxSurge = &ms
d.deployment.Spec.Strategy.RollingUpdate.MaxUnavailable = &mu
return d
}
// SetPodTemplateMetadata sets Deployment PodTemplateMetadata for ShardingSphereProxy Pod
func (d *deploymentBuilder) SetPodTemplateMetadata(obj *metav1.ObjectMeta) DeploymentBuilder {
d.deployment.Spec.Template.ObjectMeta = *obj
return d
}
// SetPodTemplateSpec sets Deployment PodTemplateSpec for ShardingSphereProxy Pod
func (d *deploymentBuilder) SetPodTemplateSpec(tpl *corev1.PodTemplateSpec) DeploymentBuilder {
d.deployment.Spec.Template = *tpl
return d
}
// SetPodTemplateAnnotations sets annotations for ShardingSphereProxy Pod
func (d *deploymentBuilder) SetPodTemplateAnnotations(annotations map[string]string) DeploymentBuilder {
d.deployment.Spec.Template.Annotations = annotations
return d
}
// SetPodTemplateLabels sets labels for ShardingSphereProxy Pod
func (d *deploymentBuilder) SetPodTemplateLabels(labels map[string]string) DeploymentBuilder {
d.deployment.Spec.Template.Labels = labels
return d
}
// Build returns a Deployment
func (d *deploymentBuilder) BuildDeployment() *appsv1.Deployment {
d.deployment.ObjectMeta = *d.MetadataBuilder.BuildMetadata()
return d.deployment
}
// SharedVolumeAndMountBuilder build a Volume which could be mounted by different containers
type SharedVolumeAndMountBuilder interface {
SetName(name string) SharedVolumeAndMountBuilder
SetMountPath(idx int, path string) SharedVolumeAndMountBuilder
SetSubPath(idx int, subpath string) SharedVolumeAndMountBuilder
SetVolumeMountSize(size int) SharedVolumeAndMountBuilder
SetVolumeSourceEmptyDir() SharedVolumeAndMountBuilder
SetVolumeSourceConfigMap(name string, kps ...corev1.KeyToPath) SharedVolumeAndMountBuilder
Build() (*corev1.Volume, []*corev1.VolumeMount)
}
type sharedVolumeAndMountBuilder struct {
volume *corev1.Volume
volumeMounts []*corev1.VolumeMount
}
// NewSharedVolumeAndMountBuilder returns a new SharedVolumeAndMountBuilder
func NewSharedVolumeAndMountBuilder() SharedVolumeAndMountBuilder {
return &sharedVolumeAndMountBuilder{
volume: &corev1.Volume{},
volumeMounts: []*corev1.VolumeMount{},
}
}
// SetName sets Volume and VolumeMounts name
func (b *sharedVolumeAndMountBuilder) SetName(name string) SharedVolumeAndMountBuilder {
b.volume.Name = name
for vm := range b.volumeMounts {
b.volumeMounts[vm].Name = name
}
return b
}
// SetVolumeMountSize sets size of VolumeMounts
func (b *sharedVolumeAndMountBuilder) SetVolumeMountSize(size int) SharedVolumeAndMountBuilder {
if len(b.volumeMounts) != size {
vms := make([]*corev1.VolumeMount, size)
for vm := range b.volumeMounts {
vms[vm] = b.volumeMounts[vm].DeepCopy()
}
b.volumeMounts = vms
}
for vm := range b.volumeMounts {
if b.volumeMounts[vm] == nil {
b.volumeMounts[vm] = &corev1.VolumeMount{}
}
}
return b
}
// SetMountPath sets mountPath of a Volume
func (b *sharedVolumeAndMountBuilder) SetMountPath(idx int, path string) SharedVolumeAndMountBuilder {
if b.volumeMounts[idx] == nil {
b.volumeMounts[idx] = &corev1.VolumeMount{}
}
b.volumeMounts[idx].MountPath = path
return b
}
// SetSubPath sets subPath of a Volume
func (b *sharedVolumeAndMountBuilder) SetSubPath(idx int, subpath string) SharedVolumeAndMountBuilder {
if b.volumeMounts[idx] == nil {
b.volumeMounts[idx] = &corev1.VolumeMount{}
}
b.volumeMounts[idx].SubPath = subpath
return b
}
// SetVolumeSourceEmptyDir sets a EmptyDir as Volume
func (b *sharedVolumeAndMountBuilder) SetVolumeSourceEmptyDir() SharedVolumeAndMountBuilder {
if b.volume.EmptyDir == nil {
b.volume.EmptyDir = &corev1.EmptyDirVolumeSource{}
}
return b
}
// SetVolumeSourceConfigMap sets a ConfigMap as Volume
func (b *sharedVolumeAndMountBuilder) SetVolumeSourceConfigMap(name string, kps ...corev1.KeyToPath) SharedVolumeAndMountBuilder {
if b.volume.ConfigMap == nil {
b.volume.ConfigMap = &corev1.ConfigMapVolumeSource{}
}
b.volume.ConfigMap.LocalObjectReference.Name = name
if len(kps) > 0 {
b.volume.ConfigMap.Items = kps
}
return b
}
// Build creates a new volume and volumeMounts
func (b *sharedVolumeAndMountBuilder) Build() (*corev1.Volume, []*corev1.VolumeMount) {
return b.volume, b.volumeMounts
}
// VolumeAndMountBuilder build a Volume and related VolumeMount
type VolumeAndMountBuilder interface {
SetName(string) VolumeAndMountBuilder
Build() (*corev1.Volume, *corev1.VolumeMount)
}
// NewVolumeAndMountBuilder returns a VolumeAndMountBuilder
func NewVolumeAndMountBuilder() VolumeAndMountBuilder {
return &volumeAndMountBuilder{
volume: &corev1.Volume{},
volumemount: &corev1.VolumeMount{},
}
}
type volumeAndMountBuilder struct {
volume *corev1.Volume
volumemount *corev1.VolumeMount
}
// SetName sets Volume and VolumeMount name
func (b *volumeAndMountBuilder) SetName(name string) VolumeAndMountBuilder {
b.volume.Name = name
b.volumemount.Name = name
return b
}
// SetMountPath sets mountPath of VolumeMount
func (b *volumeAndMountBuilder) SetMountPath(path string) VolumeAndMountBuilder {
b.volumemount.MountPath = path
return b
}
// SetSubPath sets subPath of VolumeMount
func (b *volumeAndMountBuilder) SetSubPath(subpath string) VolumeAndMountBuilder {
b.volumemount.SubPath = subpath
return b
}
// SetVolumeSourceEmptyDir sets EmptyDir as a Volume
func (b *volumeAndMountBuilder) SetVolumeSourceEmptyDir() VolumeAndMountBuilder {
b.volume.EmptyDir = &corev1.EmptyDirVolumeSource{}
return b
}
// SetVolumeSourceConfigMap sets ConfigMap as a Volume
func (b *volumeAndMountBuilder) SetVolumeSourceConfigMap(name string) VolumeAndMountBuilder {
b.volume.ConfigMap.LocalObjectReference.Name = name
return b
}
// Build builds a Volume and VolumeMount
func (b *volumeAndMountBuilder) Build() (*corev1.Volume, *corev1.VolumeMount) {
return b.volume, b.volumemount
}