openstack

package
v1.16.6 Latest Latest
Warning

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

Go to latest
Published: May 11, 2026 License: Apache-2.0 Imports: 74 Imported by: 0

README

pkg/providers/internal/openstack

Intention

pkg/providers/internal/openstack is the real cloud provider implementation for OpenStack-backed regions.

It does not merely wrap the OpenStack SDK. It is the package that translates the region service's storage model, tenancy model, metadata conventions, and lifecycle rules into concrete OpenStack operations across identity, compute, image, network, security group, load balancer, quota, and block storage surfaces.

The most important philosophy in this package is the trust and scoping model:

  • region-level manager authority is used only to provision and manage users and projects inside a managed Keystone domain
  • once that scaffolding exists, most OpenStack operations deliberately context switch into the specific project provisioned for one Unikorn identity
  • that OpenStack project then becomes the practical mapping, isolation, and accounting boundary between Unikorn resources and real cloud resources

That model is what makes it realistic for multiple regions or deployments to share one underlying cloud while still limiting blast radius. It is also what makes backchannel accounting and billing integration plausible, because the project scope becomes the place where cloud resource usage can be tied back to a specific Unikorn identity and its descendants.

The most important architectural rule is that this package prefers deterministic lookup against OpenStack over maintaining broad mirrored OpenStack state in Kubernetes. In older designs, dedicated Openstack* CRDs were used to persist more provider-side state locally. That drifted from reality and introduced race conditions. The current direction is:

  • service-native CRDs remain the primary control objects
  • OpenStack remains the source of truth for cloud-side resources where they can be re-found deterministically
  • only the provider state that still cannot be reconstructed safely or sufficiently remains persisted locally, most notably OpenstackIdentity

This package therefore owns the mapping between:

  • region-native CRDs and OpenStack resources
  • service labels, tags, and metadata conventions
  • per-identity delegated cloud credentials
  • compensating local mechanisms where OpenStack is not sufficient on its own, such as image caching and provider-network VLAN allocation

pkg/apis/unikorn/v1alpha1 defines the service-native resources and the remaining persisted provider-state records this package consumes. pkg/providers/types defines the provider-neutral contract this package implements. pkg/providers/allocation/vlan covers the local VLAN allocator used when provider networks need segmentation IDs. ADMIN.md keeps the human operator setup guidance for preparing an OpenStack region.

Invariants And Guard Rails

  • This package implements the full types.Provider contract for OpenStack regions.
  • Provider construction has an explicit bootstrap/runtime split:
    • bootstrap uses uncached Kubernetes reads to assemble OpenStack service clients before controller-manager caches exist
    • runtime operation switches back to the normal Kubernetes client and refreshes derived OpenStack client state when region configuration or credentials change
  • OpenStack access is intentionally scoped through different credential modes:
    • region-level service credentials bootstrap privileged service clients and managed-domain scaffolding
    • per-identity credentials are used for most project-scoped operations
    • some operations deliberately bind privileged credentials to a service principal's project when manager-level powers are required
  • OpenstackIdentity is the remaining persisted provider-state anchor. It currently stores the secret-bearing user/project/application-credential and bootstrap state needed to operate on behalf of a region Identity.
  • The package relies heavily on deterministic naming and metadata conventions to re-find cloud-side resources. This is a convention-heavy contract, not magic:
    • identity-scoped resources use fixed generated names
    • network lookups rely on deterministic names
    • server metadata is written deliberately as both a control-plane lookup aid and an in-guest linkage surface exposed through the metadata service
    • legacy camelCase server metadata keys remain frozen for backwards compatibility while newer namespaced keys provide the upgrade path
  • Flavor export is a hybrid model: OpenStack discovers the flavor inventory, but region configuration can enrich or override user-facing flavor metadata such as architecture, baremetal status, and GPU semantics.
  • Image handling is a first-class contract surface here:
    • OpenStack image properties are validated against a schema
    • public images can additionally be signature-verified
    • image properties are translated into provider-neutral OS, package, GPU, ownership, virtualization, and tag metadata
    • an optional refresh-ahead cache exists because raw image API latency is too expensive to expose directly to every caller
  • Quota and role behaviour are not purely discovered from OpenStack defaults. The package assumes and applies a managed-role model, including default role names such as manager, member, and load-balancer_member, unless region configuration overrides parts of that behaviour.
  • Network, security group, and server resources are re-found in OpenStack by deterministic lookup rather than relying on mirrored OpenstackNetwork, OpenstackSecurityGroup, or OpenstackServer CRDs as authoritative state.
  • Some OpenStack list APIs are not safe to treat as exact lookup, notably server, network, and Octavia load-balancer name filters:
    • name filters behave like prefix or regular-expression matches rather than strict equality
    • this package therefore re-checks exact names after listing to avoid aliasing and false matches
  • Provider networks that require VLAN segmentation use the local VLAN allocator because OpenStack does not allocate those IDs for us.

Octavia Load Balancers

