Skip to content
This repository has been archived by the owner on Jul 25, 2022. It is now read-only.

gardenctl ssh for openstack node #397

Merged
merged 1 commit into from
Oct 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions pkg/cmd/openstack.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ func NewOpenstackCmd(targetReader TargetReader) *cobra.Command {
fmt.Println("Please go to https://docs.openstack.org/newton/user-guide/common/cli-install-openstack-command-line-clients.html for how to install openstack cli")
os.Exit(2)
}
arguments := "openstack " + strings.Join(args[:], " ")
operate("openstack", arguments)
arguments := strings.Join(args[:], " ")
fmt.Println(operate("openstack", arguments))

return nil
},
Expand Down
12 changes: 9 additions & 3 deletions pkg/cmd/operate.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,17 @@ func operate(provider, arguments string) string {
password := []byte(secret.Data["password"])
tenantName := []byte(secret.Data["tenantName"])
username := []byte(secret.Data["username"])
err = ExecCmd(nil, arguments, false, "OS_IDENTITY_API_VERSION=3", "OS_AUTH_VERSION=3", "OS_AUTH_STRATEGY=keystone", "OS_AUTH_URL="+authURL, "OS_TENANT_NAME="+string(tenantName[:]),
"OS_PROJECT_DOMAIN_NAME="+string(domainName[:]), "OS_USER_DOMAIN_NAME="+string(domainName[:]), "OS_USERNAME="+string(username[:]), "OS_PASSWORD="+string(password[:]), "OS_REGION_NAME="+region)

args := strings.Fields(arguments)
cmd := exec.Command("openstack", args...)
newEnv := append(os.Environ(), "OS_IDENTITY_API_VERSION=3", "OS_AUTH_VERSION=3", "OS_AUTH_STRATEGY=keystone", "OS_AUTH_URL="+authURL, "OS_TENANT_NAME="+string(tenantName[:]), "OS_PROJECT_DOMAIN_NAME="+string(domainName[:]), "OS_USER_DOMAIN_NAME="+string(domainName[:]), "OS_USERNAME="+string(username[:]), "OS_PASSWORD="+string(password[:]), "OS_REGION_NAME="+region)
cmd.Env = newEnv
out, err = cmd.CombinedOutput()
if err != nil {
os.Exit(2)
fmt.Println(err)
log.Fatalf("Openstack CLI failed with %s\n%s\n", out, err)
}

case "aliyun":
accessKeyID := []byte(secret.Data["accessKeyID"])
accessKeySecret := []byte(secret.Data["accessKeySecret"])
Expand Down
1 change: 1 addition & 0 deletions pkg/cmd/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ func NewSSHCmd(reader TargetReader, ioStreams IOStreams) *cobra.Command {
case "alicloud":
sshToAlicloudNode(args[0], path, user, pathSSKeypair, sshPublicKey, myPublicIP)
case "openstack":
sshToOpenstackNode(args[0], path, user, pathSSKeypair, sshPublicKey, myPublicIP)
default:
return fmt.Errorf("infrastructure type %q not found", infraType)
}
Expand Down
103 changes: 103 additions & 0 deletions pkg/cmd/ssh_openstack.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Copyright (c) 2018 SAP SE or an SAP affiliate company. All rights reserved. This file is licensed under the Apache Software License, v. 2 except as noted otherwise in the LICENSE file
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// SSH to openstack is performed in following steps:
// 1) get network ID of public network
// 2) create floating IP from public network
// 3) associate server node with FIP created
// 4) perform ssh
// 5) perform cleanup (de-associate FIP from server / delete FIP)
// Note: no Bastion VM is needed, no SG rule is needed
//

package cmd

import (
"fmt"
"os"
"os/exec"
"path/filepath"
"time"
)

//OpenstackInstanceAttribute stores all the critical information for creating an instance on Openstack.
type OpenstackInstanceAttribute struct {
InstanceID string
networkID string
FIP string
}

//sshToOpenstackNode ssh to openstack node
func sshToOpenstackNode(nodeName, path, user, pathSSKeypair string, sshPublicKey []byte, myPublicIP string) {
a := &OpenstackInstanceAttribute{}
a.InstanceID = nodeName
var err error

fmt.Println("(1/5) Getting the external network for creating FIP")
resNetwork := operate("openstack", "network list --external -f json")
if len(resNetwork) < 2 {
fmt.Println("External network not found!")
os.Exit(2)
}
resNetwork = resNetwork[1 : len(resNetwork)-2] // network returns with [], trim them before next step json decode
decodedQueryNetwork := decodeAndQueryFromJSONString(resNetwork)
a.networkID, err = decodedQueryNetwork.String("ID")
fmt.Println("The external network ID is " + a.networkID)
checkError(err)

fmt.Println("(2/5) Creating floating IP from external network")
resFloatingIP := operate("openstack", "floating ip create "+a.networkID+" -f json")
decodedQueryFIP := decodeAndQueryFromJSONString(resFloatingIP)
a.FIP, err = decodedQueryFIP.String("floating_ip_address")
fmt.Println("The floating IP created is " + a.FIP)
checkError(err)
time.Sleep(5000)

fmt.Println("(3/5) Add floating IP to openstack server node")
operate("openstack", "server add floating ip "+a.InstanceID+" "+a.FIP)
time.Sleep(5000)

defer a.cleanUpOpenstack()

node := user + "@" + a.FIP
fmt.Println("(4/5) Establishing SSH connection")
fmt.Println("")

key := filepath.Join(pathSSKeypair, "key")
args := []string{"-i" + key, "-oStrictHostKeyChecking=no", node}
if debugSwitch {
args = append([]string{"-vvv"}, args...)
}

cmd := exec.Command("ssh", args...)
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
fmt.Println(err)
}
}

//cleanUpOpenstack clean the resource added to ssh to openstack node
func (a *OpenstackInstanceAttribute) cleanUpOpenstack() {
fmt.Println("")
fmt.Println("(5/5) Cleanup")

fmt.Println("De-associate server with floating ip")
operate("openstack", "server remove floating ip "+a.InstanceID+" "+a.FIP)

fmt.Println("Delete the floating IP")
operate("openstack", "floating ip delete "+a.FIP)

}