...
1
2
3
4
5
6
7
8
9
10
11
12
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
39 type ExecAction struct {
40
41
42
43
44
45
46 Command []string `json:"command,omitempty"`
47 }
48
49
50 type InjectionConfig struct {
51 Name string
52
53 Selector *v1alpha1.PodSelectorSpec
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
63
64
65
66
67 PostStart map[string]ExecAction `json:"postStart,omitempty"`
68 }
69
70
71 type Config struct {
72 sync.RWMutex
73 AnnotationNamespace string
74 Injections map[string][]*InjectionConfig
75 }
76
77
78 type TemplateArgs struct {
79 Namespace string
80 Name string `yaml:"name"`
81
82 Template string `yaml:"template"`
83 Arguments map[string]string `yaml:"arguments"`
84
85 Selector *v1alpha1.PodSelectorSpec `json:"selector,omitempty"`
86 }
87
88
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
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
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
150 func (c *Config) ReplaceInjectionConfigs(updatedConfigs map[string][]*InjectionConfig) {
151 c.Lock()
152 defer c.Unlock()
153 c.Injections = updatedConfigs
154 }
155