OpenStack load balancers are reconciled through Octavia in the service principal's project. The region LoadBalancer CRD is still the desired-state root, while Octavia remains the cloud-side source of truth for the realized topology.

The provider reconciles the full topology:

  • the Octavia load balancer and VIP
  • listeners, pools, members, and optional health monitors
  • the optional public floating IP attached to the Octavia-owned VIP port

Cloud-side lookup uses deterministic names:

  • load balancer: lb-{loadBalancer}
  • listener: lb-{loadBalancer}-{listener}-listener
  • pool: lb-{loadBalancer}-{listener}-pool
  • health monitor: lb-{loadBalancer}-{listener}-monitor

Those names are not just cosmetic. They are the linkage contract that lets the provider re-find and converge existing Octavia resources without mirrored provider-state CRDs. Octavia list filters are fuzzy in the same way as other OpenStack name filters, so the client always post-filters returned resources by exact name and treats duplicate exact matches as consistency errors.

Octavia provisioning status controls the reconcile outcome:

  • ACTIVE allows the provider to continue reconciling the next part of the topology
  • PENDING_CREATE, PENDING_UPDATE, and PENDING_DELETE yield the controller so the next pass can observe settled state
  • any other state is treated as a consistency error because the provider cannot safely infer a valid next action

Mutable topology is converged in place where Octavia permits it:

  • listener allowed CIDRs
  • listener default-pool linkage
  • TCP listener idle timeouts
  • pool members
  • health-monitor thresholds
  • orphaned listeners, pools, and monitors whose deterministic names are no longer implied by the current spec

Other fields are intentionally blocked before they reach this provider. The handler keeps existing listener protocol and port immutable, and it blocks proxyProtocolV2 drift for an existing listener name because that changes the derived Octavia pool protocol, which Octavia does not allow to be updated in place.

There are a few Octavia-specific constraints worth preserving:

  • UDP listeners do not support idle timeouts or Proxy Protocol v2.
  • UDP health checks use Octavia's UDP connect monitor type.
  • TCP pools use Octavia PROXYV2 only when proxyProtocolV2 is enabled; the load-balancer client pins microversion 2.22 so that protocol is available.
  • Floating IP cleanup runs before cascade-deleting the load balancer because the cascade removes the VIP port that otherwise anchors the floating IP lookup.

Caveats

  • This package is the convergence point of a large amount of platform policy, provider behaviour, and historical baggage. Its size reflects real behaviour, not just poor code hygiene.
  • Deterministic lookup is the preferred direction, but the package still lives in a mixed world:
    • some cloud-side state is derived live from OpenStack
    • some transitional compatibility fields still exist in repo-native CRDs
    • OpenstackIdentity still persists state that the service would ideally stop owning over time
  • Deterministic lookup is cleaner than mirrored CRDs, but it is still sensitive to convention drift. Renaming generated resources, changing metadata keys, or casually altering project-scoping assumptions can break the linkage between Unikorn resources, what OpenStack stores, and what users can see from inside provisioned servers.
  • OpenstackIdentity should not be treated as permanently special. Its current survival is largely driven by implicit side effects and secret-bearing service-owned state that the architecture should work to remove:
    • ephemeral SSH key generation and download
    • implicit server-group creation
    • persisted service-principal/user/project/application-credential data
  • Exposing application credentials to higher layers is current operational reality, not the desired end state. The package's scoping model helps contain blast radius today, while the wider platform works toward removing that exposure entirely.
  • If the wider API moves toward explicit SSH certificate authority use, explicit server-group resources, and less implicit provider-side identity scaffolding, deleting OpenstackIdentity becomes more realistic.
  • Image metadata translation is powerful but fragile. This package currently depends on OpenStack image properties carrying a large amount of semantic information correctly.
  • Image query, get, create, delete, and snapshot flows are tightly coupled to the image cache path. When caching is disabled, large parts of the higher image contract are effectively unavailable rather than merely slower.
  • The image query layer still contains its own comment admitting that some logic now operates on generic types and probably should not live here long term.
  • Some older assumptions still leak through in status fields and helper paths, especially where compatibility with older API or storage shapes is still being carried.

TODO

  • Delete the remaining mirror-state OpenStack CRD usage paths entirely: OpenstackNetwork, OpenstackSecurityGroup, and OpenstackServer should not survive as authoritative provider-state patterns.
  • Continue shrinking the reasons OpenstackIdentity must exist:
    • remove service-handled private SSH key material in favour of explicit SSH certificate trust
    • stop relying on implicit server-group provisioning
    • move toward explicit API shapes where reconstructable state does not need to be persisted here
  • Revisit image-query and image-metadata logic that now operates on provider-neutral types but still lives in this package because of historical coupling.
  • Remove remaining compatibility writes and reads that depend on transitional CRD status shapes as those fields disappear from the wider system.

Cross-Package Context

  • ../../types defines the neutral provider contract and intermediate types this package must satisfy
  • ../../../apis/unikorn/v1alpha1 defines the service-native control objects and the remaining persisted provider-state records this package consumes
  • ../../../handler and specific handler packages depend on this package to make region API operations real against OpenStack
  • ../allocation/vlan exists because this package needs a compensating local allocator for provider-network VLAN IDs

