caas

package
v0.0.0-...-3d086f3 Latest Latest
Warning

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

Go to latest
Published: Apr 18, 2024 License: AGPL-3.0 Imports: 22 Imported by: 21

Documentation

Index

Constants

View Source
const (
	// JujuExternalHostNameKey specifies the hostname of a CAAS application.
	JujuExternalHostNameKey = "juju-external-hostname"

	// JujuApplicationPath specifies the relative http path used to access a CAAS application.
	JujuApplicationPath = "juju-application-path"

	// JujuDefaultApplicationPath is the default value for juju-application-path.
	JujuDefaultApplicationPath = "/"
)
View Source
const (
	// OperatorInfoFile is the file which contains certificate information for
	// the operator.
	OperatorInfoFile = "operator.yaml"

	// OperatorClientInfoFile is the file containing info about the operator,
	// copied to the workload pod so the hook tools and juju-exec can function.
	OperatorClientInfoFile = "operator-client.yaml"

	// OperatorClientInfoCacheFile is a cache of OperatorClientInfoFile stored on the operator.
	OperatorClientInfoCacheFile = "operator-client-cache.yaml"

	// CACertFile is the file containing the cluster CA.
	CACertFile = "ca.crt"

	// InitContainerName is the name of the init container on workloads pods.
	InitContainerName = "juju-pod-init"
)

Variables

View Source
var (
	// JujudStartUpSh is the start script for K8s controller and operator style agents.
	JujudStartUpSh = `
export JUJU_DATA_DIR=%[1]s
export JUJU_TOOLS_DIR=$JUJU_DATA_DIR/%[2]s

mkdir -p $JUJU_TOOLS_DIR
cp /opt/jujud $JUJU_TOOLS_DIR/jujud

%[3]s
`[1:]

	// JujudStartUpAltSh is the start script for K8s operator style agents.
	JujudStartUpAltSh = `
export JUJU_DATA_DIR=%[1]s
export JUJU_TOOLS_DIR=$JUJU_DATA_DIR/%[2]s

mkdir -p $JUJU_TOOLS_DIR
cp %[3]s/jujud $JUJU_TOOLS_DIR/jujud

%[4]s
`[1:]

	// MongoStartupShTemplate is used to generate the start script for mongodb.
	// Mongo is very specific about what permissions the shared secret must have,
	// so we must copy it and lock it down for rootless k8s controllers.
	// NOTE: 170 uid/gid must be updated here and in caas/kubernetes/provider/constants/constants.go
	MongoStartupShTemplate = `
args="%[1]s"
ipv6Disabled=$(sysctl net.ipv6.conf.all.disable_ipv6 -n)
if [ $ipv6Disabled -eq 0 ]; then
  args="${args} --ipv6"
fi
SHARED_SECRET_SRC="%[2]s"
SHARED_SECRET_DST="%[3]s"
rm "${SHARED_SECRET_DST}" || true
cp "${SHARED_SECRET_SRC}" "${SHARED_SECRET_DST}"
chown 170:170 "${SHARED_SECRET_DST}"
chmod 600 "${SHARED_SECRET_DST}"
ls -lah "${SHARED_SECRET_DST}"
while [ ! -f "%[4]s" ]; do
  echo "Waiting for %[4]s to be created..."
  sleep 1
done
exec mongod ${args}
`[1:]

	// JujudCopySh is the start script for K8s operator style agents.
	JujudCopySh = `
cp /opt/jujud %[1]s/jujud

%[2]s
`[1:]

	// APIServerStartUpSh is the start script for the "api-server" container
	// in the controller pod (Pebble running jujud).
	APIServerStartUpSh = `
export JUJU_DATA_DIR=%[1]s
export JUJU_TOOLS_DIR=$JUJU_DATA_DIR/tools

mkdir -p $JUJU_TOOLS_DIR
cp /opt/jujud $JUJU_TOOLS_DIR/jujud

%[2]s

mkdir -p /var/lib/pebble/default/layers
cat > /var/lib/pebble/default/layers/001-jujud.yaml <<EOF
%[3]s
EOF

exec /opt/pebble run --http :%[4]s --verbose
`[1:]
)

Functions

func ConfigDefaults

func ConfigDefaults(providerDefaults schema.Defaults) schema.Defaults

