mirror of
https://github.com/linuxkit/linuxkit.git
synced 2025-07-19 17:26:28 +00:00
[OpenStack] Support specifying an SSH key name when creating an instance
This commit introduces a new option - `keyname` - to the OpenStack runner, which allows the user to specify the name of a keypair they want to associate with the instance at the time of creation. Signed-off-by: Nick Jones <nick@dischord.org>
This commit is contained in:
parent
0968be802f
commit
0556812b63
@ -1,6 +1,6 @@
|
||||
# LinuxKit with OpenStack
|
||||
|
||||
LinuxKit interacts with OpenStack through its native APIs and requires access and provides basic support for pushing images and launching virtual instances.
|
||||
LinuxKit interacts with OpenStack through its native APIs, providing basic support for pushing images and launching virtual instances.
|
||||
|
||||
Supported (tested) versions of the relevant OpenStack APIs are:
|
||||
|
||||
@ -64,6 +64,7 @@ linuxkit run openstack \
|
||||
-username=admin \
|
||||
-password=xxx \
|
||||
-project=linuxkit \
|
||||
-keyname=deadline_ed25519 \
|
||||
-network c5d02c5f-c625-4539-8aed-1dab3aa85a0a \
|
||||
LinuxKitTest
|
||||
```
|
||||
|
@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/openstack"
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs"
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
@ -35,6 +36,7 @@ func runOpenStack(args []string) {
|
||||
flavorName := flags.String("flavor", defaultOSFlavor, "Instance size (flavor)")
|
||||
instanceName := flags.String("instancename", "", "Name of instance. Defaults to the name of the image if not specified")
|
||||
networkID := flags.String("network", "", "The ID of the network to attach the instance to")
|
||||
keyName := flags.String("keyname", "", "The name of the SSH keypair to associate with the instance")
|
||||
passwordFlag := flags.String("password", "", "Password for the specified username")
|
||||
projectNameFlag := flags.String("project", "", "Name of the Project (aka Tenant) to be used")
|
||||
userDomainFlag := flags.String("domain", "Default", "Domain name")
|
||||
@ -83,7 +85,9 @@ func runOpenStack(args []string) {
|
||||
UUID: *networkID,
|
||||
}
|
||||
|
||||
serverOpts := &servers.CreateOpts{
|
||||
var serverOpts servers.CreateOptsBuilder
|
||||
|
||||
serverOpts = &servers.CreateOpts{
|
||||
FlavorName: *flavorName,
|
||||
ImageName: name,
|
||||
Name: *instanceName,
|
||||
@ -91,6 +95,13 @@ func runOpenStack(args []string) {
|
||||
ServiceClient: client,
|
||||
}
|
||||
|
||||
if *keyName != "" {
|
||||
serverOpts = &keypairs.CreateOptsExt{
|
||||
CreateOptsBuilder: serverOpts,
|
||||
KeyName: *keyName,
|
||||
}
|
||||
}
|
||||
|
||||
server, err := servers.Create(client, serverOpts).Extract()
|
||||
if err != nil {
|
||||
log.Fatalf("Unable to create server: %s", err)
|
||||
|
3
src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs/doc.go
generated
vendored
Normal file
3
src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs/doc.go
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
// Package keypairs provides information and interaction with the Keypairs
|
||||
// extension for the OpenStack Compute service.
|
||||
package keypairs
|
84
src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs/requests.go
generated
vendored
Normal file
84
src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs/requests.go
generated
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
package keypairs
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// CreateOptsExt adds a KeyPair option to the base CreateOpts.
|
||||
type CreateOptsExt struct {
|
||||
servers.CreateOptsBuilder
|
||||
KeyName string `json:"key_name,omitempty"`
|
||||
}
|
||||
|
||||
// ToServerCreateMap adds the key_name and, optionally, key_data options to
|
||||
// the base server creation options.
|
||||
func (opts CreateOptsExt) ToServerCreateMap() (map[string]interface{}, error) {
|
||||
base, err := opts.CreateOptsBuilder.ToServerCreateMap()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if opts.KeyName == "" {
|
||||
return base, nil
|
||||
}
|
||||
|
||||
serverMap := base["server"].(map[string]interface{})
|
||||
serverMap["key_name"] = opts.KeyName
|
||||
|
||||
return base, nil
|
||||
}
|
||||
|
||||
// List returns a Pager that allows you to iterate over a collection of KeyPairs.
|
||||
func List(client *gophercloud.ServiceClient) pagination.Pager {
|
||||
return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page {
|
||||
return KeyPairPage{pagination.SinglePageBase(r)}
|
||||
})
|
||||
}
|
||||
|
||||
// CreateOptsBuilder describes struct types that can be accepted by the Create call. Notable, the
|
||||
// CreateOpts struct in this package does.
|
||||
type CreateOptsBuilder interface {
|
||||
ToKeyPairCreateMap() (map[string]interface{}, error)
|
||||
}
|
||||
|
||||
// CreateOpts specifies keypair creation or import parameters.
|
||||
type CreateOpts struct {
|
||||
// Name is a friendly name to refer to this KeyPair in other services.
|
||||
Name string `json:"name" required:"true"`
|
||||
// PublicKey [optional] is a pregenerated OpenSSH-formatted public key. If provided, this key
|
||||
// will be imported and no new key will be created.
|
||||
PublicKey string `json:"public_key,omitempty"`
|
||||
}
|
||||
|
||||
// ToKeyPairCreateMap constructs a request body from CreateOpts.
|
||||
func (opts CreateOpts) ToKeyPairCreateMap() (map[string]interface{}, error) {
|
||||
return gophercloud.BuildRequestBody(opts, "keypair")
|
||||
}
|
||||
|
||||
// Create requests the creation of a new keypair on the server, or to import a pre-existing
|
||||
// keypair.
|
||||
func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) {
|
||||
b, err := opts.ToKeyPairCreateMap()
|
||||
if err != nil {
|
||||
r.Err = err
|
||||
return
|
||||
}
|
||||
_, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{
|
||||
OkCodes: []int{200},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Get returns public data about a previously uploaded KeyPair.
|
||||
func Get(client *gophercloud.ServiceClient, name string) (r GetResult) {
|
||||
_, r.Err = client.Get(getURL(client, name), &r.Body, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete requests the deletion of a previous stored KeyPair from the server.
|
||||
func Delete(client *gophercloud.ServiceClient, name string) (r DeleteResult) {
|
||||
_, r.Err = client.Delete(deleteURL(client, name), nil)
|
||||
return
|
||||
}
|
86
src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs/results.go
generated
vendored
Normal file
86
src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs/results.go
generated
vendored
Normal file
@ -0,0 +1,86 @@
|
||||
package keypairs
|
||||
|
||||
import (
|
||||
"github.com/gophercloud/gophercloud"
|
||||
"github.com/gophercloud/gophercloud/pagination"
|
||||
)
|
||||
|
||||
// KeyPair is an SSH key known to the OpenStack Cloud that is available to be injected into
|
||||
// servers.
|
||||
type KeyPair struct {
|
||||
// Name is used to refer to this keypair from other services within this region.
|
||||
Name string `json:"name"`
|
||||
|
||||
// Fingerprint is a short sequence of bytes that can be used to authenticate or validate a longer
|
||||
// public key.
|
||||
Fingerprint string `json:"fingerprint"`
|
||||
|
||||
// PublicKey is the public key from this pair, in OpenSSH format. "ssh-rsa AAAAB3Nz..."
|
||||
PublicKey string `json:"public_key"`
|
||||
|
||||
// PrivateKey is the private key from this pair, in PEM format.
|
||||
// "-----BEGIN RSA PRIVATE KEY-----\nMIICXA..." It is only present if this keypair was just
|
||||
// returned from a Create call
|
||||
PrivateKey string `json:"private_key"`
|
||||
|
||||
// UserID is the user who owns this keypair.
|
||||
UserID string `json:"user_id"`
|
||||
}
|
||||
|
||||
// KeyPairPage stores a single, only page of KeyPair results from a List call.
|
||||
type KeyPairPage struct {
|
||||
pagination.SinglePageBase
|
||||
}
|
||||
|
||||
// IsEmpty determines whether or not a KeyPairPage is empty.
|
||||
func (page KeyPairPage) IsEmpty() (bool, error) {
|
||||
ks, err := ExtractKeyPairs(page)
|
||||
return len(ks) == 0, err
|
||||
}
|
||||
|
||||
// ExtractKeyPairs interprets a page of results as a slice of KeyPairs.
|
||||
func ExtractKeyPairs(r pagination.Page) ([]KeyPair, error) {
|
||||
type pair struct {
|
||||
KeyPair KeyPair `json:"keypair"`
|
||||
}
|
||||
var s struct {
|
||||
KeyPairs []pair `json:"keypairs"`
|
||||
}
|
||||
err := (r.(KeyPairPage)).ExtractInto(&s)
|
||||
results := make([]KeyPair, len(s.KeyPairs))
|
||||
for i, pair := range s.KeyPairs {
|
||||
results[i] = pair.KeyPair
|
||||
}
|
||||
return results, err
|
||||
}
|
||||
|
||||
type keyPairResult struct {
|
||||
gophercloud.Result
|
||||
}
|
||||
|
||||
// Extract is a method that attempts to interpret any KeyPair resource response as a KeyPair struct.
|
||||
func (r keyPairResult) Extract() (*KeyPair, error) {
|
||||
var s struct {
|
||||
KeyPair *KeyPair `json:"keypair"`
|
||||
}
|
||||
err := r.ExtractInto(&s)
|
||||
return s.KeyPair, err
|
||||
}
|
||||
|
||||
// CreateResult is the response from a Create operation. Call its Extract method to interpret it
|
||||
// as a KeyPair.
|
||||
type CreateResult struct {
|
||||
keyPairResult
|
||||
}
|
||||
|
||||
// GetResult is the response from a Get operation. Call its Extract method to interpret it
|
||||
// as a KeyPair.
|
||||
type GetResult struct {
|
||||
keyPairResult
|
||||
}
|
||||
|
||||
// DeleteResult is the response from a Delete operation. Call its Extract method to determine if
|
||||
// the call succeeded or failed.
|
||||
type DeleteResult struct {
|
||||
gophercloud.ErrResult
|
||||
}
|
25
src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs/urls.go
generated
vendored
Normal file
25
src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs/urls.go
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
package keypairs
|
||||
|
||||
import "github.com/gophercloud/gophercloud"
|
||||
|
||||
const resourcePath = "os-keypairs"
|
||||
|
||||
func resourceURL(c *gophercloud.ServiceClient) string {
|
||||
return c.ServiceURL(resourcePath)
|
||||
}
|
||||
|
||||
func listURL(c *gophercloud.ServiceClient) string {
|
||||
return resourceURL(c)
|
||||
}
|
||||
|
||||
func createURL(c *gophercloud.ServiceClient) string {
|
||||
return resourceURL(c)
|
||||
}
|
||||
|
||||
func getURL(c *gophercloud.ServiceClient, name string) string {
|
||||
return c.ServiceURL(resourcePath, name)
|
||||
}
|
||||
|
||||
func deleteURL(c *gophercloud.ServiceClient, name string) string {
|
||||
return getURL(c, name)
|
||||
}
|
Loading…
Reference in New Issue
Block a user