Documentation

Index

Constants

View Source
const (
	// 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"
)

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")
)

Functions

func ImageSchema

func ImageSchema() (*jsonschema.Schema, error)

func ImageSchemaValid

func ImageSchemaValid(image *images.Image, schema *jsonschema.Schema) bool

func ImageSignatureValid

func ImageSignatureValid(image *images.Image, signingKeyRaw []byte) bool

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.

func (*BlockStorageClient) UpdateQuotas

func (c *BlockStorageClient) UpdateQuotas(ctx context.Context, projectID string) error

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) CreateImageFromServer added in v1.13.0

func (c *ComputeClient) CreateImageFromServer(ctx context.Context, id string, opts *servers.CreateImageOpts) (string, error)

func (*ComputeClient) CreateKeypair

func (c *ComputeClient) CreateKeypair(ctx context.Context, name, publicKey string) error

CreateKeypair creates a new keypair. NOTE: while OpenStack can generate one for us, we have far more control doing it ourselves thus allowing us to impose stricter security, and it's more provider agnostic that way.

func (*ComputeClient) CreateRemoteConsole

func (c *ComputeClient) CreateRemoteConsole(ctx context.Context, id string) (*remoteconsoles.RemoteConsole, error)

func (*ComputeClient) CreateServer

func (c *ComputeClient) CreateServer(ctx context.Context, server *unikornv1.Server, keyName string, networks []servers.Network, serverGroupID *string, metadata map[string]string) (*servers.Server, error)

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) DeleteKeypair

func (c *ComputeClient) DeleteKeypair(ctx context.Context, name string) error

func (*ComputeClient) DeleteServer

func (c *ComputeClient) DeleteServer(ctx context.Context, id string) error

func (*ComputeClient) DeleteServerGroup

func (c *ComputeClient) DeleteServerGroup(ctx context.Context, id string) error

DeleteServerGroup removes a server group, this exists because nova does do any cleanup on project deletion and just orphans the resource.

func (*ComputeClient) GetFlavors

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

Flavors returns a list of flavors.

func (*ComputeClient) GetServer

func (c *ComputeClient) GetServer(ctx context.Context, server *unikornv1.Server) (*servers.Server, error)

func (*ComputeClient) RebootServer

func (c *ComputeClient) RebootServer(ctx context.Context, id string, hard bool) error

func (*ComputeClient) ShowConsoleOutput

func (c *ComputeClient) ShowConsoleOutput(ctx context.Context, id string, length *int) (string, error)

func (*ComputeClient) StartServer

func (c *ComputeClient) StartServer(ctx context.Context, id string) error

func (*ComputeClient) StopServer

func (c *ComputeClient) StopServer(ctx context.Context, id string) error

func (*ComputeClient) UpdateQuotas

func (c *ComputeClient) UpdateQuotas(ctx context.Context, projectID string) error

type ComputeQuotaInterface

type ComputeQuotaInterface interface {
	UpdateQuotas(ctx context.Context, projectID string) error
}

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

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

CredentialProvider abstracts authentication methods.

type DomainScopedPasswordProvider

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

DomainScopedPasswordProvider allows use of an application credential.

func NewDomainScopedPasswordProvider

func NewDomainScopedPasswordProvider(endpoint, userID, password, domainID string) *DomainScopedPasswordProvider

NewDomainScopedPasswordProvider creates a client that consumes passwords for authentication.

func (*DomainScopedPasswordProvider) Client

Client implements the Provider interface.

type ExternalNetworkInterface added in v1.13.0

type ExternalNetworkInterface interface {
	ExternalNetworks(ctx context.Context) ([]networks.Network, error)
}

type FlavorInterface

type FlavorInterface interface {
	GetFlavors(ctx context.Context) ([]flavors.Flavor, error)
}

type FloatingIPInterface

type FloatingIPInterface interface {
	GetFloatingIP(ctx context.Context, portID string) (*floatingips.FloatingIP, error)
	CreateFloatingIP(ctx context.Context, portID string) (*floatingips.FloatingIP, error)
	DeleteFloatingIP(ctx context.Context, id string) error
}

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

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

CreateProject creates the named project.

func (*IdentityClient) CreateRoleAssignment

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) CreateUser

func (c *IdentityClient) CreateUser(ctx context.Context, domainID, name, password string) (*users.User, error)

CreateUser creates a new user.

func (*IdentityClient) DeleteApplicationCredential

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

DeleteApplicationCredential deletes an application credential for the user.

func (*IdentityClient) DeleteProject

func (c *IdentityClient) DeleteProject(ctx context.Context, projectID string) error

func (*IdentityClient) DeleteUser

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

DeleteUser removes an existing user.

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

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) CreateImage added in v1.12.0

func (c *ImageClient) CreateImage(ctx context.Context, opts *images.CreateOpts) (*images.Image, error)

CreateImage creates a new image.

