openstack

package
v0.1.15 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 5, 2024 License: Apache-2.0 Imports: 45 Imported by: 0

README

Unikorn OpenStack Provider

Provides a driver for OpenStack based regions.

Initial Setup

It is envisoned that an OpenStack cluster may be used for things other than the exclusive use of Unikorn, and as such it tries to respect this as much as possible. In particular we want to allow different instances of Unikorn to cohabit to support, for example, staging environments.

OpenStack Platform Configuration

Start by selecting a unique name that will be used for the deployment's name, project, and domain:

export PROJECT=unikorn-staging
export PASSWORD=$(apg -n 1 -m 24)

Create the project. While Unikorn, by necessity, runs as an admin account, we use the project to limit scope. For example while we can see all images and flavors on the system, we can filter out those not shared explicitly with the project. Likewise, we can have project specific images that aren't shared with other users on the system, this allows then to be discovered by the provider. By marking the images as community we can then use the images for deployment in other per-Kubernetes cluster projects.

PROJECT_ID=$(openstack project create ${PROJECT} -f json | jq -r .id)

Crete the user.

USER_ID=$(openstack user create --project ${PROJECT} --password ${PASSWORD} ${PROJECT} -f json | jq -r .id)

Grant any roles to the user. When a Kubernetes cluster is provisioned, it will be done using application credentials, so ensure any required application credentials as configured for the region are explicitly associated with the user here.

for role in admin member load-balancer_member; do
	openstack role add --user ${USER_ID} --project ${PROJECT_ID} ${role}
done

Create the domain. The use of project domains for projects deployed to provision Kubernetes cluster acheives a few aims. First namespace isolation. Second is a security consideration. It is dangerous, anecdotally, to have a privileged process that has the power of deletion. By limiting the scope of list operations to that of the project domain we limit our impact on other tenants on the system. A domain may also aid in simplifying operations like auditing and capacity planning.

DOMAIN_ID=$(openstack domain create ${PROJECT} -f json | jq -r .id)
Unikorn Configuration

When we create a Region of type openstack, it will require a secret that contains credentials. This can be configured as follows.

kubectl create secret generic -n unikorn uk-north-1-credentials \
	--from-literal=domain-id=${DOMAIN_ID} \
	--from-literal=user-id=${USER_ID} \
	--from-literal=password=${PASSWORD}

Finally we can create the region itself. For additional configuration options for individual OpenStack services, consult kubectl explain regions.unikorn-cloud.org for documentation.

apiVersion: unikorn-cloud.org/v1alpha1
kind: Region
metadata:
  name: uk-north-1
spec:
  provider: openstack
  openstack:
    endpoint: https://openstack.uk-north-1.unikorn-cloud.org:5000
    serviceAccountSecret:
      namespace: unikorn
      name: uk-north-1-credentials

Cleanup actions.

unset DOMAIN_ID
unset USER_ID
unset PROJECT_ID
unset PASSWORD
unset PROJECT

Documentation

Index

Constants

View Source
const (
	// ProjectIDAnnotation records the project ID created for a cluster.
	ProjectIDAnnotation = "openstack.unikorn-cloud.org/project-id"

	// Projects are randomly named to avoid clashes, so we need to add some tags
	// in order to be able to reason about who they really belong to.  It is also
	// useful to have these in place so we can spot orphaned resources and garbage
	// collect them.
	OrganizationTag = "organization"
	ProjectTag      = "project"
	ClusterTag      = "cluster"
	ClusterUUIDTag  = "clusterUUID"
)

Variables

View Source
var (
	// ErrPEMDecode is raised when the PEM decode failed for some reason.
	ErrPEMDecode = errors.New("PEM decode error")

	// ErrPEMType is raised when the encounter the wrong PEM type, e.g. PKCS#1.
	ErrPEMType = errors.New("PEM type unsupported")

	// ErrKeyType is raised when we encounter an unsupported key type.
	ErrKeyType = errors.New("key type unsupported")
)
View Source
var (
	// ErrExpression is raised at runtime when expression evaluation fails.
	ErrExpression = errors.New("expression must contain exactly one sub match that yields a number string")
)
View Source
var (
	ErrKeyUndefined = errors.New("a required key was not defined")
)
View Source
var (
	// ErrResourceNotFound is returned when a named resource cannot
	// be looked up (we have to do it ourselves) and it cannot be found.
	ErrResourceNotFound = errors.New("requested resource not found")
)

Functions

This section is empty.

Types

type ApplicationCredentialProvider

type ApplicationCredentialProvider struct {
	// contains filtered or unexported fields
}

ApplicationCredentialProvider allows use of an application credential.

func NewApplicationCredentialProvider

func NewApplicationCredentialProvider(endpoint, id, secret string) *ApplicationCredentialProvider

NewApplicationCredentialProvider creates a client that comsumes application credentials for authentication.

func (*ApplicationCredentialProvider) Client

Client implements the Provider interface.

type BlockStorageClient

type BlockStorageClient struct {
	// contains filtered or unexported fields
}

BlockStorageClient wraps the generic client because gophercloud is unsafe.

