Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
gitpod-io
GitHub Repository: gitpod-io/gitpod
Path: blob/main/dev/blowtorch/cmd/ablaze.go
2497 views
1
// Copyright (c) 2020 Gitpod GmbH. All rights reserved.
2
// Licensed under the GNU Affero General Public License (AGPL).
3
// See License.AGPL.txt in the project root for license information.
4
5
package cmd
6
7
import (
8
"context"
9
"math/rand"
10
"os"
11
"os/signal"
12
"syscall"
13
14
"github.com/Pallinder/go-randomdata"
15
toxiproxy "github.com/Shopify/toxiproxy/client"
16
log "github.com/sirupsen/logrus"
17
"github.com/spf13/cobra"
18
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
19
"k8s.io/client-go/kubernetes"
20
21
"github.com/gitpod-io/gitpod/blowtorch/pkg/dart"
22
)
23
24
var ablazeCmd = &cobra.Command{
25
Use: "ablaze",
26
Short: "Adds a toxiproxy intermediate for a random service, adds some random toxics and restarts all pods",
27
Args: cobra.ExactArgs(0),
28
Run: func(cmd *cobra.Command, args []string) {
29
cfg, ns, err := getKubeconfig()
30
if err != nil {
31
log.WithError(err).Fatal("cannot get Kubernetes client config")
32
}
33
34
client, err := kubernetes.NewForConfig(cfg)
35
if err != nil {
36
log.WithError(err).Fatal("cannot connect to Kubernetes")
37
}
38
39
services, err := client.CoreV1().Services(ns).List(context.Background(), metav1.ListOptions{})
40
if err != nil {
41
log.WithError(err).Fatal("cannot list services")
42
}
43
if len(services.Items) == 0 {
44
log.WithError(err).Fatal("no services available")
45
}
46
srv := services.Items[rand.Intn(len(services.Items))]
47
targetService := srv.Name
48
log.WithField("targetService", targetService).Info("found service to mess with")
49
50
defer func() {
51
err = dart.Remove(cfg, ns, targetService)
52
if err != nil {
53
log.WithError(err).Fatal("cannot remove toxiproxy")
54
}
55
}()
56
tpc, err := dart.Inject(cfg, ns, targetService)
57
if err != nil {
58
log.WithError(err).Fatal("cannot inject toxiproxy")
59
}
60
defer tpc.Close()
61
62
proxies, err := tpc.Proxies()
63
if err != nil {
64
log.WithError(err).Fatal("cannot list proxies")
65
}
66
for pn, px := range proxies {
67
err = addRandomToxic(pn, px)
68
if err != nil {
69
log.WithError(err).WithField("proxy", pn).Fatal("cannot add random toxic")
70
}
71
}
72
73
// run until we're told to stop
74
sigChan := make(chan os.Signal, 1)
75
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)
76
log.Info("🎯 blowtorch up and running. Stop with SIGINT or CTRL+C")
77
<-sigChan
78
log.Info("received SIGINT - shutting down")
79
},
80
}
81
82
var (
83
toxicTypes = []string{"latency", "bandwidth", "slow_close", "timeout", "slicer"}
84
toxicStreams = []string{"upstream", "downstream"}
85
)
86
87
func addRandomToxic(name string, proxy *toxiproxy.Proxy) error {
88
var (
89
tname = randomdata.SillyName()
90
ttype = toxicTypes[rand.Intn(len(toxicTypes))]
91
tstream = toxicStreams[rand.Intn(len(toxicStreams))]
92
tattr toxiproxy.Attributes = make(toxiproxy.Attributes)
93
)
94
switch ttype {
95
case "latency":
96
tattr["latency"] = rand.Intn(30000) // ms
97
tattr["jitter"] = rand.Intn(5000) // ms
98
case "bandwidth":
99
tattr["rate"] = rand.Intn(1024) // kb/s
100
case "slow_close":
101
tattr["delay"] = rand.Intn(5000) // ms
102
case "timeout":
103
tattr["timeout"] = rand.Intn(5000) // ms
104
case "slicer":
105
tattr["average_size"] = rand.Intn(256) + 1 //bytes
106
tattr["size_variation"] = rand.Intn(64) // bytes
107
tattr["delay"] = rand.Intn(5000) // ms
108
}
109
_, err := proxy.AddToxic(tname, ttype, tstream, 1.0, tattr)
110
if err != nil {
111
return err
112
}
113
log.WithFields(log.Fields{
114
"proxy": name,
115
"name": tname,
116
"type": ttype,
117
"attrs": tattr,
118
"stream": tstream,
119
}).Info("adding toxic")
120
121
return nil
122
}
123
124
func init() {
125
rootCmd.AddCommand(ablazeCmd)
126
}
127
128