func (*ImageClient) DeleteImage added in v1.12.0

func (c *ImageClient) DeleteImage(ctx context.Context, id string) error

func (*ImageClient) GetImage

func (c *ImageClient) GetImage(ctx context.Context, id string) (*images.Image, error)

GetImage retrieves a specific image by its ID.

func (*ImageClient) Import added in v1.13.0

func (c *ImageClient) Import(ctx context.Context, id, uri string) error

func (*ImageClient) ListImages

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

ListImages returns a list of images.

func (*ImageClient) UpdateImage added in v1.12.0

func (c *ImageClient) UpdateImage(ctx context.Context, id string, opts images.UpdateOpts) (*images.Image, error)

type KeypairInterface

type KeypairInterface interface {
	CreateKeypair(ctx context.Context, name, publicKey string) error
	DeleteKeypair(ctx context.Context, name string) error
}

type LoadBalancerClient added in v1.16.5

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

LoadBalancerClient wraps the generic client because gophercloud is unsafe.

func NewLoadBalancerClient added in v1.16.5

func NewLoadBalancerClient(ctx context.Context, provider CredentialProvider) (*LoadBalancerClient, error)

NewLoadBalancerClient creates an Octavia v2 client.

func (*LoadBalancerClient) BatchUpdateMembers added in v1.16.5

func (c *LoadBalancerClient) BatchUpdateMembers(ctx context.Context, poolID string, opts []pools.BatchUpdateMemberOpts) error

func (*LoadBalancerClient) CreateListener added in v1.16.5

func (*LoadBalancerClient) CreateLoadBalancer added in v1.16.5

func (*LoadBalancerClient) CreateMonitor added in v1.16.5

func (*LoadBalancerClient) CreatePool added in v1.16.5

func (*LoadBalancerClient) DeleteListener added in v1.16.5

func (c *LoadBalancerClient) DeleteListener(ctx context.Context, id string) error

func (*LoadBalancerClient) DeleteLoadBalancer added in v1.16.5

func (c *LoadBalancerClient) DeleteLoadBalancer(ctx context.Context, id string, cascade bool) error

func (*LoadBalancerClient) DeleteMonitor added in v1.16.5

func (c *LoadBalancerClient) DeleteMonitor(ctx context.Context, id string) error

func (*LoadBalancerClient) DeletePool added in v1.16.5

func (c *LoadBalancerClient) DeletePool(ctx context.Context, id string) error

func (*LoadBalancerClient) GetListener added in v1.16.5

func (c *LoadBalancerClient) GetListener(ctx context.Context, loadBalancerID string, loadBalancer *unikornv1.LoadBalancer, listener *unikornv1.LoadBalancerListener) (*listeners.Listener, error)

func (*LoadBalancerClient) GetLoadBalancer added in v1.16.5

func (c *LoadBalancerClient) GetLoadBalancer(ctx context.Context, loadBalancer *unikornv1.LoadBalancer) (*loadbalancers.LoadBalancer, error)

func (*LoadBalancerClient) GetMonitor added in v1.16.5

func (c *LoadBalancerClient) GetMonitor(ctx context.Context, poolID string, loadBalancer *unikornv1.LoadBalancer, listener *unikornv1.LoadBalancerListener) (*monitors.Monitor, error)

func (*LoadBalancerClient) GetPool added in v1.16.5

func (c *LoadBalancerClient) GetPool(ctx context.Context, loadBalancerID string, loadBalancer *unikornv1.LoadBalancer, listener *unikornv1.LoadBalancerListener) (*pools.Pool, error)

func (*LoadBalancerClient) ListListeners added in v1.16.5

func (c *LoadBalancerClient) ListListeners(ctx context.Context, loadBalancerID, name string) ([]listeners.Listener, error)

func (*LoadBalancerClient) ListLoadBalancers added in v1.16.5

func (c *LoadBalancerClient) ListLoadBalancers(ctx context.Context, name string) ([]loadbalancers.LoadBalancer, error)

func (*LoadBalancerClient) ListMembers added in v1.16.5

func (c *LoadBalancerClient) ListMembers(ctx context.Context, poolID string) ([]pools.Member, error)

func (*LoadBalancerClient) ListMonitors added in v1.16.5

func (c *LoadBalancerClient) ListMonitors(ctx context.Context, poolID, name string) ([]monitors.Monitor, error)

func (*LoadBalancerClient) ListPools added in v1.16.5

func (c *LoadBalancerClient) ListPools(ctx context.Context, loadBalancerID, name string) ([]pools.Pool, error)

func (*LoadBalancerClient) UpdateListener added in v1.16.5

func (*LoadBalancerClient) UpdateLoadBalancer added in v1.16.5

func (*LoadBalancerClient) UpdateMonitor added in v1.16.5

func (*LoadBalancerClient) UpdatePool added in v1.16.5

func (c *LoadBalancerClient) UpdatePool(ctx context.Context, id string, opts pools.UpdateOptsBuilder) (*pools.Pool, error)

type LoadBalancerInterface added in v1.16.5