ConfigDefaults returns the default values for a CAAS application config.

func ConfigSchema

func ConfigSchema(providerFields environschema.Fields) (environschema.Fields, error)

ConfigSchema returns the valid fields for a CAAS application config.

func RegisterContainerProvider

func RegisterContainerProvider(name string, p ContainerEnvironProvider, alias ...string) (unregister func())

RegisterContainerProvider is used for providers that we want to use for managing 'instances', but are not possible sources for 'juju bootstrap'.

Types

type Application

type Application interface {
	Ensure(config ApplicationConfig) error
	Exists() (DeploymentState, error)
	Delete() error
	Watch() (watcher.NotifyWatcher, error)
	WatchReplicas() (watcher.NotifyWatcher, error)

	// ApplicationPodSpec returns the pod spec needed to run the application workload.
	ApplicationPodSpec(config ApplicationConfig) (*core.PodSpec, error)

	// Scale scales the Application's unit to the value specified. Scale must
	// be >= 0. Application units will be removed or added to meet the scale
	// defined.
	Scale(int) error

	// Trust sets up the role on the application's service account to
	// give full access to the cluster.
	Trust(bool) error

	State() (ApplicationState, error)

	// Units of the application fetched from kubernetes by matching pod labels.
	Units() ([]Unit, error)

	UnitsToRemove(context.Context, int) ([]string, error)

	// Service returns the service associated with the application.
	Service() (*Service, error)

	ServiceInterface
}

Application is for interacting with the CAAS substrate.

type ApplicationBroker

type ApplicationBroker interface {
	// Application returns the broker interface for an Application
	Application(string, DeploymentType) Application

	// WatchUnits returns a watcher which notifies when there
	// are changes to units of the specified application.
	WatchUnits(appName string, mode DeploymentMode) (watcher.NotifyWatcher, error)

	// Units returns all units and any associated filesystems
	// of the specified application. Filesystems are mounted
	// via volumes bound to the unit.
	Units(appName string, mode DeploymentMode) ([]Unit, error)

	// AnnotateUnit annotates the specified pod (name or uid) with a unit tag.
	AnnotateUnit(appName string, mode DeploymentMode, podName string, unit names.UnitTag) error

	// WatchContainerStart returns a watcher which is notified when the specified container
	// for each unit in the application is starting/restarting. Each string represents
	// the provider id for the unit. If containerName is empty, then the first workload container
	// is used.
	WatchContainerStart(appName string, containerName string) (watcher.StringsWatcher, error)
}

ApplicationBroker provides an API for accessing the broker interface for individual applications and watching their units.

type ApplicationConfig

type ApplicationConfig struct {
	// AgentVersion is the Juju version of the agent image.
	AgentVersion version.Number

	// AgentImagePath is the docker registry URL for the charm container.
	AgentImagePath string

	// CharmBaseImagePath is the docker registry URL for the workload containers to run pebble.
	CharmBaseImagePath string

	// IsPrivateImageRepo indicates if the images repositories are private or not.
	// If they are, we need to set the image pull secret.
	IsPrivateImageRepo bool

	// CharmModifiedVersion is a monotonically incrementing version number
	// that represents the version of the charm and resources with regards to
	// this application. The CAAS provider will pass this to the uniter worker
	// to ensure the container infrastructure matches the charm.
	CharmModifiedVersion int

	// Containers is the list of containers that make up the container (excluding uniter and init containers).
	Containers map[string]ContainerConfig

	// ExistingContainers is a list of names for containers which will be added
	// to the application pod spec outside the ApplicationPodSpec method.
	// These containers will be added to the JUJU_CONTAINER_NAMES env variable
	// in the charm container, but we will not create new container specs for
	// them, as they are assumed to already exist.
	ExistingContainers []string

	// IntroductionSecret
	IntroductionSecret string
	// ControllerAddresses is a comma separated list of controller addresses.
	// TODO: Use model-operator service instead for introduction, so controller addresses can change
	// without having to update deployed application.
	ControllerAddresses string
	// ControllerCertBundle is a PEM cert bundle for talking to the Juju controller.
	ControllerCertBundle string

	// ResourceTags is a set of tags to set on the operator pod.
	ResourceTags map[string]string

	// Constraints is a set of constraints on
	// the pod to create.
	Constraints constraints.Value

	// Filesystems is a set of parameters for filesystems that should be created.
	Filesystems []storage.KubernetesFilesystemParams

	// Devices is a set of parameters for Devices that is required.
	Devices []devices.KubernetesDeviceParams

	// Trust is set to true to give the application cloud access.
	Trust bool

	// InitialScale is used to provide the initial desired scale of the application.
	// After the application is created, InitialScale has no effect.
	InitialScale int

	// CharmUser controls what user the charm/unit agent runs as.
	CharmUser RunAs
}

