| // Package rancher wraps Rancher commands necessary for K8s inspection. |
| package rancher |
| |
| import ( |
| "bytes" |
| "errors" |
| "os/exec" |
| ) |
| |
| const ( |
| bin = "rancher" |
| paramHost = "--host" |
| cmdHosts = "hosts" |
| cmdHostsParams = "--quiet" |
| cmdDocker = "docker" |
| cmdDockerCmdPs = "ps" |
| cmdDockerCmdPsParams = "--no-trunc" |
| cmdDockerCmdPsFilter = "--filter" |
| cmdDockerCmdPsFilterArgs = "label=io.rancher.stack_service.name=kubernetes/kubernetes" |
| cmdDockerCmdPsFormat = "--format" |
| cmdDockerCmdPsFormatArgs = "{{.Command}}" |
| k8sProcess = "kube-apiserver" |
| ) |
| |
| // GetK8sParams returns parameters of running Kubernetes API server. |
| // It queries default environment set in configuration file. |
| func GetK8sParams() ([]string, error) { |
| hosts, err := listHosts() |
| if err != nil { |
| return []string{}, err |
| } |
| |
| for _, host := range hosts { |
| cmd, err := getK8sCmd(host) |
| if err != nil { |
| return []string{}, err |
| } |
| |
| if len(cmd) > 0 { |
| i := bytes.Index(cmd, []byte(k8sProcess)) |
| if i == -1 { |
| return []string{}, errors.New("missing " + k8sProcess + " command") |
| } |
| return btos(cmd[i+len(k8sProcess):]), nil |
| } |
| } |
| return []string{}, nil |
| } |
| |
| // listHosts lists IDs of active hosts. |
| // It queries default environment set in configuration file. |
| func listHosts() ([]string, error) { |
| cmd := exec.Command(bin, cmdHosts, cmdHostsParams) |
| out, err := cmd.Output() |
| if err != nil { |
| return nil, err |
| } |
| return btos(out), nil |
| } |
| |
| // getK8sCmd returns running Kubernetes API server command with its parameters. |
| // It queries default environment set in configuration file. |
| func getK8sCmd(host string) ([]byte, error) { |
| // Following is equivalent to: |
| // $ rancher --host $HOST \ |
| // docker ps --no-trunc \ |
| // --filter "label=io.rancher.stack_service.name=kubernetes/kubernetes" \ |
| // --format "{{.Command}}" |
| cmd := exec.Command(bin, paramHost, host, |
| cmdDocker, cmdDockerCmdPs, cmdDockerCmdPsParams, |
| cmdDockerCmdPsFilter, cmdDockerCmdPsFilterArgs, |
| cmdDockerCmdPsFormat, cmdDockerCmdPsFormatArgs) |
| out, err := cmd.Output() |
| if err != nil { |
| return nil, err |
| } |
| return out, nil |
| } |
| |
| // btos converts slice of bytes to slice of strings split by white space characters. |
| func btos(in []byte) []string { |
| var out []string |
| for _, b := range bytes.Fields(in) { |
| out = append(out, string(b)) |
| } |
| return out |
| } |