type LoadBalancerInterface interface {
	ListLoadBalancers(ctx context.Context, name string) ([]loadbalancers.LoadBalancer, error)
	GetLoadBalancer(ctx context.Context, loadBalancer *unikornv1.LoadBalancer) (*loadbalancers.LoadBalancer, error)
	CreateLoadBalancer(ctx context.Context, opts loadbalancers.CreateOptsBuilder) (*loadbalancers.LoadBalancer, error)
	UpdateLoadBalancer(ctx context.Context, id string, opts loadbalancers.UpdateOptsBuilder) (*loadbalancers.LoadBalancer, error)
	DeleteLoadBalancer(ctx context.Context, id string, cascade bool) error
}

type LoadBalancerListenerInterface added in v1.16.5

type LoadBalancerListenerInterface interface {
	ListListeners(ctx context.Context, loadBalancerID, name string) ([]listeners.Listener, error)
	GetListener(ctx context.Context, loadBalancerID string, loadBalancer *unikornv1.LoadBalancer, listener *unikornv1.LoadBalancerListener) (*listeners.Listener, error)
	CreateListener(ctx context.Context, opts listeners.CreateOptsBuilder) (*listeners.Listener, error)
	UpdateListener(ctx context.Context, id string, opts listeners.UpdateOptsBuilder) (*listeners.Listener, error)
	DeleteListener(ctx context.Context, id string) error
}

type LoadBalancerMemberInterface added in v1.16.5

type LoadBalancerMemberInterface interface {
	ListMembers(ctx context.Context, poolID string) ([]pools.Member, error)
	BatchUpdateMembers(ctx context.Context, poolID string, opts []pools.BatchUpdateMemberOpts) error
}

type LoadBalancerMonitorInterface added in v1.16.5

type LoadBalancerMonitorInterface interface {
	ListMonitors(ctx context.Context, poolID, name string) ([]monitors.Monitor, error)
	GetMonitor(ctx context.Context, poolID string, loadBalancer *unikornv1.LoadBalancer, listener *unikornv1.LoadBalancerListener) (*monitors.Monitor, error)
	CreateMonitor(ctx context.Context, opts monitors.CreateOptsBuilder) (*monitors.Monitor, error)
	UpdateMonitor(ctx context.Context, id string, opts monitors.UpdateOptsBuilder) (*monitors.Monitor, error)
	DeleteMonitor(ctx context.Context, id string) error
}

type LoadBalancerPoolInterface added in v1.16.5

type LoadBalancerPoolInterface interface {
	ListPools(ctx context.Context, loadBalancerID, name string) ([]pools.Pool, error)
	GetPool(ctx context.Context, loadBalancerID string, loadBalancer *unikornv1.LoadBalancer, listener *unikornv1.LoadBalancerListener) (*pools.Pool, error)
	CreatePool(ctx context.Context, opts pools.CreateOptsBuilder) (*pools.Pool, error)
	UpdatePool(ctx context.Context, id string, opts pools.UpdateOptsBuilder) (*pools.Pool, error)
	DeletePool(ctx context.Context, id string) error
}

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, options *unikornv1.RegionOpenstackNetworkSpec) (*NetworkClient, error)

NewNetworkClient provides a simple one-liner to start networking.

func NewTestNetworkClient

func NewTestNetworkClient(options *unikornv1.RegionOpenstackNetworkSpec) *NetworkClient

func (*NetworkClient) AddRouterInterface

func (c *NetworkClient) AddRouterInterface(ctx context.Context, routerID, subnetID string) error

func (*NetworkClient) CreateFloatingIP

func (c *NetworkClient) CreateFloatingIP(ctx context.Context, portID string) (*floatingips.FloatingIP, error)

CreateFloatingIP creates a floating IP.

func (*NetworkClient) CreateNetwork

func (c *NetworkClient) CreateNetwork(ctx context.Context, network *unikornv1.Network, vlanID *int) (*NetworkExt, error)

CreateNetwork creates a virtual or VLAN provider network for a project. This requires https://github.com/unikorn-cloud/python-unikorn-openstack-policy to be installed, see the README for further details on how this has to work.

func (*NetworkClient) CreateRouter

func (c *NetworkClient) CreateRouter(ctx context.Context, network *unikornv1.Network) (*routers.Router, error)

func (*NetworkClient) CreateSecurityGroup

func (c *NetworkClient) CreateSecurityGroup(ctx context.Context, securityGroup *unikornv1.SecurityGroup) (*groups.SecGroup, error)

CreateSecurityGroup creates a new security group.

func (*NetworkClient) CreateSecurityGroupRule

func (c *NetworkClient) CreateSecurityGroupRule(ctx context.Context, securityGroupID string, direction rules.RuleDirection, protocol rules.RuleProtocol, portStart, portEnd int, prefix string) (*rules.SecGroupRule, error)

CreateSecurityGroupRule adds a security group rule to a security group.

func (*NetworkClient) CreateServerPort