ApplicationConfig is the config passed to the application units.

type ApplicationOperatorManager

type ApplicationOperatorManager interface {
	// Application returns the broker interface for an Application.
	Application(string, DeploymentType) Application

	// OperatorExists indicates if the operator for the specified
	// application exists, and whether the operator is terminating.
	OperatorExists(appName string) (DeploymentState, error)

	// EnsureOperator creates or updates an operator pod for running
	// a charm for the specified application.
	EnsureOperator(appName, agentPath string, config *OperatorConfig) error

	// DeleteOperator deletes the specified operator.
	DeleteOperator(appName string) error

	// Operator returns an Operator with current status and life details.
	Operator(string) (*Operator, error)

	// WatchOperator returns a watcher which notifies when there
	// are changes to the operator of the specified application.
	WatchOperator(string) (watcher.NotifyWatcher, error)

	// WatchService returns a watcher which notifies when there
	// are changes to the deployment of the specified application.
	WatchService(appName string, mode DeploymentMode) (watcher.NotifyWatcher, error)
}

ApplicationOperatorManager provides an API for deploying operators for individual applications.

type ApplicationState

type ApplicationState struct {
	DesiredReplicas int
	Replicas        []string
}

ApplicationState represents the application state.

type Broker

type Broker interface {
	// Provider returns the ContainerEnvironProvider that created this Broker.
	Provider() ContainerEnvironProvider

	// InstancePrechecker provides a means of "prechecking" placement
	// arguments before recording them in state.
	environs.InstancePrechecker

	// BootstrapEnviron defines methods for bootstrapping a controller.
	environs.BootstrapEnviron

	// ResourceAdopter defines methods for adopting resources.
	environs.ResourceAdopter

	// StorageValidator provides methods to validate storage.
	StorageValidator

	// Upgrader provides the API to perform upgrades.
	Upgrader

	// APIVersion returns the version of the container orchestration layer.
	APIVersion() (string, error)

	// GetSecretToken returns the token content for the specified secret name.
	GetSecretToken(name string) (string, error)

	// ClusterVersionGetter provides methods to get cluster version information.
	ClusterVersionGetter

	// CredentialChecker provides an API for checking that the credentials
	// used by the broker are functioning.
	CredentialChecker

	// ApplicationBroker provides an API for accessing the broker interface
	// for individual applications and watching their units.
	ApplicationBroker

	// ServiceManager provides an API for creating and watching services.
	ServiceManager

	// SecretsProvider provides an API for accessing the broker interface for managing secret k8s provider resources.
	SecretsProvider

	// SecretsBackend provides an API for managing Juju secrets.
	SecretsBackend

	// ModelOperatorManager provides an API for deploying operators for
	// individual models.
	ModelOperatorManager

	// ApplicationOperatorManager provides an API for deploying operators
	// for individual applications.
	ApplicationOperatorManager

	// EnsureImageRepoSecret ensures the image pull secret gets created.
	EnsureImageRepoSecret(docker.ImageRepoDetails) error

	// ProxyManager provides methods for managing application proxy connections.
	ProxyManager
}

Broker instances interact with the CAAS substrate.

func New

func New(ctx context.Context, args environs.OpenParams) (Broker, error)

New returns a new broker based on the provided configuration.

func Open

Open creates a Broker instance and errors if the provider is not for a container substrate.

type CharmStorageParams

type CharmStorageParams struct {
	// Size is the minimum size of the filesystem in MiB.
	Size uint64

	// The provider type for this filesystem.
	Provider storage.ProviderType

	// Attributes is a set of provider-specific options for storage creation,
	// as defined in a storage pool.
	Attributes map[string]interface{}

	// ResourceTags is a set of tags to set on the created filesystem, if the
	// storage provider supports tags.
	ResourceTags map[string]string
}