func NewBlockStorageClient

func NewBlockStorageClient(ctx context.Context, provider CredentialProvider) (*BlockStorageClient, error)

NewBlockStorageClient provides a simple one-liner to start computing.

func (*BlockStorageClient) AvailabilityZones

AvailabilityZones retrieves block storage availability zones.

type CloudsProvider

type CloudsProvider struct {
	// contains filtered or unexported fields
}

CloudsProvider cretes a client from clouds.yaml.

func NewCloudsProvider

func NewCloudsProvider(cloud string) *CloudsProvider

NewTokenProvider returns a new initialized provider.

func (*CloudsProvider) Client

Client implements the Provider interface.

type ComputeClient

type ComputeClient struct {
	// contains filtered or unexported fields
}

ComputeClient wraps the generic client because gophercloud is unsafe.

func NewComputeClient

func NewComputeClient(ctx context.Context, provider CredentialProvider, options *unikornv1.RegionOpenstackComputeSpec) (*ComputeClient, error)

NewComputeClient provides a simple one-liner to start computing.

func (*ComputeClient) AvailabilityZones

func (c *ComputeClient) AvailabilityZones(ctx context.Context) ([]availabilityzones.AvailabilityZone, error)

AvailabilityZones returns a list of availability zones.

func (*ComputeClient) CreateServerGroup

func (c *ComputeClient) CreateServerGroup(ctx context.Context, name string) (*servergroups.ServerGroup, error)

CreateServerGroup creates the named server group with the given policy and returns the result.

func (*ComputeClient) FlavorGPUs

func (c *ComputeClient) FlavorGPUs(flavor *Flavor) (GPUMeta, error)

FlavorGPUs returns metadata about GPUs, e.g. the number of GPUs. Sadly there is absolutely no way of assiging metadata to flavors without having to add those same values to your host aggregates, so we have to have knowledge of flavors built in somewhere.

func (*ComputeClient) Flavors

func (c *ComputeClient) Flavors(ctx context.Context) ([]Flavor, error)

Flavors returns a list of flavors.

func (*ComputeClient) KeyPairs

func (c *ComputeClient) KeyPairs(ctx context.Context) ([]keypairs.KeyPair, error)

KeyPairs returns a list of key pairs.

func (*ComputeClient) ListServerGroups

func (c *ComputeClient) ListServerGroups(ctx context.Context) ([]servergroups.ServerGroup, error)

ListServerGroups returns all server groups in the project.

type CreateTokenOptions

type CreateTokenOptions interface {
	// Options returns a valid set of authentication options.
	Options() *tokens.AuthOptions
}

CreateTokenOptions abstracts away how schizophrenic Openstack is with its million options and million ways to fuck it up.

type CreateTokenOptionsScopedToken

type CreateTokenOptionsScopedToken struct {
	// contains filtered or unexported fields
}

CreateTokenOptionsScopedToken is typically used to upgrade from an unscoped password passed login to a project scoped one once you have determined a valid project.

func NewCreateTokenOptionsScopedToken

func NewCreateTokenOptionsScopedToken(token, projectID string) *CreateTokenOptionsScopedToken

NewCreateTokenOptionsScopedToken returns a new instance of project scoped token options.

func (*CreateTokenOptionsScopedToken) Options

Options implements the CreateTokenOptions interface.

type CreateTokenOptionsUnscopedPassword

type CreateTokenOptionsUnscopedPassword struct {
	// contains filtered or unexported fields
}

CreateTokenOptionsUnscopedPassword is typically used when logging on to a UI when you don't know anything other than username/password.

func NewCreateTokenOptionsUnscopedPassword

func NewCreateTokenOptionsUnscopedPassword(domain, username, password string) *CreateTokenOptionsUnscopedPassword

NewCreateTokenOptionsUnscopedPassword returns a new instance of unscoped username/password options.

func (*CreateTokenOptionsUnscopedPassword) Options

Options implements the CreateTokenOptions interface.

type CredentialProvider added in v0.1.7

type CredentialProvider interface {
	// Client returns a new provider client.
	Client() (*gophercloud.ProviderClient, error)
}

CredentialProvider abstracts authentication methods.

type Flavor

type Flavor struct {
	flavors.Flavor

	ExtraSpecs map[string]string
}

Flavor defines an extended set of flavor information not included by default in gophercloud.

func ExtractFlavors

func ExtractFlavors(r pagination.Page) ([]Flavor, error)

ExtractFlavors takes raw JSON and decodes it into our custom flavour struct.

func (*Flavor) UnmarshalJSON

func (f *Flavor) UnmarshalJSON(b []byte) error

UnmarshalJSON is required because "flavors.Flavor" already defines this, and it will undergo method promotion.

type GPUMeta

type GPUMeta struct {
	// GPUs is the number of GPUs, this may be the total number
	// or physical GPUs, or a single virtual GPU.  This value
	// is what will be reported for Kubernetes scheduling.
	GPUs int
}

GPUMeta describes GPUs.

type IdentityClient

type IdentityClient struct {
	// contains filtered or unexported fields
}

IdentityClient wraps up gophercloud identity management.