func (c *NetworkClient) CreateServerPort(ctx context.Context, server *unikornv1.Server, networkID string, securityGroupIDs []string, allowedAddressPairs []ports.AddressPair) (*ports.Port, error)

func (*NetworkClient) CreateSubnet

func (c *NetworkClient) CreateSubnet(ctx context.Context, network *unikornv1.Network, networkID, prefix, gatewayIP string, dnsNameservers []string, routes []subnets.HostRoute, allocationPools []subnets.AllocationPool) (*subnets.Subnet, error)

func (*NetworkClient) DeleteFloatingIP

func (c *NetworkClient) DeleteFloatingIP(ctx context.Context, id string) error

DeleteFloatingIP deletes a floating IP.

func (*NetworkClient) DeleteNetwork

func (c *NetworkClient) DeleteNetwork(ctx context.Context, id string) error

func (*NetworkClient) DeletePort

func (c *NetworkClient) DeletePort(ctx context.Context, portID string) error

func (*NetworkClient) DeleteRouter

func (c *NetworkClient) DeleteRouter(ctx context.Context, id string) error

func (*NetworkClient) DeleteSecurityGroup

func (c *NetworkClient) DeleteSecurityGroup(ctx context.Context, securityGroupID string) error

DeleteSecurityGroup deletes a security group.

func (*NetworkClient) DeleteSecurityGroupRule

func (c *NetworkClient) DeleteSecurityGroupRule(ctx context.Context, securityGroupID, ruleID string) error

DeleteSecurityGroupRule deletes a security group rule from a security group.

func (*NetworkClient) DeleteSubnet

func (c *NetworkClient) DeleteSubnet(ctx context.Context, id string) error

func (*NetworkClient) ExternalNetworks

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

ExternalNetworks returns a list of external networks.

func (*NetworkClient) GetFloatingIP

func (c *NetworkClient) GetFloatingIP(ctx context.Context, portID string) (*floatingips.FloatingIP, error)

func (*NetworkClient) GetNetwork

func (c *NetworkClient) GetNetwork(ctx context.Context, network *unikornv1.Network) (*NetworkExt, error)

func (*NetworkClient) GetRouter

func (c *NetworkClient) GetRouter(ctx context.Context, network *unikornv1.Network) (*routers.Router, error)

func (*NetworkClient) GetSecurityGroup

func (c *NetworkClient) GetSecurityGroup(ctx context.Context, securityGroup *unikornv1.SecurityGroup) (*groups.SecGroup, error)

func (*NetworkClient) GetServerPort

func (c *NetworkClient) GetServerPort(ctx context.Context, server *unikornv1.Server) (*ports.Port, error)

func (*NetworkClient) GetSubnet

func (c *NetworkClient) GetSubnet(ctx context.Context, network *unikornv1.Network) (*subnets.Subnet, error)

func (*NetworkClient) ListRouterPorts

func (c *NetworkClient) ListRouterPorts(ctx context.Context, routerID string) ([]ports.Port, error)

func (*NetworkClient) ListSecurityGroupRules

func (c *NetworkClient) ListSecurityGroupRules(ctx context.Context, securityGroupID string) ([]rules.SecGroupRule, error)

ListSecurityGroupRules does exactly that.

func (*NetworkClient) ListServerPorts

func (c *NetworkClient) ListServerPorts(ctx context.Context, serverID string) ([]ports.Port, error)

ListServerPorts returns a list of ports for a server.

func (*NetworkClient) RemoveRouterInterface

func (c *NetworkClient) RemoveRouterInterface(ctx context.Context, routerID, subnetID string) error

func (*NetworkClient) UpdatePort

func (c *NetworkClient) UpdatePort(ctx context.Context, portID string, securityGroupIDs []string, allowedAddressPairs []ports.AddressPair) (*ports.Port, error)

func (*NetworkClient) UpdateQuotas added in v1.13.2

func (c *NetworkClient) UpdateQuotas(ctx context.Context, projectID string) error

Update quotas overrides any OpenStack default quotas for the project's networking. At present it's only security groups, security group rules and floating IPs that are affected.

func (*NetworkClient) UpdateSubnet

func (c *NetworkClient) UpdateSubnet(ctx context.Context, subnetID string, dnsNameservers []string, routes []subnets.HostRoute) (*subnets.Subnet, error)

type NetworkExt

type NetworkExt struct {
	networks.Network
	provider.NetworkProviderExt
}

type NetworkInterface

type NetworkInterface interface {
	GetNetwork(ctx context.Context, network *unikornv1.Network) (*NetworkExt, error)
	CreateNetwork(ctx context.Context, network *unikornv1.Network, vlanID *int) (*NetworkExt, error)
	DeleteNetwork(ctx context.Context, id string) error
}

type Options added in v1.16.0

type Options struct {
	// WarmImageCache enables startup-time image cache initialization.
	WarmImageCache bool
}

type PasswordProvider

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

PasswordProvider allows use of an application credential.

func NewPasswordProvider

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

NewPasswordProvider creates a client that comsumes passwords for authentication.

func (*PasswordProvider) Client