CharmStorageParams defines parameters used to create storage for operators to use for charm state.

type ClusterVersionGetter

type ClusterVersionGetter interface {
	// Version returns cluster version information.
	Version() (*version.Number, error)
}

ClusterVersionGetter provides methods to get cluster version information.

type ContainerConfig

type ContainerConfig struct {
	// Name of the container.
	Name string

	// Image used to create the container.
	Image resources.DockerImageDetails

	// Mounts to storage that are to be provided within this container.
	Mounts []MountConfig

	// Uid to run as. Default to 0 or root.
	Uid int

	// Gid to run as. Default to 0 or root.
	Gid int
}

ContainerConfig describes a container that is deployed alonside the uniter/charm container.

type ContainerEnvironProvider

type ContainerEnvironProvider interface {
	environs.EnvironProvider

	// Open opens the broker and returns it. The configuration must
	// have passed through PrepareConfig at some point in its lifecycle.
	//
	// Open should not perform any expensive operations, such as querying
	// the cloud API, as it will be called frequently.
	Open(args environs.OpenParams) (Broker, error)
}

ContainerEnvironProvider represents a computing and storage provider for a container runtime.

type CredentialChecker

type CredentialChecker interface {
	// CheckCloudCredentials verifies that the provided cloud credentials
	// are still valid for the cloud.
	CheckCloudCredentials() error
}

CredentialChecker provides an API for checking that the credentials used by the broker are functioning.

type DeploymentMode

type DeploymentMode string

DeploymentMode defines a deployment mode.

const (
	ModeOperator DeploymentMode = "operator"
	ModeWorkload DeploymentMode = "workload"
	ModeSidecar  DeploymentMode = "embedded"
)

type DeploymentParams

type DeploymentParams struct {
	DeploymentType DeploymentType
	ServiceType    ServiceType
}

DeploymentParams defines parameters for specifying how a service is deployed.

type DeploymentState

type DeploymentState struct {
	// Exists is true if the operator/application exists in the cluster.
	Exists bool

	// Terminating is true if the operator/application is in Terminating state.
	Terminating bool
}

DeploymentState is returned by the OperatorExists call.

type DeploymentType

type DeploymentType string

DeploymentType defines a deployment type.

const (
	DeploymentStateless DeploymentType = "stateless"
	DeploymentStateful  DeploymentType = "stateful"
	DeploymentDaemon    DeploymentType = "daemon"
)

func (DeploymentType) Validate

func (dt DeploymentType) Validate() error

Validate validates if this deployment type is supported.

type FilesystemInfo

type FilesystemInfo struct {
	StorageName  string
	FilesystemId string
	Size         uint64
	MountPoint   string
	ReadOnly     bool
	Status       status.StatusInfo
	Volume       VolumeInfo
}

FilesystemInfo represents information about a filesystem mounted by a unit.

type ModelOperatorConfig

type ModelOperatorConfig struct {
	// AgentConf is the contents of the agent.conf file.
	AgentConf []byte

	// ImageDetails is the docker registry URL and auth details for the juju operator image.
	ImageDetails resources.DockerImageDetails

	// Port is the socket port that the operator model will be listening on
	Port int32
}

ModelOperatorConfig is the config to when creating a model operator

type ModelOperatorManager

type ModelOperatorManager interface {
	// ModelOperatorExists indicates if the model operator for the given broker
	// exists
	ModelOperatorExists() (bool, error)

	// EnsureModelOperator creates or updates a model operator pod for running
	// model operations in a CAAS namespace/model
	EnsureModelOperator(modelUUID, agentPath string, config *ModelOperatorConfig) error

	// ModelOperator return the model operator config used to create the current
	// model operator for this broker
	ModelOperator() (*ModelOperatorConfig, error)
}

ModelOperatorManager provides an API for deploying operators for individual models.

type MountConfig

type MountConfig struct {
	// StorageName is the name of the storage as specified in the charm.
	StorageName string

	// Path is the mount point inside the container.
	Path string
}

MountConfig describes a storage that should be mounted to a container.

type NewContainerBrokerFunc

type NewContainerBrokerFunc func(ctx context.Context, args environs.OpenParams) (Broker, error)

NewContainerBrokerFunc returns a Container Broker.

type Operator

