github.com/caos/orbos@v1.5.14-0.20221103111702-e6cd0cea7ad4/cmd/chore/e2e/run/desire.go (about)

     1  package main
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"fmt"
     7  	"time"
     8  
     9  	"github.com/caos/orbos/internal/helpers"
    10  
    11  	"github.com/caos/orbos/internal/operator/common"
    12  
    13  	"gopkg.in/yaml.v3"
    14  )
    15  
    16  var _ testFunc = desireORBITERState
    17  
    18  func desireORBITERState(specs *testSpecs, settings programSettings, conditions *conditions) interactFunc {
    19  
    20  	clusterSpec := fmt.Sprintf(`      controlplane:
    21          updatesdisabled: false
    22          provider: %s
    23          nodes: %d
    24          pool: management
    25          taints:
    26          - key: node-role.kubernetes.io/master
    27            effect: NoSchedule
    28        kubeconfig: null
    29        networking:
    30          dnsdomain: cluster.orbitertest
    31          network: calico
    32          podcidr: 100.126.4.0/22
    33          servicecidr: 100.127.224.0/20
    34        verbose: false
    35        versions:
    36          kubernetes: v1.18.8
    37          orbiter: %s
    38        workers:
    39        - updatesdisabled: false
    40          provider: %s
    41          nodes: %d
    42          pool: application`,
    43  		settings.orbID,
    44  		specs.DesireORBITERState.InitialMasters,
    45  		settings.artifactsVersion(),
    46  		settings.orbID,
    47  		specs.DesireORBITERState.InitialWorkers,
    48  	)
    49  
    50  	if err := yaml.Unmarshal([]byte(clusterSpec), conditions.kubernetes); err != nil {
    51  		panic(err)
    52  	}
    53  
    54  	return func(ctx context.Context, _ uint8, newOrbctl newOrbctlCommandFunc) error {
    55  
    56  		initCtx, initCancel := context.WithTimeout(ctx, 1*time.Minute)
    57  		defer initCancel()
    58  
    59  		var providerYml string
    60  		if err := runCommand(settings, nil, nil, func(line string) {
    61  			providerYml += fmt.Sprintf("    %s\n", line)
    62  		}, newOrbctl(initCtx), "--gitops", "file", "print", "provider.yml"); err != nil {
    63  			return err
    64  		}
    65  
    66  		conditions.testCase = nil
    67  
    68  		return desireState(initCtx, settings, newOrbctl, "orbiter.yml", fmt.Sprintf(`kind: orbiter.caos.ch/Orb
    69  version: v0
    70  spec:
    71    verbose: false
    72  clusters:
    73    %s:
    74      kind: orbiter.caos.ch/KubernetesCluster
    75      version: v0
    76      spec:
    77  %s
    78  providers:
    79    %s:
    80  %s
    81      loadbalancing:
    82        kind: orbiter.caos.ch/DynamicLoadBalancer
    83        version: v2
    84        spec:
    85          management:
    86          - ip: 192.168.122.2
    87            transport:
    88            - name: kubeapi
    89              frontendport: 6443
    90              backendport: 6666
    91              backendpools:
    92              - management
    93              whitelist:
    94              - 0.0.0.0/0
    95              healthchecks:
    96                protocol: https
    97                path: /healthz
    98                code: 200
    99          application:
   100          - ip: 192.168.122.3
   101            transport:
   102            - name: httpsingress
   103              frontendport: 443
   104              backendport: 30443
   105              backendpools:
   106              - application
   107              whitelist:
   108              - 0.0.0.0/0
   109              healthchecks:
   110                protocol: https
   111                path: /ambassador/v0/check_ready
   112                code: 200
   113              proxyprotocol: true
   114            - name: httpingress
   115              frontendport: 80
   116              backendport: 30080
   117              backendpools:
   118              - application
   119              whitelist:
   120              - 0.0.0.0/0
   121              healthchecks:
   122                protocol: http
   123                path: /ambassador/v0/check_ready
   124                code: 200
   125              proxyprotocol: true
   126  `, settings.orbID, clusterSpec, settings.orbID, providerYml))
   127  	}
   128  }
   129  
   130  func desireBOOMState(deploy bool) testFunc {
   131  	return func(specs *testSpecs, settings programSettings, conditions *conditions) interactFunc {
   132  
   133  		// needs to be assigned also when test is skipped
   134  		conditions.boom = &condition{
   135  			watcher: watch(10*time.Minute, boom),
   136  			checks: func(ctx context.Context, newKubectl newKubectlCommandFunc, orbiter currentOrbiter, current common.NodeAgentsCurrentKind) error {
   137  
   138  				checkCtx, checkCancel := context.WithTimeout(ctx, 1*time.Minute)
   139  				defer checkCancel()
   140  
   141  				var expectTotal uint8
   142  				checkPodsAreReadyFunc := func(selector string, expectPods uint8) func() error {
   143  					expectTotal += expectPods
   144  					return func() error {
   145  						return checkPodsAreReady(checkCtx, settings, newKubectl, "caos-system", selector, expectPods)
   146  					}
   147  				}
   148  
   149  				if !deploy {
   150  					// only orbiter and boom should be running in caos-system
   151  					return checkPodsAreReadyFunc("", 2)()
   152  				}
   153  
   154  				workers := conditions.desiredWorkers()
   155  				allNodes := conditions.desiredMasters() + workers
   156  
   157  				return helpers.Fanout([]func() error{
   158  					checkPodsAreReadyFunc("app.kubernetes.io/instance=ambassador", 2),
   159  					checkPodsAreReadyFunc("app.kubernetes.io/instance=argocd", 4),
   160  					checkPodsAreReadyFunc("app.kubernetes.io/instance=grafana", 1),
   161  					checkPodsAreReadyFunc("app.kubernetes.io/instance=kube-state-metrics", 1),
   162  					checkPodsAreReadyFunc("app.kubernetes.io/name=fluentbit", workers),
   163  					checkPodsAreReadyFunc("app.kubernetes.io/name=fluentd", 1),
   164  					checkPodsAreReadyFunc("app.kubernetes.io/instance=logging-operator", 1),
   165  					checkPodsAreReadyFunc("app=loki", 1),
   166  					checkPodsAreReadyFunc("app=prometheus-node-exporter", allNodes),
   167  					checkPodsAreReadyFunc("app=prometheus", 1),
   168  					checkPodsAreReadyFunc("app=prometheus-operator-operator", 1),
   169  					checkPodsAreReadyFunc("app=systemd-exporter", allNodes),
   170  					checkPodsAreReadyFunc("app.kubernetes.io/name notin (orbiter, boom)", expectTotal),
   171  					func() error {
   172  						provider, ok := orbiter.Providers[settings.orbID]
   173  						if !ok {
   174  							return fmt.Errorf("provider %s not found in current state", settings.orbID)
   175  						}
   176  
   177  						ep := provider.Current.Ingresses.Httpsingress
   178  
   179  						msg, err := helpers.Check("https", ep.Location, ep.FrontendPort, "/ambassador/v0/check_ready", 200, false)
   180  						if err != nil {
   181  							return fmt.Errorf("ambassador ready check failed with message: %s: %w", msg, err)
   182  						}
   183  
   184  						settings.logger.Infof(msg)
   185  
   186  						return nil
   187  					},
   188  				})()
   189  			},
   190  		}
   191  
   192  		return func(ctx context.Context, step uint8, orbctl newOrbctlCommandFunc) (err error) {
   193  
   194  			storage := `
   195      storage:
   196        accessModes:
   197          - ReadWriteOnce
   198        size: 1G`
   199  
   200  			if specs.DesireBOOMState.Stateless {
   201  				storage = ""
   202  			}
   203  
   204  			return desireState(ctx, settings, orbctl, "boom.yml", fmt.Sprintf(`
   205  apiVersion: caos.ch/v1
   206  kind: Boom
   207  metadata:
   208    name: caos
   209    namespace: caos-system
   210  spec:
   211    boomVersion: %s
   212    preApply:
   213      folder: preapply
   214      deploy: true
   215    postApply:
   216      folder: postapply
   217      deploy: true
   218    metricCollection:
   219      resources:
   220        requests: {}
   221      deploy: %t
   222    logCollection:
   223      deploy: %t
   224      fluentbit:
   225        resources:
   226          requests: {}
   227      fluentd:
   228        resources:
   229          requests: {}
   230    nodeMetricsExporter:
   231      resources:
   232        requests: {}
   233      deploy: %t
   234    systemdMetricsExporter:
   235      resources:
   236        requests: {}
   237      deploy: %t
   238    monitoring:
   239      resources:
   240        requests: {}
   241      deploy: %t
   242    apiGateway:
   243      deploy: %t
   244      replicaCount: 1
   245      service:
   246        type: NodePort
   247    kubeMetricsExporter:
   248      deploy: %t
   249      resources:
   250        requests: {}
   251    reconciling:
   252      deploy: %t
   253      resources:
   254        requests: {}
   255    metricsPersisting:
   256      deploy: %t
   257      resources:
   258        requests: {}%s
   259    logsPersisting:
   260      deploy: %t
   261      resources:
   262        requests: {}
   263    metricsServer:
   264      deploy: false
   265  `,
   266  				settings.artifactsVersion(),
   267  				deploy,
   268  				deploy,
   269  				deploy,
   270  				deploy,
   271  				deploy,
   272  				deploy,
   273  				deploy,
   274  				deploy,
   275  				deploy,
   276  				storage,
   277  				deploy,
   278  			))
   279  		}
   280  	}
   281  }
   282  
   283  func desireState(ctx context.Context, settings programSettings, newOrbctl newOrbctlCommandFunc, path, yml string) error {
   284  
   285  	desireCtx, desireCancel := context.WithTimeout(ctx, 1*time.Minute)
   286  	defer desireCancel()
   287  
   288  	cmd := newOrbctl(desireCtx)
   289  	cmd.Stdin = bytes.NewReader([]byte(yml))
   290  
   291  	return runCommand(settings, orbctl.strPtr(), nil, nil, cmd, "--gitops", "file", "patch", path, "--exact", "--stdin")
   292  }