templates.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /*
  2. Copyright 2023 The Rook Authors. All rights reserved.
  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. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package multus
  14. import (
  15. "bytes"
  16. _ "embed"
  17. "fmt"
  18. "strings"
  19. "text/template"
  20. apps "k8s.io/api/apps/v1"
  21. core "k8s.io/api/core/v1"
  22. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  23. "k8s.io/apimachinery/pkg/util/yaml"
  24. )
  25. var (
  26. //go:embed nginx-pod.yaml
  27. nginxPodTemplate string
  28. //go:embed nginx-config.yaml
  29. nginxConfigTemplate string
  30. //go:embed image-pull-daemonset.yaml
  31. imagePullDaemonSet string
  32. //go:embed client-daemonset.yaml
  33. clientDaemonSet string
  34. )
  35. type webServerTemplateConfig struct {
  36. NetworksAnnotationValue string
  37. NginxImage string
  38. Placement PlacementConfig
  39. }
  40. type imagePullTemplateConfig struct {
  41. NodeType string
  42. NginxImage string
  43. Placement PlacementConfig
  44. }
  45. type clientTemplateConfig struct {
  46. NodeType string
  47. ClientType string
  48. ClientID int
  49. NetworksAnnotationValue string
  50. NetworkNamesAndAddresses map[string]string
  51. NginxImage string
  52. Placement PlacementConfig
  53. }
  54. func webServerPodName() string {
  55. return "multus-validation-test-web-server"
  56. }
  57. func imagePullAppLabel() string {
  58. return "app=multus-validation-test-image-pull"
  59. }
  60. func getNodeType(m *metav1.ObjectMeta) string {
  61. return m.GetLabels()["nodeType"]
  62. }
  63. func clientAppLabel() string {
  64. return "app=multus-validation-test-client"
  65. }
  66. const (
  67. ClientTypeOSD = "osd"
  68. ClientTypeNonOSD = "other"
  69. )
  70. type daemonsetAppType string
  71. const imagePullDaemonSetAppType = "image pull"
  72. const clientDaemonSetAppType = "client"
  73. func (vt *ValidationTest) generateWebServerTemplateConfig(placement PlacementConfig) webServerTemplateConfig {
  74. return webServerTemplateConfig{
  75. NetworksAnnotationValue: vt.generateNetworksAnnotationValue(true, true), // always on both nets
  76. NginxImage: vt.NginxImage,
  77. Placement: placement,
  78. }
  79. }
  80. func (vt *ValidationTest) generateClientTemplateConfig(
  81. attachPublic, attachCluster bool,
  82. serverPublicAddr, serverClusterAddr string,
  83. nodeType, clientType string,
  84. clientID int,
  85. placement PlacementConfig,
  86. ) clientTemplateConfig {
  87. netNamesAndAddresses := map[string]string{}
  88. if attachPublic && serverPublicAddr != "" {
  89. netNamesAndAddresses["public"] = serverPublicAddr
  90. }
  91. if attachCluster && serverClusterAddr != "" {
  92. netNamesAndAddresses["cluster"] = serverClusterAddr
  93. }
  94. return clientTemplateConfig{
  95. NodeType: nodeType,
  96. ClientType: clientType,
  97. ClientID: clientID,
  98. NetworksAnnotationValue: vt.generateNetworksAnnotationValue(attachPublic, attachCluster),
  99. NetworkNamesAndAddresses: netNamesAndAddresses,
  100. NginxImage: vt.NginxImage,
  101. Placement: placement,
  102. }
  103. }
  104. func (vt *ValidationTest) generateImagePullTemplateConfig(nodeType string, placement PlacementConfig) imagePullTemplateConfig {
  105. return imagePullTemplateConfig{
  106. NodeType: nodeType,
  107. NginxImage: vt.NginxImage,
  108. Placement: placement,
  109. }
  110. }
  111. func (vt *ValidationTest) generateWebServerPod(placement PlacementConfig) (*core.Pod, error) {
  112. t, err := loadTemplate("webServerPod", nginxPodTemplate, vt.generateWebServerTemplateConfig(placement))
  113. if err != nil {
  114. return nil, fmt.Errorf("failed to load web server pod template: %w", err)
  115. }
  116. var p core.Pod
  117. err = yaml.Unmarshal(t, &p)
  118. if err != nil {
  119. return nil, fmt.Errorf("failed to unmarshal web server pod template: %w", err)
  120. }
  121. return &p, nil
  122. }
  123. func (vt *ValidationTest) generateWebServerConfigMap() (*core.ConfigMap, error) {
  124. t, err := loadTemplate("webServerConfigMap", nginxConfigTemplate, vt.generateWebServerTemplateConfig(
  125. PlacementConfig{}, // not used for configmap
  126. ))
  127. if err != nil {
  128. return nil, fmt.Errorf("failed to load web server configmap template: %w", err)
  129. }
  130. var cm core.ConfigMap
  131. err = yaml.Unmarshal(t, &cm)
  132. if err != nil {
  133. return nil, fmt.Errorf("failed to unmarshal web server configmap template: %w", err)
  134. }
  135. return &cm, nil
  136. }
  137. func (vt *ValidationTest) generateImagePullDaemonSet(nodeType string, placement PlacementConfig) (*apps.DaemonSet, error) {
  138. t, err := loadTemplate("imagePullDaemonSet", imagePullDaemonSet, vt.generateImagePullTemplateConfig(nodeType, placement))
  139. if err != nil {
  140. return nil, fmt.Errorf("failed to load image pull daemonset template: %w", err)
  141. }
  142. var d apps.DaemonSet
  143. err = yaml.Unmarshal(t, &d)
  144. if err != nil {
  145. return nil, fmt.Errorf("failed to unmarshal image pull daemonset template: %w", err)
  146. }
  147. return &d, nil
  148. }
  149. func (vt *ValidationTest) generateClientDaemonSet(
  150. attachPublic, attachCluster bool,
  151. serverPublicAddr, serverClusterAddr string,
  152. nodeType, clientType string,
  153. clientID int,
  154. placement PlacementConfig,
  155. ) (*apps.DaemonSet, error) {
  156. t, err := loadTemplate("clientDaemonSet", clientDaemonSet, vt.generateClientTemplateConfig(attachPublic, attachCluster, serverPublicAddr, serverClusterAddr, nodeType, clientType, clientID, placement))
  157. if err != nil {
  158. return nil, fmt.Errorf("failed to load client daemonset template: %w", err)
  159. }
  160. var d apps.DaemonSet
  161. err = yaml.Unmarshal(t, &d)
  162. if err != nil {
  163. return nil, fmt.Errorf("failed to unmarshal client daemonset template: %w", err)
  164. }
  165. return &d, nil
  166. }
  167. func (vt *ValidationTest) generateNetworksAnnotationValue(public, cluster bool) string {
  168. nets := []string{}
  169. if public && vt.PublicNetwork != "" {
  170. nets = append(nets, vt.PublicNetwork)
  171. }
  172. if cluster && vt.ClusterNetwork != "" {
  173. nets = append(nets, vt.ClusterNetwork)
  174. }
  175. return strings.Join(nets, ",")
  176. }
  177. func loadTemplate(name, templateFileText string, config interface{}) ([]byte, error) {
  178. var writer bytes.Buffer
  179. t := template.New(name)
  180. t, err := t.Parse(templateFileText)
  181. if err != nil {
  182. return nil, fmt.Errorf("failed to parse template %q: %w", name, err)
  183. }
  184. err = t.Execute(&writer, config)
  185. return writer.Bytes(), err
  186. }