type Operator struct {
	Id     string
	Dying  bool
	Status status.StatusInfo
	Config *OperatorConfig
}

Operator represents information about the status of an "operator pod".

type OperatorClientInfo

type OperatorClientInfo struct {
	ServiceAddress string `yaml:"service-address,omitempty"`
	Token          string `yaml:"token,omitempty"`
}

OperatorClientInfo contains information needed by CAAS tools.

func UnmarshalOperatorClientInfo

func UnmarshalOperatorClientInfo(data []byte) (*OperatorClientInfo, error)

UnmarshalOperatorClientInfo parses OperatorClientInfo yaml data.

func (OperatorClientInfo) Marshal

func (info OperatorClientInfo) Marshal() ([]byte, error)

Marshal OperatorClientInfo into yaml data.

type OperatorConfig

type OperatorConfig struct {
	// ImageDetails is the docker registry URL and auth details for the juju operator image.
	ImageDetails resources.DockerImageDetails

	// BaseImageDetails is the docker registry URL and auth details for the charm base image.
	BaseImageDetails resources.DockerImageDetails

	// Version is the Juju version of the operator image.
	Version version.Number

	// CharmStorage defines parameters used to optionally
	// create storage for operators to use for charm state.
	CharmStorage *CharmStorageParams

	// AgentConf is the contents of the agent.conf file.
	AgentConf []byte

	// OperatorInfo is the contents of the operator.yaml file.
	OperatorInfo []byte

	// ResourceTags is a set of tags to set on the operator pod.
	ResourceTags map[string]string

	// ConfigMapGeneration is set when updating the operator config
	// map for consistency in Read after Write and Write after Write.
	// A value of 0 is ignored.
	ConfigMapGeneration int64
}

OperatorConfig is the config to use when creating an operator.

type OperatorInfo

type OperatorInfo struct {
	CACert     string `yaml:"ca-cert,omitempty"`
	Cert       string `yaml:"cert,omitempty"`
	PrivateKey string `yaml:"private-key,omitempty"`
}

OperatorInfo contains information needed by CAAS operators

func UnmarshalOperatorInfo

func UnmarshalOperatorInfo(data []byte) (*OperatorInfo, error)

UnmarshalOperatorInfo parses OperatorInfo yaml data.

func (OperatorInfo) Marshal

func (info OperatorInfo) Marshal() ([]byte, error)

Marshal OperatorInfo into yaml data.

type ProxyManager

type ProxyManager interface {
	ProxyToApplication(appName, remotePort string) (proxy.Proxier, error)
}

ProxyManager provides the API to get proxier information for applications

type RunAs

type RunAs string

RunAs defines which user to run a certain process as.

const (
	RunAsRoot    RunAs = "root"
	RunAsSudoer  RunAs = "sudoer"
	RunAsNonRoot RunAs = "non-root"
)

type SecretsBackend

type SecretsBackend interface {
	// SaveJujuSecret saves a secret, returning an id used to access the secret later.
	SaveJujuSecret(ctx context.Context, name string, value secrets.SecretValue) (string, error)

	// GetJujuSecret gets the content of a Juju secret.
	GetJujuSecret(ctx context.Context, id string) (secrets.SecretValue, error)

	// DeleteJujuSecret deletes a Juju secret.
	DeleteJujuSecret(ctx context.Context, id string) error
}

SecretsBackend provides an API for managing Juju secrets.

type SecretsProvider

type SecretsProvider interface {
	// EnsureSecretAccessToken ensures the secret related RBAC resources for the provided entity.
	EnsureSecretAccessToken(tag names.Tag, owned, read, removed []string) (string, error)

	// RemoveSecretAccessToken removes the secret related RBAC resources for the provided entity.
	RemoveSecretAccessToken(tag names.Tag) error
}

SecretsProvider provides an API for accessing the broker interface for managing secret k8s provider resources.

type Service

type Service struct {
	Id         string
	Addresses  network.ProviderAddresses
	Scale      *int
	Generation *int64
	Status     status.StatusInfo
}

Service represents information about the status of a caas service entity.

type ServiceInterface

type ServiceInterface interface {
	// UpdateService updates the default service with specific service type and port mappings.
	UpdateService(ServiceParam) error

	UpdatePorts(ports []ServicePort, updateContainerPorts bool) error
}

