...

Source file src/github.com/chaos-mesh/chaos-mesh/pkg/webhook/config/config.go

Documentation: github.com/chaos-mesh/chaos-mesh/pkg/webhook/config

     1  // Copyright 2019 Chaos Mesh Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package config
    15  
    16  import (
    17  	"fmt"
    18  	"io"
    19  	"io/ioutil"
    20  	"sync"
    21  
    22  	"github.com/ghodss/yaml"
    23  
    24  	corev1 "k8s.io/api/core/v1"
    25  
    26  	"github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
    27  )
    28  
    29  var (
    30  	errMissingName         = fmt.Errorf(`name field is required for template args config`)
    31  	errMissingTemplateName = fmt.Errorf(`template field is required for template args config`)
    32  )
    33  
    34  const (
    35  	annotationNamespaceDefault = "admission-webhook.chaos-mesh.org"
    36  )
    37  
    38  // ExecAction describes a "run in container" action.
    39  type ExecAction struct {
    40  	// Command is the command line to execute inside the container, the working directory for the
    41  	// command  is root ('/') in the container's filesystem. The command is simply exec'd, it is
    42  	// not run inside a shell, so traditional shell instructions ('|', etc) won't work. To use
    43  	// a shell, you need to explicitly call out to that shell.
    44  	// Exit status of 0 is treated as live/healthy and non-zero is unhealthy.
    45  	// +optional
    46  	Command []string `json:"command,omitempty"`
    47  }
    48  
    49  // InjectionConfig is a specific instance of an injected config, for a given annotation
    50  type InjectionConfig struct {
    51  	Name string
    52  	// Selector is used to select pods that are used to inject sidecar.
    53  	Selector *v1alpha1.SelectorSpec
    54  
    55  	Containers            []corev1.Container   `json:"containers"`
    56  	Volumes               []corev1.Volume      `json:"volumes"`
    57  	Environment           []corev1.EnvVar      `json:"env"`
    58  	VolumeMounts          []corev1.VolumeMount `json:"volumeMounts"`
    59  	HostAliases           []corev1.HostAlias   `json:"hostAliases"`
    60  	InitContainers        []corev1.Container   `json:"initContainers"`
    61  	ShareProcessNamespace bool                 `json:"shareProcessNamespace"`
    62  	// PostStart is called after a container is created first.
    63  	// If the handler fails, the containers will failed.
    64  	// Key defines for the name of deployment container.
    65  	// Value defines for the Commands for stating container.
    66  	// +optional
    67  	PostStart map[string]ExecAction `json:"postStart,omitempty"`
    68  }
    69  
    70  // Config is a struct indicating how a given injection should be configured
    71  type Config struct {
    72  	sync.RWMutex
    73  	AnnotationNamespace string
    74  	Injections          map[string][]*InjectionConfig
    75  }
    76  
    77  // TemplateArgs is a set of arguments to render template
    78  type TemplateArgs struct {
    79  	Namespace string
    80  	Name      string `yaml:"name"`
    81  	// Name of the template
    82  	Template  string            `yaml:"template"`
    83  	Arguments map[string]string `yaml:"arguments"`
    84  	// Selector is used to select pods that are used to inject sidecar.
    85  	Selector *v1alpha1.SelectorSpec `json:"selector,omitempty"`
    86  }
    87  
    88  // NewConfigWatcherConf creates a configuration for watcher
    89  func NewConfigWatcherConf() *Config {
    90  	return &Config{
    91  		AnnotationNamespace: annotationNamespaceDefault,
    92  		Injections:          make(map[string][]*InjectionConfig),
    93  	}
    94  }
    95  
    96  func (c *Config) RequestAnnotationKey() string {
    97  	return c.AnnotationNamespace + "/request"
    98  }
    99  
   100  func (c *Config) StatusAnnotationKey() string {
   101  	return c.AnnotationNamespace + "/status"
   102  }
   103  
   104  func (c *Config) RequestInitAnnotationKey() string {
   105  	return c.AnnotationNamespace + "/init-request"
   106  }
   107  
   108  // GetRequestedConfig returns the InjectionConfig given a requested key
   109  func (c *Config) GetRequestedConfig(namespace, key string) (*InjectionConfig, error) {
   110  	c.RLock()
   111  	defer c.RUnlock()
   112  
   113  	if _, ok := c.Injections[namespace]; !ok {
   114  		return nil, fmt.Errorf("no injection config at ns %s", namespace)
   115  	}
   116  
   117  	for _, conf := range c.Injections[namespace] {
   118  		if key == conf.Name {
   119  			return conf, nil
   120  		}
   121  	}
   122  
   123  	return nil, fmt.Errorf("no injection config found for key %s at ns %s", key, namespace)
   124  }
   125  
   126  // LoadTemplateArgs takes an io.Reader and parses out an template args
   127  func LoadTemplateArgs(reader io.Reader) (*TemplateArgs, error) {
   128  	data, err := ioutil.ReadAll(reader)
   129  	if err != nil {
   130  		return nil, err
   131  	}
   132  
   133  	var cfg TemplateArgs
   134  	if err := yaml.Unmarshal(data, &cfg); err != nil {
   135  		return nil, err
   136  	}
   137  
   138  	if cfg.Name == "" {
   139  		return nil, errMissingName
   140  	}
   141  
   142  	if cfg.Template == "" {
   143  		return nil, errMissingTemplateName
   144  	}
   145  
   146  	return &cfg, nil
   147  }
   148  
   149  // ReplaceInjectionConfigs will update the injection configs.
   150  func (c *Config) ReplaceInjectionConfigs(updatedConfigs map[string][]*InjectionConfig) {
   151  	c.Lock()
   152  	defer c.Unlock()
   153  	c.Injections = updatedConfigs
   154  }
   155