k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/test/e2e_node/remote/gce/gcloud.go (about) 1 /* 2 Copyright 2024 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 gce 18 19 import ( 20 "encoding/json" 21 "fmt" 22 "os/exec" 23 ) 24 25 type gceImage struct { 26 CreationTimestamp string `json:"creationTimestamp"` 27 Family string `json:"family"` 28 ID string `json:"id"` 29 Name string `json:"name"` 30 } 31 32 type gceMetadata struct { 33 Fingerprint string `json:"fingerprint"` 34 Kind string `json:"kind"` 35 Items []gceMetadataItems `json:"items,omitempty"` 36 } 37 38 type gceMetadataItems struct { 39 Key string `json:"key,omitempty"` 40 Value string `json:"value,omitempty"` 41 } 42 43 type gceAccessConfigs struct { 44 Type string `json:"type"` 45 Name string `json:"name"` 46 NatIP string `json:"natIP,omitempty"` 47 } 48 49 type gceNetworkInterfaces struct { 50 AccessConfigs []gceAccessConfigs `json:"accessConfigs"` 51 } 52 53 type gceInstance struct { 54 CreationTimestamp string `json:"creationTimestamp"` 55 Description string `json:"description"` 56 Fingerprint string `json:"fingerprint"` 57 ID string `json:"id"` 58 KeyRevocationActionType string `json:"keyRevocationActionType"` 59 Kind string `json:"kind"` 60 LabelFingerprint string `json:"labelFingerprint"` 61 LastStartTimestamp string `json:"lastStartTimestamp"` 62 MachineType string `json:"machineType"` 63 Metadata gceMetadata `json:"metadata"` 64 Name string `json:"name"` 65 NetworkInterfaces []gceNetworkInterfaces `json:"networkInterfaces"` 66 Status string `json:"status"` 67 } 68 69 type projectInfo struct { 70 CommonInstanceMetadata struct { 71 Fingerprint string `json:"fingerprint"` 72 Items []struct { 73 Key string `json:"key"` 74 Value string `json:"value"` 75 } `json:"items"` 76 Kind string `json:"kind"` 77 } `json:"commonInstanceMetadata"` 78 CreationTimestamp string `json:"creationTimestamp"` 79 DefaultNetworkTier string `json:"defaultNetworkTier"` 80 DefaultServiceAccount string `json:"defaultServiceAccount"` 81 ID string `json:"id"` 82 } 83 84 func runGCPCommandWithZone(args ...string) ([]byte, error) { 85 if zone != nil && len(*zone) > 0 { 86 args = append(args, "--zone="+*zone) 87 } 88 return runGCPCommand(args...) 89 } 90 91 func runGCPCommandWithZones(args ...string) ([]byte, error) { 92 if zone != nil && len(*zone) > 0 { 93 args = append(args, "--zones="+*zone+",") 94 } 95 return runGCPCommand(args...) 96 } 97 98 func runGCPCommand(args ...string) ([]byte, error) { 99 if project != nil && len(*project) > 0 { 100 args = append(args, "--project="+*project) 101 } 102 return runGCPCommandNoProject(args...) 103 } 104 105 func runGCPCommandNoProject(args ...string) ([]byte, error) { 106 bytes, err := exec.Command("gcloud", args...).Output() 107 if err != nil { 108 var message string 109 if ee, ok := err.(*exec.ExitError); ok { 110 message = fmt.Sprintf("%v\n%v", ee, string(ee.Stderr)) 111 } else { 112 message = fmt.Sprintf("%v", err) 113 } 114 return nil, fmt.Errorf("unable to run gcloud command\n %s \n %w", message, err) 115 } 116 return bytes, nil 117 } 118 119 func getGCEInstance(host string) (*gceInstance, error) { 120 data, err := runGCPCommandWithZone("compute", "instances", "describe", host, "--format=json") 121 if err != nil { 122 return nil, fmt.Errorf("failed to describe instance in project %q: %w", *project, err) 123 } 124 125 var gceHost gceInstance 126 err = json.Unmarshal(data, &gceHost) 127 if err != nil { 128 return nil, fmt.Errorf("failed to parse instance: %w", err) 129 } 130 return &gceHost, nil 131 } 132 133 func (g *GCERunner) getSerialOutput(host string) (string, error) { 134 data, err := runGCPCommandWithZone("compute", "instances", "get-serial-port-output", "--port=1", host) 135 if err != nil { 136 return "", fmt.Errorf("failed to describe instance in project %q: %w", *project, err) 137 } 138 return string(data), nil 139 }