github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/manager/resources/deployment/deployment.go (about)

     1  /*
     2   * Copyright contributors to the Hyperledger Fabric Operator project
     3   *
     4   * SPDX-License-Identifier: Apache-2.0
     5   *
     6   * Licensed under the Apache License, Version 2.0 (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at:
     9   *
    10   * 	  http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18  
    19  package deployment
    20  
    21  import (
    22  	"fmt"
    23  
    24  	"github.com/IBM-Blockchain/fabric-operator/pkg/manager/resources/container"
    25  	"github.com/IBM-Blockchain/fabric-operator/pkg/util"
    26  	appsv1 "k8s.io/api/apps/v1"
    27  	v1 "k8s.io/api/apps/v1"
    28  	corev1 "k8s.io/api/core/v1"
    29  )
    30  
    31  func New(deployment *v1.Deployment) *Deployment {
    32  	return &Deployment{
    33  		Deployment: deployment,
    34  	}
    35  }
    36  
    37  type Deployment struct {
    38  	*v1.Deployment
    39  }
    40  
    41  func (d *Deployment) RemoveContainer(name string) {
    42  	for i, c := range d.Deployment.Spec.Template.Spec.Containers {
    43  		if c.Name == name {
    44  			if i == len(d.Deployment.Spec.Template.Spec.Containers)-1 {
    45  				d.Deployment.Spec.Template.Spec.Containers = d.Deployment.Spec.Template.Spec.Containers[:len(d.Deployment.Spec.Template.Spec.Containers)-1]
    46  				return
    47  			}
    48  
    49  			d.Deployment.Spec.Template.Spec.Containers = append(
    50  				d.Deployment.Spec.Template.Spec.Containers[:i],
    51  				d.Deployment.Spec.Template.Spec.Containers[i+1:]...)
    52  			return
    53  		}
    54  	}
    55  }
    56  
    57  func (d *Deployment) UpdateContainer(update container.Container) {
    58  	for i, c := range d.Deployment.Spec.Template.Spec.Containers {
    59  		if c.Name == update.Name {
    60  			d.Deployment.Spec.Template.Spec.Containers[i] = *update.Container
    61  			return
    62  		}
    63  	}
    64  }
    65  
    66  func (d *Deployment) UpdateInitContainer(update container.Container) {
    67  	for i, c := range d.Deployment.Spec.Template.Spec.InitContainers {
    68  		if c.Name == update.Name {
    69  			d.Deployment.Spec.Template.Spec.InitContainers[i] = *update.Container
    70  			return
    71  		}
    72  	}
    73  }
    74  
    75  func (d *Deployment) AddContainer(add container.Container) {
    76  	d.Deployment.Spec.Template.Spec.Containers = util.AppendContainerIfMissing(d.Deployment.Spec.Template.Spec.Containers, *add.Container)
    77  }
    78  
    79  func (d *Deployment) AddInitContainer(add container.Container) {
    80  	d.Deployment.Spec.Template.Spec.InitContainers = util.AppendContainerIfMissing(d.Deployment.Spec.Template.Spec.InitContainers, *add.Container)
    81  }
    82  
    83  func (d *Deployment) ContainerNames() []string {
    84  	names := []string{}
    85  	for _, c := range d.Deployment.Spec.Template.Spec.Containers {
    86  		names = append(names, c.Name)
    87  	}
    88  	for _, c := range d.Deployment.Spec.Template.Spec.InitContainers {
    89  		names = append(names, c.Name)
    90  	}
    91  	return names
    92  }
    93  
    94  func (d *Deployment) GetContainers() map[string]container.Container {
    95  	return container.LoadFromDeployment(d.Deployment)
    96  }
    97  
    98  func (d *Deployment) MustGetContainer(name string) container.Container {
    99  	cont, _ := d.GetContainer(name)
   100  	return cont
   101  }
   102  
   103  func (d *Deployment) GetContainer(name string) (cont container.Container, err error) {
   104  	for i, c := range d.Deployment.Spec.Template.Spec.Containers {
   105  		if c.Name == name {
   106  			cont = container.Container{Container: &d.Deployment.Spec.Template.Spec.Containers[i]}
   107  			return
   108  		}
   109  	}
   110  	for i, c := range d.Deployment.Spec.Template.Spec.InitContainers {
   111  		if c.Name == name {
   112  			cont = container.Container{Container: &d.Deployment.Spec.Template.Spec.InitContainers[i]}
   113  			return
   114  		}
   115  	}
   116  	return cont, fmt.Errorf("container '%s' not found", name)
   117  }
   118  
   119  func (d *Deployment) ContainerExists(name string) bool {
   120  	_, found := d.GetContainers()[name]
   121  	return found
   122  }
   123  
   124  func (d *Deployment) SetServiceAccountName(name string) {
   125  	d.Deployment.Spec.Template.Spec.ServiceAccountName = name
   126  }
   127  
   128  func (d *Deployment) SetImagePullSecrets(pullSecrets []string) {
   129  	if pullSecrets != nil && len(pullSecrets) > 0 {
   130  		d.Deployment.Spec.Template.Spec.ImagePullSecrets = []corev1.LocalObjectReference{}
   131  
   132  		for _, pullSecret := range pullSecrets {
   133  			imagePullSecret := corev1.LocalObjectReference{
   134  				Name: pullSecret,
   135  			}
   136  			d.Deployment.Spec.Template.Spec.ImagePullSecrets = util.AppendImagePullSecretIfMissing(d.Deployment.Spec.Template.Spec.ImagePullSecrets, imagePullSecret)
   137  		}
   138  	}
   139  }
   140  
   141  func (d *Deployment) AppendPullSecret(imagePullSecret corev1.LocalObjectReference) {
   142  	d.Deployment.Spec.Template.Spec.ImagePullSecrets = util.AppendImagePullSecretIfMissing(d.Deployment.Spec.Template.Spec.ImagePullSecrets, imagePullSecret)
   143  }
   144  
   145  func (d *Deployment) AppendVolumeIfMissing(volume corev1.Volume) {
   146  	d.Deployment.Spec.Template.Spec.Volumes = util.AppendVolumeIfMissing(d.Deployment.Spec.Template.Spec.Volumes, volume)
   147  }
   148  
   149  func (d *Deployment) AppendPVCVolumeIfMissing(name, claimName string) {
   150  	volume := corev1.Volume{
   151  		Name: name,
   152  		VolumeSource: corev1.VolumeSource{
   153  			PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{
   154  				ClaimName: claimName,
   155  			},
   156  		},
   157  	}
   158  	d.AppendVolumeIfMissing(volume)
   159  }
   160  
   161  func (d *Deployment) AppendConfigMapVolumeIfMissing(name, localObjReferenceName string) {
   162  	volume := corev1.Volume{
   163  		Name: name,
   164  		VolumeSource: corev1.VolumeSource{
   165  			ConfigMap: &corev1.ConfigMapVolumeSource{
   166  				LocalObjectReference: corev1.LocalObjectReference{
   167  					Name: localObjReferenceName,
   168  				},
   169  			},
   170  		},
   171  	}
   172  	d.AppendVolumeIfMissing(volume)
   173  }
   174  
   175  func (d *Deployment) AppendSecretVolumeIfMissing(name, secretName string) {
   176  	volume := corev1.Volume{
   177  		Name: name,
   178  		VolumeSource: corev1.VolumeSource{
   179  			Secret: &corev1.SecretVolumeSource{
   180  				SecretName: secretName,
   181  			},
   182  		},
   183  	}
   184  	d.AppendVolumeIfMissing(volume)
   185  }
   186  
   187  func (d *Deployment) AppendEmptyDirVolumeIfMissing(name string, storageMedium corev1.StorageMedium) {
   188  	volume := corev1.Volume{
   189  		Name: name,
   190  		VolumeSource: corev1.VolumeSource{
   191  			EmptyDir: &corev1.EmptyDirVolumeSource{
   192  				Medium: storageMedium,
   193  			},
   194  		},
   195  	}
   196  	d.AppendVolumeIfMissing(volume)
   197  }
   198  
   199  func (d *Deployment) AppendHostPathVolumeIfMissing(name, hostPath string, hostPathType corev1.HostPathType) {
   200  	volume := corev1.Volume{
   201  		Name: name,
   202  		VolumeSource: corev1.VolumeSource{
   203  			HostPath: &corev1.HostPathVolumeSource{
   204  				Path: hostPath,
   205  				Type: &hostPathType,
   206  			},
   207  		},
   208  	}
   209  	d.AppendVolumeIfMissing(volume)
   210  }
   211  
   212  func (d *Deployment) SetAffinity(affinity *corev1.Affinity) {
   213  	d.Deployment.Spec.Template.Spec.Affinity = affinity
   214  }
   215  
   216  func (d *Deployment) SetReplicas(replicas *int32) {
   217  	d.Deployment.Spec.Replicas = replicas
   218  }
   219  
   220  func (d *Deployment) SetStrategy(strategyType appsv1.DeploymentStrategyType) {
   221  	strategy := appsv1.DeploymentStrategy{
   222  		Type: appsv1.RollingUpdateDeploymentStrategyType,
   223  	}
   224  	d.Deployment.Spec.Strategy = strategy
   225  }
   226  
   227  // UpdateSecurityContextForAllContainers updates the security context for all containers defined
   228  // in the deployment
   229  func (d *Deployment) UpdateSecurityContextForAllContainers(sc container.SecurityContext) {
   230  	for i := range d.Spec.Template.Spec.InitContainers {
   231  		container.UpdateSecurityContext(&d.Spec.Template.Spec.InitContainers[i], sc)
   232  	}
   233  
   234  	for i := range d.Spec.Template.Spec.Containers {
   235  		container.UpdateSecurityContext(&d.Spec.Template.Spec.Containers[i], sc)
   236  	}
   237  }