blob: 842fd3ff6d759d8ccac185bb58127fd351940e2d [file] [log] [blame]
Pawel Wieczorek6b223c92019-05-26 15:35:02 +02001// Package rancher wraps Rancher commands necessary for K8s inspection.
2package rancher
3
4import (
5 "bytes"
Pawel Wieczorek76dd9bf2019-09-26 16:43:01 +02006 "fmt"
Pawel Wieczorek6b223c92019-05-26 15:35:02 +02007 "os/exec"
Pawel Wieczorek76dd9bf2019-09-26 16:43:01 +02008
9 "check"
Pawel Wieczorek6b223c92019-05-26 15:35:02 +020010)
11
12const (
13 bin = "rancher"
14 paramHost = "--host"
15 cmdHosts = "hosts"
16 cmdHostsParams = "--quiet"
17 cmdDocker = "docker"
18 cmdDockerCmdPs = "ps"
19 cmdDockerCmdPsParams = "--no-trunc"
20 cmdDockerCmdPsFilter = "--filter"
Pawel Wieczorek76dd9bf2019-09-26 16:43:01 +020021 cmdDockerCmdPsFilterArgs = "label=io.rancher.stack_service.name="
Pawel Wieczorek6b223c92019-05-26 15:35:02 +020022 cmdDockerCmdPsFormat = "--format"
23 cmdDockerCmdPsFormatArgs = "{{.Command}}"
Pawel Wieczorek6b223c92019-05-26 15:35:02 +020024)
25
Pawel Wieczorek76dd9bf2019-09-26 16:43:01 +020026// Rancher implements Informer interface.
27type Rancher struct {
28 check.Informer
29}
30
31// GetAPIParams returns parameters of running Kubernetes API server.
Pawel Wieczorek6b223c92019-05-26 15:35:02 +020032// It queries default environment set in configuration file.
Pawel Wieczorek76dd9bf2019-09-26 16:43:01 +020033func (r *Rancher) GetAPIParams() ([]string, error) {
34 return getProcessParams(check.APIProcess, check.APIService)
35}
36
Pawel Wieczorek96f4e2f2019-09-27 16:10:33 +020037// GetSchedulerParams returns parameters of running Kubernetes scheduler.
38// It queries default environment set in configuration file.
39func (r *Rancher) GetSchedulerParams() ([]string, error) {
40 return getProcessParams(check.SchedulerProcess, check.SchedulerService)
41}
42
Pawel Wieczorek5a61d612019-09-27 18:26:13 +020043// GetControllerManagerParams returns parameters of running Kubernetes scheduler.
44// It queries default environment set in configuration file.
45func (r *Rancher) GetControllerManagerParams() ([]string, error) {
46 return getProcessParams(check.ControllerManagerProcess, check.ControllerManagerService)
47}
48
Pawel Wieczorek76dd9bf2019-09-26 16:43:01 +020049func getProcessParams(process check.Command, service check.Service) ([]string, error) {
Pawel Wieczorek6b223c92019-05-26 15:35:02 +020050 hosts, err := listHosts()
51 if err != nil {
52 return []string{}, err
53 }
54
55 for _, host := range hosts {
Pawel Wieczorek76dd9bf2019-09-26 16:43:01 +020056 cmd, err := getPsCmdOutput(host, service)
Pawel Wieczorek6b223c92019-05-26 15:35:02 +020057 if err != nil {
58 return []string{}, err
59 }
60
61 if len(cmd) > 0 {
Pawel Wieczorek76dd9bf2019-09-26 16:43:01 +020062 i := bytes.Index(cmd, []byte(process.String()))
Pawel Wieczorek6b223c92019-05-26 15:35:02 +020063 if i == -1 {
Pawel Wieczorek76dd9bf2019-09-26 16:43:01 +020064 return []string{}, fmt.Errorf("missing %s command", process)
Pawel Wieczorek6b223c92019-05-26 15:35:02 +020065 }
Pawel Wieczorek76dd9bf2019-09-26 16:43:01 +020066 return btos(cmd[i+len(process.String()):]), nil
Pawel Wieczorek6b223c92019-05-26 15:35:02 +020067 }
68 }
69 return []string{}, nil
70}
71
72// listHosts lists IDs of active hosts.
73// It queries default environment set in configuration file.
74func listHosts() ([]string, error) {
75 cmd := exec.Command(bin, cmdHosts, cmdHostsParams)
76 out, err := cmd.Output()
77 if err != nil {
78 return nil, err
79 }
80 return btos(out), nil
81}
82
Pawel Wieczorek76dd9bf2019-09-26 16:43:01 +020083// getPsCmdOutput returns running Kubernetes service command with its parameters.
Pawel Wieczorek6b223c92019-05-26 15:35:02 +020084// It queries default environment set in configuration file.
Pawel Wieczorek76dd9bf2019-09-26 16:43:01 +020085func getPsCmdOutput(host string, service check.Service) ([]byte, error) {
Pawel Wieczorek6b223c92019-05-26 15:35:02 +020086 // Following is equivalent to:
87 // $ rancher --host $HOST \
88 // docker ps --no-trunc \
Pawel Wieczorek76dd9bf2019-09-26 16:43:01 +020089 // --filter "label=io.rancher.stack_service.name=$SERVICE" \
Pawel Wieczorek6b223c92019-05-26 15:35:02 +020090 // --format "{{.Command}}"
91 cmd := exec.Command(bin, paramHost, host,
92 cmdDocker, cmdDockerCmdPs, cmdDockerCmdPsParams,
Pawel Wieczorek76dd9bf2019-09-26 16:43:01 +020093 cmdDockerCmdPsFilter, cmdDockerCmdPsFilterArgs+service.String(),
Pawel Wieczorek6b223c92019-05-26 15:35:02 +020094 cmdDockerCmdPsFormat, cmdDockerCmdPsFormatArgs)
95 out, err := cmd.Output()
96 if err != nil {
97 return nil, err
98 }
99 return out, nil
100}
101
102// btos converts slice of bytes to slice of strings split by white space characters.
103func btos(in []byte) []string {
104 var out []string
105 for _, b := range bytes.Fields(in) {
106 out = append(out, string(b))
107 }
108 return out
109}