github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/manager/resources/container/container.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 container
    20  
    21  import (
    22  	"github.com/IBM-Blockchain/fabric-operator/pkg/util"
    23  	"github.com/IBM-Blockchain/fabric-operator/pkg/util/image"
    24  	"github.com/pkg/errors"
    25  	appsv1 "k8s.io/api/apps/v1"
    26  	corev1 "k8s.io/api/core/v1"
    27  )
    28  
    29  type SecurityContext struct {
    30  	Privileged               *bool
    31  	RunAsNonRoot             *bool
    32  	RunAsUser                *int64
    33  	AllowPrivilegeEscalation *bool
    34  }
    35  
    36  func New(container *corev1.Container) *Container {
    37  	return &Container{container}
    38  }
    39  
    40  func LoadFromDeployment(deployment *appsv1.Deployment) map[string]Container {
    41  	containers := map[string]Container{}
    42  	for i, c := range deployment.Spec.Template.Spec.Containers {
    43  		containers[c.Name] = Container{&deployment.Spec.Template.Spec.Containers[i]}
    44  	}
    45  	for i, c := range deployment.Spec.Template.Spec.InitContainers {
    46  		containers[c.Name] = Container{&deployment.Spec.Template.Spec.InitContainers[i]}
    47  	}
    48  	return containers
    49  }
    50  
    51  func LoadFromFile(file string) (*Container, error) {
    52  	container, err := util.GetContainerFromFile(file)
    53  	if err != nil {
    54  		return nil, errors.Wrap(err, "failed to read container file")
    55  	}
    56  	return &Container{container}, nil
    57  }
    58  
    59  type Container struct {
    60  	*corev1.Container
    61  }
    62  
    63  func (c *Container) DeleteEnv(name string) {
    64  	newEnvs := []corev1.EnvVar{}
    65  	for _, env := range c.Env {
    66  		if env.Name == name {
    67  			continue
    68  		}
    69  		newEnvs = append(newEnvs, env)
    70  	}
    71  
    72  	c.Env = newEnvs
    73  }
    74  
    75  func (c *Container) UpdateEnv(name, value string) {
    76  	var updated bool
    77  
    78  	newEnvs := []corev1.EnvVar{}
    79  	for _, env := range c.Env {
    80  		if env.Name == name {
    81  			env.Value = value
    82  			updated = true
    83  		}
    84  		newEnvs = append(newEnvs, env)
    85  	}
    86  
    87  	if updated {
    88  		c.Env = newEnvs
    89  	} else {
    90  		c.Env = append(newEnvs, corev1.EnvVar{Name: name, Value: value})
    91  	}
    92  }
    93  
    94  func (c *Container) AppendEnvStructIfMissing(envVar corev1.EnvVar) {
    95  	c.Env = util.AppendEnvIfMissing(c.Env, envVar)
    96  }
    97  
    98  func (c *Container) AppendEnvIfMissing(name, value string) {
    99  	envVar := corev1.EnvVar{
   100  		Name:  name,
   101  		Value: value,
   102  	}
   103  	c.Env = util.AppendEnvIfMissing(c.Env, envVar)
   104  }
   105  
   106  func (c *Container) AppendEnvIfMissingOverrideIfPresent(name, value string) {
   107  	envVar := corev1.EnvVar{
   108  		Name:  name,
   109  		Value: value,
   110  	}
   111  	c.Env = util.AppendEnvIfMissingOverrideIfPresent(c.Env, envVar)
   112  }
   113  
   114  func (c *Container) SetImage(img, tag string) {
   115  	if img != "" {
   116  		if tag != "" {
   117  			c.Container.Image = image.Format(img, tag)
   118  		} else {
   119  			c.Container.Image = img + ":latest"
   120  		}
   121  	}
   122  }
   123  
   124  func (c *Container) AppendVolumeMountStructIfMissing(volumeMount corev1.VolumeMount) {
   125  	c.VolumeMounts = util.AppendVolumeMountIfMissing(c.VolumeMounts, volumeMount)
   126  }
   127  
   128  func (c *Container) AppendVolumeMountIfMissing(name, mountPath string) {
   129  	volumeMount := corev1.VolumeMount{
   130  		Name:      name,
   131  		MountPath: mountPath,
   132  	}
   133  	c.VolumeMounts = util.AppendVolumeMountIfMissing(c.VolumeMounts, volumeMount)
   134  }
   135  
   136  func (c *Container) AppendVolumeMountWithSubPathIfMissing(name, mountPath, subPath string) {
   137  	volumeMount := corev1.VolumeMount{
   138  		Name:      name,
   139  		MountPath: mountPath,
   140  		SubPath:   subPath,
   141  	}
   142  	c.VolumeMounts = util.AppendVolumeMountWithSubPathIfMissing(c.VolumeMounts, volumeMount)
   143  }
   144  
   145  func (c *Container) AppendVolumeMountWithSubPath(name, mountPath, subPath string) {
   146  	volumeMount := corev1.VolumeMount{
   147  		Name:      name,
   148  		MountPath: mountPath,
   149  		SubPath:   subPath,
   150  	}
   151  	c.VolumeMounts = append(c.VolumeMounts, volumeMount)
   152  }
   153  
   154  func (c *Container) SetVolumeMounts(volumeMounts []corev1.VolumeMount) {
   155  	c.VolumeMounts = volumeMounts
   156  }
   157  
   158  func (c *Container) UpdateResources(new *corev1.ResourceRequirements) error {
   159  	current := &c.Resources
   160  	update, err := util.GetResourcePatch(current, new)
   161  	if err != nil {
   162  		return errors.Wrap(err, "failed to get resource patch")
   163  	}
   164  
   165  	c.Resources = *update
   166  	return nil
   167  }
   168  
   169  func (c *Container) SetCommand(command []string) {
   170  	c.Command = command
   171  }
   172  
   173  func (c *Container) SetArgs(args []string) {
   174  	c.Args = args
   175  }
   176  
   177  func (c *Container) AppendConfigMapFromSourceIfMissing(name string) {
   178  	envFrom := corev1.EnvFromSource{
   179  		ConfigMapRef: &corev1.ConfigMapEnvSource{
   180  			LocalObjectReference: corev1.LocalObjectReference{
   181  				Name: name,
   182  			},
   183  		},
   184  	}
   185  	c.EnvFrom = util.AppendConfigMapFromSourceIfMissing(c.Container.EnvFrom, envFrom)
   186  }
   187  
   188  func (c *Container) AppendEnvVarValueFromIfMissing(name string, valueFrom *corev1.EnvVarSource) {
   189  	envVar := corev1.EnvVar{
   190  		Name:      name,
   191  		ValueFrom: valueFrom,
   192  	}
   193  	c.Env = util.AppendEnvIfMissing(c.Container.Env, envVar)
   194  }
   195  
   196  func (c *Container) GetEnvs(reqs []string) []corev1.EnvVar {
   197  	envVars := []corev1.EnvVar{}
   198  
   199  	for _, env := range c.Env {
   200  		for _, req := range reqs {
   201  			if env.Name == req {
   202  				envVars = append(envVars, env)
   203  			}
   204  		}
   205  	}
   206  
   207  	return envVars
   208  }
   209  
   210  // UpdateSecurityContext will update the security context of the container
   211  func (c *Container) UpdateSecurityContext(sc SecurityContext) {
   212  	UpdateSecurityContext(c.Container, sc)
   213  }
   214  
   215  // UpdateSecurityContext will update the security context of passed in container
   216  func UpdateSecurityContext(c *corev1.Container, sc SecurityContext) {
   217  	if c.SecurityContext == nil {
   218  		c.SecurityContext = &corev1.SecurityContext{}
   219  	}
   220  
   221  	c.SecurityContext.Privileged = sc.Privileged
   222  	c.SecurityContext.RunAsNonRoot = sc.RunAsNonRoot
   223  	c.SecurityContext.RunAsUser = sc.RunAsUser
   224  	c.SecurityContext.AllowPrivilegeEscalation = sc.AllowPrivilegeEscalation
   225  }
   226  
   227  func (c *Container) SetReadinessProbe(probe *corev1.Probe) {
   228  	c.ReadinessProbe = probe
   229  }
   230  
   231  func (c *Container) SetLivenessProbe(probe *corev1.Probe) {
   232  	c.LivenessProbe = probe
   233  }
   234  
   235  func (c *Container) SetStartupProbe(probe *corev1.Probe) {
   236  	c.StartupProbe = probe
   237  }