func NewIdentityClient

func NewIdentityClient(ctx context.Context, provider CredentialProvider) (*IdentityClient, error)

NewIdentityClient returns a new identity client.

func (*IdentityClient) CreateApplicationCredential

func (c *IdentityClient) CreateApplicationCredential(ctx context.Context, userID, name, description string, roles []string) (*applicationcredentials.ApplicationCredential, error)

CreateApplicationCredential creates an application credential for the user.

func (*IdentityClient) CreateProject added in v0.1.7

func (c *IdentityClient) CreateProject(ctx context.Context, domainID, name string, tags []string) (*projects.Project, error)

CreateProject creates the named project.

func (*IdentityClient) CreateRoleAssignment added in v0.1.7

func (c *IdentityClient) CreateRoleAssignment(ctx context.Context, userID, projectID, roleID string) error

CreateRoleAssignment creates a role between a user and a project.

func (*IdentityClient) CreateToken

func (c *IdentityClient) CreateToken(ctx context.Context, options CreateTokenOptions) (*tokens.Token, *tokens.User, error)

CreateToken issues a new token.

func (*IdentityClient) DeleteApplicationCredential

func (c *IdentityClient) DeleteApplicationCredential(ctx context.Context, userID, id string) error

DeleteApplicationCredential deletes an application credential for the user.

func (*IdentityClient) GetUser

func (c *IdentityClient) GetUser(ctx context.Context, userID string) (*users.User, error)

GetUser returns user details.

func (*IdentityClient) ListApplicationCredentials

func (c *IdentityClient) ListApplicationCredentials(ctx context.Context, userID string) ([]applicationcredentials.ApplicationCredential, error)

ListApplicationCredentials lists application credentials for the scoped user.

func (*IdentityClient) ListAvailableProjects

func (c *IdentityClient) ListAvailableProjects(ctx context.Context) ([]projects.Project, error)

ListAvailableProjects lists projects that an authenticated (but unscoped) user can scope to.

func (*IdentityClient) ListRoles added in v0.1.7

func (c *IdentityClient) ListRoles(ctx context.Context) ([]roles.Role, error)

ListRoles grabs a set of roles that are on the provider.

type ImageClient

type ImageClient struct {
	// contains filtered or unexported fields
}

ImageClient wraps the generic client because gophercloud is unsafe.

func NewImageClient

func NewImageClient(ctx context.Context, provider CredentialProvider, options *unikornv1.RegionOpenstackImageSpec) (*ImageClient, error)

NewImageClient provides a simple one-liner to start computing.

func (*ImageClient) Images

func (c *ImageClient) Images(ctx context.Context) ([]images.Image, error)

Images returns a list of images.

type NetworkClient

type NetworkClient struct {
	// contains filtered or unexported fields
}

NetworkClient wraps the generic client because gophercloud is unsafe.

func NewNetworkClient

func NewNetworkClient(ctx context.Context, provider CredentialProvider) (*NetworkClient, error)

NewNetworkClient provides a simple one-liner to start networking.

func (*NetworkClient) ExternalNetworks

func (c *NetworkClient) ExternalNetworks(ctx context.Context) ([]networks.Network, error)

ExternalNetworks returns a list of external networks.

type PasswordProvider added in v0.1.7

type PasswordProvider struct {
	// contains filtered or unexported fields
}

PasswordProvider allows use of an application credential.

func NewPasswordProvider added in v0.1.7

func NewPasswordProvider(endpoint, userID, password, projectID string) *PasswordProvider

NewPasswordProvider creates a client that comsumes passwords for authentication.

func (*PasswordProvider) Client added in v0.1.7

Client implements the Provider interface.

type Provider

type Provider struct {
	// contains filtered or unexported fields
}

func New added in v0.1.7

func New(client client.Client, region *unikornv1.Region) *Provider

func (*Provider) ConfigureCluster added in v0.1.7

func (p *Provider) ConfigureCluster(ctx context.Context, cluster *unikornv1.KubernetesCluster) error

ConfigureCluster does any provider specific configuration for a cluster.

func (*Provider) Flavors added in v0.1.7

func (p *Provider) Flavors(ctx context.Context) (providers.FlavorList, error)

Flavors list all available flavors.

func (*Provider) Images added in v0.1.7

func (p *Provider) Images(ctx context.Context) (providers.ImageList, error)

Images lists all available images.

type TokenProvider

type TokenProvider struct {
	// contains filtered or unexported fields
}

TokenProvider creates a client from an endpoint and token.

func NewTokenProvider

func NewTokenProvider(endpoint, token string) *TokenProvider

NewTokenProvider returns a new initialized provider.

func (*TokenProvider) Client

Client implements the Provider interface.

type UnauthenticatedProvider

type UnauthenticatedProvider struct {
	// contains filtered or unexported fields
}

UnauthenticatedProvider is used for token issue.

func NewUnauthenticatedProvider

func NewUnauthenticatedProvider(endpoint string) *UnauthenticatedProvider

NewTokenProvider returns a new initialized provider.

func (*UnauthenticatedProvider) Client

Client implements the Provider interface.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL