sigs.k8s.io/kubebuilder/v3@v3.14.0/test/e2e/utils/kubectl.go (about) 1 /* 2 Copyright 2019 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package utils 18 19 import ( 20 "encoding/json" 21 "errors" 22 "os/exec" 23 "strconv" 24 "strings" 25 ) 26 27 // Kubectl contains context to run kubectl commands 28 type Kubectl struct { 29 *CmdContext 30 Namespace string 31 ServiceAccount string 32 } 33 34 // Command is a general func to run kubectl commands 35 func (k *Kubectl) Command(cmdOptions ...string) (string, error) { 36 cmd := exec.Command("kubectl", cmdOptions...) 37 output, err := k.Run(cmd) 38 return string(output), err 39 } 40 41 // WithInput is a general func to run kubectl commands with input 42 func (k *Kubectl) WithInput(stdinInput string) *Kubectl { 43 k.Stdin = strings.NewReader(stdinInput) 44 return k 45 } 46 47 // CommandInNamespace is a general func to run kubectl commands in the namespace 48 func (k *Kubectl) CommandInNamespace(cmdOptions ...string) (string, error) { 49 if len(k.Namespace) == 0 { 50 return "", errors.New("namespace should not be empty") 51 } 52 return k.Command(append([]string{"-n", k.Namespace}, cmdOptions...)...) 53 } 54 55 // Apply is a general func to run kubectl apply commands 56 func (k *Kubectl) Apply(inNamespace bool, cmdOptions ...string) (string, error) { 57 ops := append([]string{"apply"}, cmdOptions...) 58 if inNamespace { 59 return k.CommandInNamespace(ops...) 60 } 61 return k.Command(ops...) 62 } 63 64 // Get is a func to run kubectl get commands 65 func (k *Kubectl) Get(inNamespace bool, cmdOptions ...string) (string, error) { 66 ops := append([]string{"get"}, cmdOptions...) 67 if inNamespace { 68 return k.CommandInNamespace(ops...) 69 } 70 return k.Command(ops...) 71 } 72 73 // Delete is a func to run kubectl delete commands 74 func (k *Kubectl) Delete(inNamespace bool, cmdOptions ...string) (string, error) { 75 ops := append([]string{"delete"}, cmdOptions...) 76 if inNamespace { 77 return k.CommandInNamespace(ops...) 78 } 79 return k.Command(ops...) 80 } 81 82 // Logs is a func to run kubectl logs commands 83 func (k *Kubectl) Logs(cmdOptions ...string) (string, error) { 84 ops := append([]string{"logs"}, cmdOptions...) 85 return k.CommandInNamespace(ops...) 86 } 87 88 // Wait is a func to run kubectl wait commands 89 func (k *Kubectl) Wait(inNamespace bool, cmdOptions ...string) (string, error) { 90 ops := append([]string{"wait"}, cmdOptions...) 91 if inNamespace { 92 return k.CommandInNamespace(ops...) 93 } 94 return k.Command(ops...) 95 } 96 97 // VersionInfo holds a subset of client/server version information. 98 type VersionInfo struct { 99 Major string `json:"major"` 100 Minor string `json:"minor"` 101 GitVersion string `json:"gitVersion"` 102 103 // Leaving major/minor int fields unexported prevents them from being set 104 // while leaving their exported counterparts untouched -> incorrect marshaled format. 105 major, minor uint64 106 } 107 108 // GetMajorInt returns the uint64 representation of vi.Major. 109 func (vi VersionInfo) GetMajorInt() uint64 { return vi.major } 110 111 // GetMinorInt returns the uint64 representation of vi.Minor. 112 func (vi VersionInfo) GetMinorInt() uint64 { return vi.minor } 113 114 func (vi *VersionInfo) parseVersionInts() (err error) { 115 if vi.Major != "" { 116 if vi.major, err = strconv.ParseUint(vi.Major, 10, 64); err != nil { 117 return err 118 } 119 } 120 if vi.Minor != "" { 121 if vi.minor, err = strconv.ParseUint(vi.Minor, 10, 64); err != nil { 122 return err 123 } 124 } 125 return nil 126 } 127 128 // KubernetesVersion holds a subset of both client and server versions. 129 type KubernetesVersion struct { 130 ClientVersion VersionInfo `json:"clientVersion,omitempty"` 131 ServerVersion VersionInfo `json:"serverVersion,omitempty"` 132 } 133 134 func (v *KubernetesVersion) prepare() error { 135 if err := v.ClientVersion.parseVersionInts(); err != nil { 136 return err 137 } 138 if err := v.ServerVersion.parseVersionInts(); err != nil { 139 return err 140 } 141 return nil 142 } 143 144 // Version is a func to run kubectl version command 145 func (k *Kubectl) Version() (ver KubernetesVersion, err error) { 146 out, err := k.Command("version", "-o", "json") 147 if err != nil { 148 return KubernetesVersion{}, err 149 } 150 if err := ver.decode(out); err != nil { 151 return KubernetesVersion{}, err 152 } 153 return ver, nil 154 } 155 156 func (v *KubernetesVersion) decode(out string) (err error) { 157 dec := json.NewDecoder(strings.NewReader(out)) 158 if err := dec.Decode(&v); err != nil { 159 return err 160 } 161 if err := v.prepare(); err != nil { 162 return err 163 } 164 return nil 165 }