ServiceInterface provides the API to get/set service.

type ServiceManager

type ServiceManager interface {
	// EnsureService creates or updates a service for pods with the given params.
	EnsureService(appName string, statusCallback StatusCallbackFunc, params *ServiceParams, numUnits int, config config.ConfigAttributes) error

	// DeleteService deletes the specified service with all related resources.
	DeleteService(appName string) error

	// ExposeService sets up external access to the specified service.
	ExposeService(appName string, resourceTags map[string]string, config config.ConfigAttributes) error

	// UnexposeService removes external access to the specified service.
	UnexposeService(appName string) error

	// GetService returns the service for the specified application.
	GetService(appName string, mode DeploymentMode, includeClusterIP bool) (*Service, error)

	// WatchService returns a watcher which notifies when there
	// are changes to the deployment of the specified application.
	WatchService(appName string, mode DeploymentMode) (watcher.NotifyWatcher, error)
}

ServiceManager provides the API to manipulate services.

type ServiceParam

type ServiceParam struct {
	Type  string        `json:"type"`
	Ports []ServicePort `json:"ports"`
}

ServiceParam defines parameters for an UpdateService request.

type ServiceParams

type ServiceParams struct {
	// Deployment defines how a service is deployed.
	Deployment DeploymentParams

	// PodSpec is the spec used to configure a pod.
	PodSpec *specs.PodSpec

	// RawK8sSpec is the raw spec used to to apply to the cluster.
	RawK8sSpec string

	// ResourceTags is a set of tags to set on the created service.
	ResourceTags map[string]string

	// Constraints is a set of constraints on
	// the pod to create.
	Constraints constraints.Value

	// Filesystems is a set of parameters for filesystems that should be created.
	Filesystems []storage.KubernetesFilesystemParams

	// Devices is a set of parameters for Devices that is required.
	Devices []devices.KubernetesDeviceParams

	// CharmModifiedVersion increases when the charm changes in some way.
	CharmModifiedVersion int

	// ImageDetails is the docker registry URL and auth details for the juju init container image.
	ImageDetails resources.DockerImageDetails
}

ServiceParams defines parameters used to create a service.

type ServicePort

type ServicePort struct {
	Name       string `json:"name"`
	Port       int    `json:"port"`
	TargetPort int    `json:"target-port"`
	Protocol   string `json:"protocol"`
}

ServicePort represents service ports mapping from service to units.

type ServiceType

type ServiceType string

ServiceType defines a service type.

const (
	ServiceCluster      ServiceType = "cluster"
	ServiceLoadBalancer ServiceType = "loadbalancer"
	ServiceExternal     ServiceType = "external"
	ServiceOmit         ServiceType = "omit"
)

func (ServiceType) IsOmit

func (st ServiceType) IsOmit() bool

IsOmit indicates if a service is required.

type StatusCallbackFunc

type StatusCallbackFunc func(appName string, settableStatus status.Status, info string, data map[string]interface{}) error

StatusCallbackFunc represents a function that can be called to report a status.

type StorageValidator

type StorageValidator interface {
	// ValidateStorageClass returns an error if the storage config is not valid.
	ValidateStorageClass(config map[string]interface{}) error
}

StorageValidator provides methods to validate storage.

type Unit

type Unit struct {
	Id             string
	Address        string
	Ports          []string
	Dying          bool
	Stateful       bool
	Status         status.StatusInfo
	FilesystemInfo []FilesystemInfo
}

Unit represents information about the status of a "pod".

type Upgrader

type Upgrader interface {
	// Upgrade sets the OCI image for the app to the specified version.
	Upgrade(appName string, vers version.Number) error
}

Upgrader provides the API to perform upgrades.

type VolumeInfo

type VolumeInfo struct {
	VolumeId   string
	Size       uint64
	Persistent bool
	Status     status.StatusInfo
}

VolumeInfo represents information about a volume mounted by a unit.

Directories

Path Synopsis
pod
provider/exec/mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
provider/mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
provider/pebble
Package pebble defines constants (probe handlers, health check ports) to be used in Pebble container specs.
Package pebble defines constants (probe handlers, health check ports) to be used in Pebble container specs.
provider/resources/mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
provider/specs/mocks
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.
Package mocks is a generated GoMock package.

Jump to

Keyboard shortcuts

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