Permalink
Browse files

[OpenStack] Support os-client-config usage for authentication

Update Gophercloud dependencies and also bring in the 'utils'
package.  This provides support for configuring access to OpenStack
clouds as detailed in the [official
documentation](https://docs.openstack.org/os-client-config/latest/user/configuration.html).

By relying on this package we can simplify the code required to
interact with OpenStack's APIs.  Support is also provided upstream for
self-signed and insecure SSL configurations.

Tested with a public cloud running OpenStack 'Rocky', the latest release.

Signed-off-by: Nick Jones <nick@dischord.org>
  • Loading branch information...
yankcrime committed Jan 19, 2019
1 parent eb7e075 commit 1df6804d99a39599c82c8aedc584d05374204a43
Showing with 4,090 additions and 900 deletions.
  1. +2 −27 docs/platform-openstack.md
  2. +6 −42 src/cmd/linuxkit/push_openstack.go
  3. +5 −77 src/cmd/linuxkit/run_openstack.go
  4. +2 −1 src/cmd/linuxkit/vendor.conf
  5. +18 −2 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/README.md
  6. +135 −43 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/auth_options.go
  7. +30 −6 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/doc.go
  8. +1 −1 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/endpoint_search.go
  9. +61 −9 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/errors.go
  10. +62 −16 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/auth_env.go
  11. +176 −44 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/client.go
  12. +70 −2 ...inuxkit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs/doc.go
  13. +11 −9 ...it/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs/requests.go
  14. +22 −17 ...kit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/extensions/keypairs/results.go
  15. +136 −6 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/doc.go
  16. +235 −41 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/requests.go
  17. +154 −17 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/results.go
  18. +32 −0 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/flavors/urls.go
  19. +31 −6 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images/doc.go
  20. +19 −12 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images/requests.go
  21. +26 −14 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/images/results.go
  22. +114 −5 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/doc.go
  23. +178 −128 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/requests.go
  24. +122 −58 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/results.go
  25. +3 −2 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/compute/v2/servers/util.go
  26. +14 −0 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/doc.go
  27. +21 −13 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/endpoint_location.go
  28. +64 −6 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/doc.go
  29. +15 −6 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/requests.go
  30. +11 −6 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tenants/results.go
  31. +45 −4 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/doc.go
  32. +16 −12 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/requests.go
  33. +41 −26 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/identity/v2/tokens/results.go
  34. +107 −5 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/doc.go
  35. +41 −79 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/requests.go
  36. +35 −20 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/identity/v3/tokens/results.go
  37. +48 −0 ...cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/imagedata/doc.go
  38. +13 −2 ...inuxkit/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/imagedata/requests.go
  39. +10 −2 ...linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/imagedata/results.go
  40. +11 −1 ...md/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/imagedata/urls.go
  41. +60 −0 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/doc.go
  42. +150 −36 ...d/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/requests.go
  43. +40 −27 ...md/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/results.go
  44. +37 −8 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/types.go
  45. +18 −4 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/urls.go
  46. +28 −0 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/utils/base_endpoint.go
  47. +14 −17 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/openstack/utils/choose_version.go
  48. +23 −10 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/pagination/pager.go
  49. +59 −13 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/params.go
  50. +95 −15 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/provider_client.go
  51. +115 −3 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/results.go
  52. +28 −0 src/cmd/linuxkit/vendor/github.com/gophercloud/gophercloud/service_client.go
  53. +201 −0 src/cmd/linuxkit/vendor/github.com/gophercloud/utils/LICENSE
  54. +49 −0 src/cmd/linuxkit/vendor/github.com/gophercloud/utils/openstack/clientconfig/doc.go
  55. +763 −0 src/cmd/linuxkit/vendor/github.com/gophercloud/utils/openstack/clientconfig/requests.go
  56. +112 −0 src/cmd/linuxkit/vendor/github.com/gophercloud/utils/openstack/clientconfig/results.go
  57. +155 −0 src/cmd/linuxkit/vendor/github.com/gophercloud/utils/openstack/clientconfig/utils.go
@@ -11,17 +11,7 @@ Supported (tested) versions of the relevant OpenStack APIs are:

## Authentication

LinuxKit's support for OpenStack handles two ways of providing the endpoint and authentication details. You can either set the standard set of environment variables and the commands detailed below will inherit those, or you can explicitly provide them on the command-line as options to `push` and `run`. The examples below use the latter, but if you prefer the former then you'll need to set the following:

```shell
OS_USERNAME="admin"
OS_PASSWORD="xxx"
OS_TENANT_NAME="linuxkit"
OS_AUTH_URL="https://keystone.com:5000/v3"
OS_USER_DOMAIN_NAME=default
OS_CACERT=/path/to/cacert.pem
OS_INSECURE=false
```
LinuxKit's support for OpenStack includes configuring access to your cloud as detailed in the official [os-client-config](https://docs.openstack.org/os-client-config/latest/user/configuration.html) documentation.

## Push

@@ -40,32 +30,17 @@ Images generated with Moby can be uploaded into OpenStack's image service with `

```shell
./linuxkit push openstack \
-authurl=https://keystone.example.com:5000/v3 \
-username=admin \
-password=XXXXXXXXXXX \
-project=linuxkit \
-img-name=LinuxKitTest
./linuxkit.iso
```

If successful, this will return the image's UUID. If you've set your environment variables up as described above, this command can then be simplified:

```shell
./linuxkit push openstack \
-img-name "LinuxKitTest" \
~/Desktop/linuxkitmage.qcow2
```

## Run

Virtual machines can be launched using `linuxkit run openstack`. As an example:

```shell
linuxkit run openstack \
-authurl https://keystone.example.com:5000/v3 \
-username=admin \
-password=xxx \
-project=linuxkit \
-flavor=hotdog
-keyname=deadline_ed25519 \
-sec-groups=allow_ssh,nginx \
-network c5d02c5f-c625-4539-8aed-1dab3aa85a0a \
@@ -9,9 +9,10 @@ import (
"strings"

"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack"
"github.com/gophercloud/gophercloud/openstack/imageservice/v2/imagedata"
"github.com/gophercloud/gophercloud/openstack/imageservice/v2/images"
"github.com/gophercloud/utils/openstack/clientconfig"

log "github.com/sirupsen/logrus"
)

@@ -25,14 +26,7 @@ func pushOpenstack(args []string) {
fmt.Printf("Options:\n\n")
flags.PrintDefaults()
}
authurlFlag := flags.String("authurl", "", "The URL of the OpenStack identity service, i.e https://keystone.example.com:5000/v3")
imageName := flags.String("img-name", "", "A unique name for the image, if blank the filename will be used")
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")
usernameFlag := flags.String("username", "", "Username with permissions to upload image")
cacertFlag := flags.String("cacert", "", "CA certificate bundle file")
insecureFlag := flags.Bool("insecure", false, "Disable server certificate verification")

if err := flags.Parse(args); err != nil {
log.Fatal("Unable to parse args")
@@ -48,41 +42,15 @@ func pushOpenstack(args []string) {
// Check that the file both exists, and can be read
checkFile(filePath)

authurl := getStringValue(authurlVar, *authurlFlag, "")
password := getStringValue(passwordVar, *passwordFlag, "")
projectName := getStringValue(projectNameVar, *projectNameFlag, "")
userDomain := getStringValue(userDomainVar, *userDomainFlag, "")
username := getStringValue(usernameVar, *usernameFlag, "")
cacert := getStringValue(cacertVar, *cacertFlag, "")
insecure := getBoolValue(insecureVar, *insecureFlag)

authOpts := gophercloud.AuthOptions{
DomainName: userDomain,
IdentityEndpoint: authurl,
Password: password,
TenantName: projectName,
Username: username,
}

provider, err := openstack.NewClient(authOpts.IdentityEndpoint)
if err != nil {
log.Fatalf("Failed to connect to OpenStack: %s", err)
}

provider.HTTPClient, err = openstackHTTPClient(cacert, insecure)
client, err := clientconfig.NewServiceClient("image", nil)
if err != nil {
log.Fatalf("Failed to authenticate with OpenStack: %s", err)
log.Fatalf("Error connecting to your OpenStack cloud: %s", err)
}

err = openstack.Authenticate(provider, authOpts)
if err != nil {
log.Fatalf("Failed to authenticate with OpenStack: %s", err)
}

createOpenStackImage(filePath, *imageName, provider)
createOpenStackImage(filePath, *imageName, client)
}

func createOpenStackImage(filePath string, imageName string, provider *gophercloud.ProviderClient) {
func createOpenStackImage(filePath string, imageName string, client *gophercloud.ServiceClient) {
// Image formats that are supported by both LinuxKit and OpenStack Glance V2
formats := []string{"ami", "vhd", "vhdx", "vmdk", "raw", "qcow2", "iso"}

@@ -106,10 +74,6 @@ func createOpenStackImage(filePath string, imageName string, provider *gopherclo
imageName = fileName
}

client, err := openstack.NewImageServiceV2(provider, gophercloud.EndpointOpts{})
if err != nil {
log.Fatalf("Unable to create Image V2 client: %s", err)
}
imageOpts := images.CreateOpts{
Name: imageName,
ContainerFormat: "bare",
@@ -1,57 +1,23 @@
package main

import (
"crypto/tls"
"crypto/x509"
"errors"
"flag"
"fmt"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"strings"

"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"
"github.com/gophercloud/utils/openstack/clientconfig"

log "github.com/sirupsen/logrus"
)

const (
defaultOSFlavor = "m1.tiny"
authurlVar = "OS_AUTH_URL"
usernameVar = "OS_USERNAME"
passwordVar = "OS_PASSWORD"
projectNameVar = "OS_PROJECT_NAME"
userDomainVar = "OS_USER_DOMAIN_NAME"
cacertVar = "OS_CACERT"
insecureVar = "OS_INSECURE"
)

func openstackHTTPClient(cacert string, insecure bool) (http.Client, error) {
if cacert == "" {
return http.Client{}, nil
}

caCertPool := x509.NewCertPool()
caCert, err := ioutil.ReadFile(cacert)
if err != nil {
return http.Client{}, errors.New("Can't read certificate file")
}
caCertPool.AppendCertsFromPEM(caCert)

tlsConfig := &tls.Config{
RootCAs: caCertPool,
InsecureSkipVerify: insecure,
}
tlsConfig.BuildNameToCertificate()
transport := &http.Transport{TLSClientConfig: tlsConfig}

return http.Client{Transport: transport}, nil
}

func runOpenStack(args []string) {
flags := flag.NewFlagSet("openstack", flag.ExitOnError)
invoked := filepath.Base(os.Args[0])
@@ -62,18 +28,11 @@ func runOpenStack(args []string) {
fmt.Printf("Options:\n\n")
flags.PrintDefaults()
}
authurlFlag := flags.String("authurl", "", "The URL of the OpenStack identity service, i.e https://keystone.example.com:5000/v3")
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")
secGroups := flags.String("sec-groups", "", "Security Group names separated by comma")
secGroups := flags.String("sec-groups", "default", "Security Group names separated by comma")
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")
usernameFlag := flags.String("username", "", "Username with permissions to create an instance")
cacertFlag := flags.String("cacert", "", "CA certificate bundle file")
insecureFlag := flags.Bool("insecure", false, "Disable server certificate verification")

if err := flags.Parse(args); err != nil {
log.Fatal("Unable to parse args")
@@ -91,40 +50,9 @@ func runOpenStack(args []string) {
*instanceName = name
}

authurl := getStringValue(authurlVar, *authurlFlag, "")
password := getStringValue(passwordVar, *passwordFlag, "")
projectName := getStringValue(projectNameVar, *projectNameFlag, "")
userDomain := getStringValue(userDomainVar, *userDomainFlag, "")
username := getStringValue(usernameVar, *usernameFlag, "")
cacert := getStringValue(cacertVar, *cacertFlag, "")
insecure := getBoolValue(insecureVar, *insecureFlag)

authOpts := gophercloud.AuthOptions{
DomainName: userDomain,
IdentityEndpoint: authurl,
Password: password,
TenantName: projectName,
Username: username,
}

provider, err := openstack.NewClient(authOpts.IdentityEndpoint)
if err != nil {
log.Fatalf("Failed to connect to OpenStack: %s", err)
}

provider.HTTPClient, err = openstackHTTPClient(cacert, insecure)
if err != nil {
log.Fatalf("Failed to authenticate with OpenStack: %s", err)
}

err = openstack.Authenticate(provider, authOpts)
if err != nil {
log.Fatalf("Failed to authenticate with OpenStack: %s", err)
}

client, err := openstack.NewComputeV2(provider, gophercloud.EndpointOpts{})
client, err := clientconfig.NewServiceClient("compute", nil)
if err != nil {
log.Fatalf("Unable to create Compute V2 client, %s", err)
log.Fatalf("Unable to create Compute client, %s", err)
}

network := servers.Network{
@@ -25,7 +25,8 @@ github.com/gogo/protobuf v1.0.0
github.com/golang/protobuf v1.1.0
github.com/google/uuid 7e072fc3a7be179aee6d3359e46015aa8c995314
github.com/googleapis/gax-go 8c5154c0fe5bf18cf649634d4c6df50897a32751
github.com/gophercloud/gophercloud 2804b72cf099b41d2e25c8afcca786f9f962ddee
github.com/gophercloud/gophercloud b9ea9cb68cf5803ea1567c404b549a783c8264b2
github.com/gophercloud/utils 34f5991525d116b3832e0d9409492274f1c06bda
github.com/gorilla/context v1.1
github.com/gorilla/mux v1.1
github.com/gorilla/websocket 21ab95fa12b9bdd8fecf5fa3586aad941cc98785

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.
Oops, something went wrong.

0 comments on commit 1df6804

Please sign in to comment.