Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

openstack: run test with only 1 public IP #349

Merged
merged 5 commits into from
Aug 5, 2022
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Added storage abstraction for Equinix Metal tests (SSH can be used in addition of Google Cloud Storage) ([#340](https://github.com/flatcar-linux/mantle/pull/340))
- `plume prune` support for soft-deleting AWS images and more advanced retention strategies ([#343](https://github.com/flatcar-linux/mantle/pull/343))
- Added simple wireguard test ([#348](https://github.com/flatcar-linux/mantle/pull/348))
- Added SSH proxy jump to Openstack platform ([#349](https://github.com/flatcar-linux/mantle/pull/349))

### Changed
- removed `packet` occurrences in favor of `equinixmetal` ([#277](https://github.com/flatcar-linux/mantle/pull/277))
Expand Down
3 changes: 3 additions & 0 deletions cmd/kola/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ func init() {
sv(&kola.OpenStackOptions.Network, "openstack-network", "", "OpenStack network")
sv(&kola.OpenStackOptions.Domain, "openstack-domain", "", "OpenStack domain ID")
sv(&kola.OpenStackOptions.FloatingIPPool, "openstack-floating-ip-pool", "", "OpenStack floating IP pool for Compute v2 networking")
sv(&kola.OpenStackOptions.Host, "openstack-host", "", "Host can be used to optionally SSH into deployed VMs from the OpenStack host")
sv(&kola.OpenStackOptions.User, "openstack-user", "", "User is the one used for the SSH connection to the Host")
sv(&kola.OpenStackOptions.Keyfile, "openstack-keyfile", "", "Keyfile is the absolute path to private SSH key file for the User on the Host")

// packet-specific options (kept for compatiblity but marked as deprecated)
sv(&kola.EquinixMetalOptions.ConfigPath, "packet-config-file", "", "Packet config file (default \"~/"+auth.EquinixMetalConfigPath+"\")")
Expand Down
67 changes: 67 additions & 0 deletions network/jump.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright The Mantle Authors.
// SPDX-License-Identifier: Apache-2.0
package network

import (
"fmt"
"io/ioutil"
"net"

"golang.org/x/crypto/ssh"
)

var _ Dialer = (*JumpDialer)(nil)

// JumpDialer is a RetryDialer from a proxy.
type JumpDialer struct {
RetryDialer
user string
addr string
keyfile string
}

// NewJumpDialer initializes a JumpDialer to establish a SSH Proxy Jump.
func NewJumpDialer(addr, user, keyfile string) *JumpDialer {
return &JumpDialer{
RetryDialer: RetryDialer{
Dialer: &net.Dialer{
Timeout: DefaultTimeout,
KeepAlive: DefaultKeepAlive,
},
Retries: DefaultRetries,
},
user: user,
addr: addr,
keyfile: keyfile,
}
}

// Dial connects to a remote address, retrying on failure.
func (d *JumpDialer) Dial(network, address string) (c net.Conn, err error) {
key, err := ioutil.ReadFile(d.keyfile)
if err != nil {
return nil, fmt.Errorf("reading private key: %w", err)
}

signer, err := ssh.ParsePrivateKey(key)
if err != nil {
return nil, fmt.Errorf("parsing private key: %w", err)
}

cfg := &ssh.ClientConfig{
User: d.user,
// this is only used for testing - it's ok to live with that.
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
},
}

addr := ensurePortSuffix(d.addr, defaultPort)
client, err := ssh.Dial("tcp", addr, cfg)
if err != nil {
return nil, fmt.Errorf("creating SSH client: %w", err)
}

return client.Dial(network, address)
}
6 changes: 6 additions & 0 deletions platform/api/openstack/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ type Options struct {
Domain string
// Floating IP Pool
FloatingIPPool string
// Host can be used to optionally SSH into deployed VMs from the OpenStack host
Host string
// User is the one used for the SSH connection to the Host
User string
// Keyfile is the abs. path to private SSH key file for the User on the Host
Keyfile string
}

type Server struct {
Expand Down
26 changes: 23 additions & 3 deletions platform/machine/openstack/flight.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
package openstack

import (
"fmt"

"github.com/coreos/pkg/capnslog"
ctplatform "github.com/flatcar-linux/container-linux-config-transpiler/config/platform"

"github.com/flatcar-linux/mantle/network"
"github.com/flatcar-linux/mantle/platform"
"github.com/flatcar-linux/mantle/platform/api/openstack"
)
Expand All @@ -44,9 +47,26 @@ func NewFlight(opts *openstack.Options) (platform.Flight, error) {
return nil, err
}

bf, err := platform.NewBaseFlight(opts.Options, Platform, ctplatform.OpenStackMetadata)
if err != nil {
return nil, err
var bf *platform.BaseFlight

if opts.Host != "" {
if opts.User == "" || opts.Keyfile == "" {
return nil, fmt.Errorf("--openstack-user and --openstack-keyfile can't be empty when using --openstack-host")
}

bf, err = platform.NewBaseFlightWithDialer(opts.Options, Platform, ctplatform.OpenStackMetadata, network.NewJumpDialer(opts.Host, opts.User, opts.Keyfile))
if err != nil {
return nil, fmt.Errorf("creating base flight with jump dialer: %w", err)
}
} else {
if opts.User == "" || opts.Keyfile == "" {
plog.Info("--openstack-user and/or --openstack-keyfile are provided but ignored")
}

bf, err = platform.NewBaseFlight(opts.Options, Platform, ctplatform.OpenStackMetadata)
if err != nil {
return nil, err
}
}

of := &flight{
Expand Down
32 changes: 30 additions & 2 deletions platform/machine/openstack/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,37 @@ func (om *machine) ID() string {
func (om *machine) IP() string {
if om.mach.FloatingIP != nil {
return om.mach.FloatingIP.IP
} else {
return om.mach.Server.AccessIPv4
}

// we try to get the IPv4 address.
for _, addrs := range om.mach.Server.Addresses {
addrs, ok := addrs.([]interface{})
if !ok {
continue
}

for _, addr := range addrs {
a, ok := addr.(map[string]interface{})
if !ok {
continue
}

iptype, ok := a["OS-EXT-IPS:type"].(string)
if !ok || iptype != "fixed" {
continue
}

version, ok := a["version"].(float64)
if !ok || version != 4 {
continue
}

if ip, ok := a["addr"].(string); ok {
return ip
}
}
}
return ""
}

func (om *machine) PrivateIP() string {
Expand Down