@@ -2,6 +2,8 @@ package main
22
33import (
44 "bufio"
5+ "crypto/x509"
6+ "encoding/base64"
57 "fmt"
68 "io"
79 "net/http"
@@ -25,37 +27,39 @@ func newCli(appConfig *appConfig) *cli {
2527 }
2628}
2729
28- func logHelp () {
29- log .Info ("Available Commands:" )
30- log .Info (" help: get info about available commands and endpoints" )
31- log .Info (" init: set readiness true, liveness true and delay 0" )
32- log .Info (" config: print out the current application configuration" )
33- log .Info (" set ready: application readiness probe will be successful" )
34- log .Info (" set unready: application readiness probe will fail" )
35- log .Info (" set alive: application liveness probe will be successful" )
36- log .Info (" set dead: application liveness probe will fail" )
37- log .Info (" leak mem: leak memory" )
38- log .Info (" leak cpu: leak cpu" )
39- log .Info (" request <url>: request a url, eg 'request https://www.kubermatic.com/'" )
40- log .Info (" delay / <seconds>: set delay for the root endpoint ('/') in seconds, eg 'delay / 5'" )
41- log .Info ("Available Endpoints:" )
42- log .Info (" /: root endpoint, the output is depending on the application configuration" )
43- log .Info (" /liveness: liveness probe" )
44- log .Info (" /readiness: readiness probe" )
30+ func createHelpText () string {
31+ var sb strings.Builder
32+ sb .WriteString ("\n Available Commands:\n " )
33+ sb .WriteString ("\t help: get info about available commands and endpoints\n " )
34+ sb .WriteString ("\t init: set readiness true, liveness true and delay 0\n " )
35+ sb .WriteString ("\t config: print out the current application configuration\n " )
36+ sb .WriteString ("\t set ready: application readiness probe will be successful\n " )
37+ sb .WriteString ("\t set unready: application readiness probe will fail\n " )
38+ sb .WriteString ("\t set alive: application liveness probe will be successful\n " )
39+ sb .WriteString ("\t set dead: application liveness probe will fail\n " )
40+ sb .WriteString ("\t leak mem: leak memory\n " )
41+ sb .WriteString ("\t leak cpu: leak cpu\n " )
42+ sb .WriteString ("\t request <url>: request a url, eg 'request https://www.kubermatic.com/'\n " )
43+ sb .WriteString ("\t delay / <seconds>: set delay for the root endpoint ('/') in seconds, eg 'delay / 5'\n " )
44+ sb .WriteString ("\t able Endpoints:\n " )
45+ sb .WriteString ("\t /: root endpoint, the output is depending on the application configuration\n " )
46+ sb .WriteString ("\t /liveness: liveness probe\n " )
47+ sb .WriteString ("\t /readiness: readiness probe\n " )
48+ return sb .String ()
4549}
4650
4751func (cli * cli ) handleStdin () {
4852 reader := bufio .NewReader (os .Stdin )
4953 for {
5054 text , err := reader .ReadString ('\n' )
5155 if err != nil {
52- log .Errorf ("Error on reading from stdin: '%s'" , err )
56+ log .Errorf ("error on reading from stdin: '%s'" , err )
5357 }
5458 text = strings .ReplaceAll (text , "\n " , "" )
5559 if text != "" {
5660 err = cli .executeCommand (text )
5761 if err != nil {
58- log .Errorf ("Error on handling command '%s': %s" , text , err )
62+ log .Errorf ("error on handling command '%s': %s" , text , err )
5963 }
6064 }
6165 }
@@ -64,14 +68,14 @@ func (cli *cli) handleStdin() {
6468func (cli * cli ) executeCommand (command string ) error {
6569
6670 if command == "help" {
67- logHelp ( )
71+ log . Info ( createHelpText () )
6872 } else if command == "init" {
6973 log .Info ("Re-initializing the application configuration" )
7074 cli .config .initAppConfig (true )
7175 cli .config .ready = true
72- cli .config . logAppConfig ( )
76+ log . Info ( cli .config )
7377 } else if command == "config" {
74- cli .config . logAppConfig ( )
78+ log . Info ( cli .config )
7579 } else if command == "set ready" {
7680 cli .config .ready = true
7781 log .Info ("Set the application to ready" )
@@ -107,10 +111,10 @@ func (cli *cli) executeCommand(command string) error {
107111 log .Infof ("Set delay for the root endpoint ('/') to '%d' seconds" , cli .config .rootDelaySeconds )
108112 } else if strings .HasPrefix (command , "disable /" ) {
109113 cli .config .rootEnabled = false
110- log .Info ("Disabled the root endpoint ('/')" )
114+ log .Info ("Disabled the root endpoint ('/')" )
111115 } else if strings .HasPrefix (command , "enable /" ) {
112116 cli .config .rootEnabled = true
113- log .Info ("Enabled the root endpoint ('/')" )
117+ log .Info ("Enabled the root endpoint ('/')" )
114118 } else {
115119 return fmt .Errorf ("unknown command '%s'" , command )
116120 }
@@ -123,24 +127,35 @@ func request(url string) error {
123127 if err != nil {
124128 return err
125129 }
126- defer resp .Body .Close ()
130+ defer func () {
131+ if err := resp .Body .Close (); err != nil {
132+ log .Errorf ("error on closing: %v" , err )
133+ }
134+ }()
127135
128136 log .Infof ("StatusCode of response %d" , resp .StatusCode )
129137
130138 if resp .TLS == nil {
131139 log .Info ("Response is not encrypted" )
140+ clientCertHeader := resp .Header .Get ("X-Client-Cert" )
141+ if clientCertHeader != "" {
142+ certData , err := base64 .StdEncoding .DecodeString (clientCertHeader )
143+ if err != nil {
144+ log .Errorf ("error decoding proxied certificate: %s" , err )
145+ }
146+ cert , err := x509 .ParseCertificate (certData )
147+ if err != nil {
148+ log .Errorf ("error parsing proxied certificate: %s" , err )
149+ }
150+ log .Info (getCertString ("Proxied certificate" , cert ))
151+ } else {
152+ log .Infof ("No proxied certificate found" )
153+ }
132154 } else {
133155 log .Info ("Response is encrypted" )
134156 log .Infof ("TLS Version: %d" , resp .TLS .Version )
135- for _ , cert := range resp .TLS .PeerCertificates {
136- log .Infof ("Certificate Subject: %s" , cert .Subject .String ())
137- log .Infof ("Certificate Issuer: %s" , cert .Issuer .String ())
138- log .Infof ("Certificate Serial Number: %s" , cert .SerialNumber .String ())
139- log .Infof ("Certificate Not Before: %s" , cert .NotBefore .String ())
140- log .Infof ("Certificate Not After: %s" , cert .NotAfter .String ())
141- log .Infof ("Certificate DNS Names: %v" , cert .DNSNames )
142- log .Infof ("Certificate Email Addresses: %v" , cert .EmailAddresses )
143- log .Infof ("Certificate IP Addresses: %v" , cert .IPAddresses )
157+ for i , cert := range resp .TLS .PeerCertificates {
158+ log .Info (getCertString (fmt .Sprintf ("Certificate %d" , i + 1 ), cert ))
144159 }
145160 }
146161
@@ -156,6 +171,20 @@ func request(url string) error {
156171 return nil
157172}
158173
174+ func getCertString (header string , cert * x509.Certificate ) string {
175+ var sb strings.Builder
176+ sb .WriteString (fmt .Sprintf ("%s: \n " , header ))
177+ sb .WriteString (fmt .Sprintf ("\t Certificate Subject: %s\n " , cert .Subject .String ()))
178+ sb .WriteString (fmt .Sprintf ("\t Certificate Issuer: %s\n " , cert .Issuer .String ()))
179+ sb .WriteString (fmt .Sprintf ("\t Certificate Serial Number: %s\n " , cert .SerialNumber .String ()))
180+ sb .WriteString (fmt .Sprintf ("\t Certificate Not Before: %s\n " , cert .NotBefore .String ()))
181+ sb .WriteString (fmt .Sprintf ("\t Certificate Not After: %s\n " , cert .NotAfter .String ()))
182+ sb .WriteString (fmt .Sprintf ("\t Certificate DNS Names: %v\n " , cert .DNSNames ))
183+ sb .WriteString (fmt .Sprintf ("\t Certificate Email Addresses: %v\n " , cert .EmailAddresses ))
184+ sb .WriteString (fmt .Sprintf ("\t Certificate IP Addresses: %v\n " , cert .IPAddresses ))
185+ return sb .String ()
186+ }
187+
159188func leakMem () {
160189 memLeak := make ([]string , 0 )
161190 count := 0
@@ -170,7 +199,7 @@ func leakMem() {
170199 }
171200 time .Sleep (time .Nanosecond )
172201 count ++
173- memLeak = append (memLeak , "THIS IS A MEM LEAK" )
202+ memLeak = append (memLeak , "THIS IS A MEM LEAK" ) //nolint:staticcheck
174203 }
175204}
176205
@@ -188,7 +217,7 @@ func leakCpu() {
188217 waitGroup .Add (1 )
189218 go cpuIntensiveTask (& waitGroup , numGoroutines + 1 )
190219 }
191- }
220+ }
192221
193222func cpuIntensiveTask (waitGroup * sync.WaitGroup , id int ) {
194223 defer waitGroup .Done ()
@@ -200,34 +229,34 @@ func cpuIntensiveTask(waitGroup *sync.WaitGroup, id int) {
200229 fmt .Printf ("Goroutine %d finished\n " , id )
201230}
202231
203- // // TODO is this really the smartest way to create a CPU leak?
204-
205- // writer, err := os.Open(os.DevNull)
206- // if err != nil {
207- // log.Errorf("Error on opening /dev/null: %s", err)
208- // return err
209- // }
210- // defer writer.Close()
211- // n := runtime.NumCPU()
212- // runtime.GOMAXPROCS(n)
213-
214- // for i := 0; i < n; i++ {
215- // go func() {
216- // for {
217- // var usage syscall.Rusage
218- // err = syscall.Getrusage(syscall.RUSAGE_SELF, &usage)
219- // if err != nil {
220- // log.Errorf("Error on cpu usage: %s", err)
221- // }
222- // log.Infof("User CPU Time: %v\n", usage.Utime)
223- // log.Infof("System CPU Time: %v\n", usage.Stime)
224- // fmt.Fprintf(writer, ".")
225- // }
226- // }()
227- // }
228-
229- // // TODO do I need this?
230- // // time.Sleep(10 * time.Second)
231- // return nil
232+ // // TODO is this really the smartest way to create a CPU leak?
233+
234+ // writer, err := os.Open(os.DevNull)
235+ // if err != nil {
236+ // log.Errorf("error on opening /dev/null: %s", err)
237+ // return err
238+ // }
239+ // defer writer.Close()
240+ // n := runtime.NumCPU()
241+ // runtime.GOMAXPROCS(n)
242+
243+ // for i := 0; i < n; i++ {
244+ // go func() {
245+ // for {
246+ // var usage syscall.Rusage
247+ // err = syscall.Getrusage(syscall.RUSAGE_SELF, &usage)
248+ // if err != nil {
249+ // log.Errorf("error on cpu usage: %s", err)
250+ // }
251+ // log.Infof("User CPU Time: %v\n", usage.Utime)
252+ // log.Infof("System CPU Time: %v\n", usage.Stime)
253+ // fmt.Fprintf(writer, ".")
254+ // }
255+ // }()
256+ // }
257+
258+ // // TODO do I need this?
259+ // // time.Sleep(10 * time.Second)
260+ // return nil
232261
233262// }
0 commit comments