Client implements the Provider interface.

type PortInterface

type PortInterface interface {
	ListServerPorts(ctx context.Context, serverID string) ([]ports.Port, error)
	ListRouterPorts(ctx context.Context, routerID string) ([]ports.Port, error)
	GetServerPort(ctx context.Context, server *unikornv1.Server) (*ports.Port, error)
	CreateServerPort(ctx context.Context, server *unikornv1.Server, networkID string, securityGroupIDs []string, allowedAddressPairs []ports.AddressPair) (*ports.Port, error)
	UpdatePort(ctx context.Context, portID string, securityGroupIDs []string, allowedAddressPairs []ports.AddressPair) (*ports.Port, error)
	DeletePort(ctx context.Context, portID string) error
}

type Provider

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

func New

func New(ctx context.Context, initClient client.Client, runtimeClient client.Client, region *unikornv1.Region, opts Options) (*Provider, error)

New constructs an OpenStack provider.

Provider construction has two phases: 1. Bootstrap service-client state with initClient before any controller cache exists. 2. Return a provider that retains runtimeClient for all subsequent Kubernetes reads.

This makes the bootstrap/runtime boundary explicit: direct reads are used only while building the initial OpenStack client state, and normal provider operation switches back to the runtime client immediately afterwards.

func (*Provider) CreateConsoleSession

func (p *Provider) CreateConsoleSession(ctx context.Context, identity *unikornv1.Identity, server *unikornv1.Server) (string, error)

func (*Provider) CreateIdentity

func (p *Provider) CreateIdentity(ctx context.Context, identity *unikornv1.Identity) error

CreateIdentity creates a new identity for cloud infrastructure.

func (*Provider) CreateImage added in v1.13.0

func (p *Provider) CreateImage(ctx context.Context, image *types.Image, uri string) (*types.Image, error)

CreateImage creates a new image.

func (*Provider) CreateLoadBalancer added in v1.16.1

func (p *Provider) CreateLoadBalancer(ctx context.Context, identity *unikornv1.Identity, loadBalancer *unikornv1.LoadBalancer) error

CreateLoadBalancer reconciles the full Octavia topology — load balancer, listeners, pools, members, and health monitors — for the given spec. It yields between PENDING transitions and surfaces VIP mismatches and other terminal Octavia states as ErrConsistency.

func (*Provider) CreateNetwork

func (p *Provider) CreateNetwork(ctx context.Context, identity *unikornv1.Identity, network *unikornv1.Network) error

CreateNetwork creates a physical network for an identity.

func (*Provider) CreateSecurityGroup

func (p *Provider) CreateSecurityGroup(ctx context.Context, identity *unikornv1.Identity, securityGroup *unikornv1.SecurityGroup) error

CreateSecurityGroup creates a new security group.

func (*Provider) CreateServer

func (p *Provider) CreateServer(ctx context.Context, identity *unikornv1.Identity, server *unikornv1.Server, options *types.ServerCreateOptions) error

func (*Provider) CreateSnapshot added in v1.13.0

func (p *Provider) CreateSnapshot(ctx context.Context, identity *unikornv1.Identity, server *unikornv1.Server, image *types.Image) (*types.Image, error)

CreateSnapshot creates a new image from an existing server.

func (*Provider) DeleteIdentity

func (p *Provider) DeleteIdentity(ctx context.Context, identity *unikornv1.Identity) error

DeleteIdentity cleans up an identity for cloud infrastructure.

func (*Provider) DeleteImage added in v1.12.0

func (p *Provider) DeleteImage(ctx context.Context, imageID string) error

func (*Provider) DeleteLoadBalancer added in v1.16.1

func (p *Provider) DeleteLoadBalancer(ctx context.Context, identity *unikornv1.Identity, loadBalancer *unikornv1.LoadBalancer) error

DeleteLoadBalancer removes the Octavia topology and any attached floating IP idempotently. It yields while Octavia is in any PENDING_* state and after issuing a cascade delete so the next reconcile can confirm completion.

func (*Provider) DeleteNetwork

func (p *Provider) DeleteNetwork(ctx context.Context, identity *unikornv1.Identity, network *unikornv1.Network) error

DeleteNetwork deletes a physical network.

func (*Provider) DeleteSecurityGroup

func (p *Provider) DeleteSecurityGroup(ctx context.Context, identity *unikornv1.Identity, securityGroup *unikornv1.SecurityGroup) error

DeleteSecurityGroup deletes a security group.

func (*Provider) DeleteServer

func (p *Provider) DeleteServer(ctx context.Context, identity *unikornv1.Identity, server *unikornv1.Server) error

func (*Provider) Flavors

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

Flavors list all available flavors.

func (*Provider) GetConsoleOutput

func (p *Provider) GetConsoleOutput(ctx context.Context, identity *unikornv1.Identity, server *unikornv1.Server, length *int) (string, error)

func (*Provider) GetImage

func (p *Provider) GetImage(ctx context.Context, organizationID, imageID string) (*types.Image, error)

GetImage retrieves a specific image by its ID.

func (*Provider) GetOpenstackIdentity

func (p *Provider) GetOpenstackIdentity(ctx context.Context, identity *unikornv1.Identity) (*unikornv1.OpenstackIdentity, error)

func (*Provider) GetOrCreateOpenstackIdentity

func (p *Provider) GetOrCreateOpenstackIdentity(ctx context.Context, identity *unikornv1.Identity) (*unikornv1.OpenstackIdentity, bool, error)

func (*Provider) Kind added in v1.15.0

func (p *Provider) Kind() unikornv1.Provider

Kind returns the provider kind.

func (*Provider) ListExternalNetworks

func (p *Provider) ListExternalNetworks(ctx context.Context) (types.ExternalNetworks, error)

ListExternalNetworks returns a list of external networks if the platform supports such a concept.

func (*Provider) QueryImages added in v1.14.0

func (p *Provider) QueryImages() (types.ImageQuery, error)

func (*Provider) RebootServer

func (p *Provider) RebootServer(ctx context.Context, identity *unikornv1.Identity, server *unikornv1.Server, hard bool) error

func (*Provider) Region

func (p *Provider) Region(ctx context.Context) (*unikornv1.Region, error)

Region returns the provider's region.

func (*Provider) StartServer

func (p *Provider) StartServer(ctx context.Context, identity *unikornv1.Identity, server *unikornv1.Server) error

func (*Provider) StopServer

func (p *Provider) StopServer(ctx context.Context, identity *unikornv1.Identity, server *unikornv1.Server) error

func (*Provider) UpdateServerState

func (p *Provider) UpdateServerState(ctx context.Context, identity *unikornv1.Identity, server *unikornv1.Server) error

UpdateServerState checks a server's state and modifies the resource in place.

type RouterInterface

type RouterInterface interface {
	GetRouter(ctx context.Context, network *unikornv1.Network) (*routers.Router, error)
	CreateRouter(ctx context.Context, network *unikornv1.Network) (*routers.Router, error)
	DeleteRouter(ctx context.Context, id string) error

	AddRouterInterface(ctx context.Context, routerID, subnetID string) error
	RemoveRouterInterface(ctx context.Context, routerID, subnetID string) error
}

type SecurityGroupInterface

type SecurityGroupInterface interface {
	GetSecurityGroup(ctx context.Context, securityGroup *unikornv1.SecurityGroup) (*groups.SecGroup, error)
	CreateSecurityGroup(ctx context.Context, securityGroup *unikornv1.SecurityGroup) (*groups.SecGroup, error)
	DeleteSecurityGroup(ctx context.Context, securityGroupID string) error
	ListSecurityGroupRules(ctx context.Context, securityGroupID string) ([]rules.SecGroupRule, error)
	CreateSecurityGroupRule(ctx context.Context, securityGroupID string, direction rules.RuleDirection, protocol rules.RuleProtocol, portStart, portEnd int, prefix string) (*rules.SecGroupRule, error)
	DeleteSecurityGroupRule(ctx context.Context, securityGroupID, ruleID string) error
}

type ServerGroupInterface

type ServerGroupInterface interface {
	CreateServerGroup(ctx context.Context, name string) (*servergroups.ServerGroup, error)
	DeleteServerGroup(ctx context.Context, id string) error
}

type ServerInterface

type ServerInterface interface {
	GetServer(ctx context.Context, server *unikornv1.Server) (*servers.Server, error)
	CreateServer(ctx context.Context, server *unikornv1.Server, keyName string, networks []servers.Network, serverGroupID *string, metadata map[string]string) (*servers.Server, error)
	DeleteServer(ctx context.Context, id string) error
	RebootServer(ctx context.Context, id string, hard bool) error
	StartServer(ctx context.Context, id string) error
	StopServer(ctx context.Context, id string) error
	CreateRemoteConsole(ctx context.Context, id string) (*remoteconsoles.RemoteConsole, error)
	ShowConsoleOutput(ctx context.Context, id string, length *int) (string, error)
	CreateImageFromServer(ctx context.Context, id string, opts *servers.CreateImageOpts) (string, error)
}

type SubnetInterface

type SubnetInterface interface {
	GetSubnet(ctx context.Context, network *unikornv1.Network) (*subnets.Subnet, error)
	CreateSubnet(ctx context.Context, network *unikornv1.Network, networkID string, prefix, gatewayID string, dnsNameservers []string, routes []subnets.HostRoute, allocationPools []subnets.AllocationPool) (*subnets.Subnet, error)
	UpdateSubnet(ctx context.Context, subnetID string, dnsNameservers []string, routes []subnets.HostRoute) (*subnets.Subnet, error)
	DeleteSubnet(ctx context.Context, id string) error
}

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

NewUnauthenticatedProvider returns a new initialized provider.

func (*UnauthenticatedProvider) Client

Client implements the Provider interface.

Directories

Path Synopsis
Code generated by MockGen.
Code generated by MockGen.

Jump to

Keyboard shortcuts

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