Documentation
¶
Overview ¶
Package v1beta1 contains API Schema definitions for the cloudscale v1beta1 API group +kubebuilder:object:generate=true +groupName=cloudscale.appuio.io
Index ¶
- Variables
- type AllowedCIDR
- type AllowedSubnet
- type FloatingIPAddress
- type HTTPHealthMonitor
- func (in *HTTPHealthMonitor) DeepCopy() *HTTPHealthMonitor
- func (in *HTTPHealthMonitor) DeepCopyInto(out *HTTPHealthMonitor)
- func (h HTTPHealthMonitor) GetMethod() string
- func (h HTTPHealthMonitor) GetPath() string
- func (h HTTPHealthMonitor) GetStatusCodes() []string
- func (h HTTPHealthMonitor) GetVersion() string
- type HealthMonitor
- func (in *HealthMonitor) DeepCopy() *HealthMonitor
- func (in *HealthMonitor) DeepCopyInto(out *HealthMonitor)
- func (h HealthMonitor) GetDelay() time.Duration
- func (h HealthMonitor) GetDownThreshold() int
- func (h HealthMonitor) GetTimeout() time.Duration
- func (h HealthMonitor) GetType() string
- func (h HealthMonitor) GetUpThreshold() int
- type LoadBalancer
- type LoadBalancerList
- type LoadBalancerSpec
- type LoadBalancerStatus
- type Pool
- type PoolBackend
- type PoolFrontend
- type StatusBackend
- type StatusFloatingIPAddress
- type StatusPool
- type StatusVirtualIPAddress
- type VirtualIPAddress
Constants ¶
This section is empty.
Variables ¶
var ( // GroupVersion is group version used to register these objects GroupVersion = schema.GroupVersion{Group: "cloudscale.appuio.io", Version: "v1beta1"} // SchemeBuilder is used to add go types to the GroupVersionKind scheme SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} // AddToScheme adds the types in this group-version to the given scheme. AddToScheme = SchemeBuilder.AddToScheme )
Functions ¶
This section is empty.
Types ¶
type AllowedCIDR ¶
type AllowedCIDR struct {
// CIDR is the source IP address in CIDR notation.
// For example: "192.168.1.0/24"
CIDR string `json:"cidr"`
}
AllowedCIDR defines a CIDR that is allowed to access the listener.
func (*AllowedCIDR) DeepCopy ¶
func (in *AllowedCIDR) DeepCopy() *AllowedCIDR
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AllowedCIDR.
func (*AllowedCIDR) DeepCopyInto ¶
func (in *AllowedCIDR) DeepCopyInto(out *AllowedCIDR)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type AllowedSubnet ¶
type AllowedSubnet struct {
// UUID is the UUID of the subnet that should be used for the load balancer.
UUID string `json:"uuid"`
}
func (*AllowedSubnet) DeepCopy ¶
func (in *AllowedSubnet) DeepCopy() *AllowedSubnet
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AllowedSubnet.
func (*AllowedSubnet) DeepCopyInto ¶
func (in *AllowedSubnet) DeepCopyInto(out *AllowedSubnet)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type FloatingIPAddress ¶
type FloatingIPAddress struct {
// CIDR is the actual floating IP address that should be assigned to the loadbalancer in CIDR notation.
CIDR string `json:"cidr"`
}
FloatingIPAddress defines a floating IP address for the load balancer.
func (*FloatingIPAddress) DeepCopy ¶
func (in *FloatingIPAddress) DeepCopy() *FloatingIPAddress
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FloatingIPAddress.
func (*FloatingIPAddress) DeepCopyInto ¶
func (in *FloatingIPAddress) DeepCopyInto(out *FloatingIPAddress)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type HTTPHealthMonitor ¶
type HTTPHealthMonitor struct {
// Method is the HTTP method to use for the health check.
// This can be one of `CONNECT`, `DELETE`, `GET`, `HEAD`, `OPTIONS`, `PATCH`,
// `POST`, `PUT`, or `TRACE`.
// Defaults to `GET`.
//+kubebuilder:validation:Enum=CONNECT;DELETE;GET;HEAD;OPTIONS;PATCH;POST;PUT;TRACE
Method string `json:"method,omitempty"`
// Path is the URL path to check.
// Defaults to `/`.
Path string `json:"path,omitempty"`
// Host is the HTTP `Host:` header to use for the health check.
Host string `json:"host,omitempty"`
// Version is the HTTP version to use for the health check.
// This can be one of `1.0`or `1.1`.
// Defaults to `1.1`.
//+kubebuilder:validation:Enum="1.0";"1.1"
Version string `json:"version,omitempty"`
// StatusCodes is a list of HTTP status codes that indicate a healthy backend.
// This can either be a list of status codes or a single range of status codes.
// For example, `200`, `201`, `202`, or `200-299`.
// Defaults to `[200]`.
StatusCodes []string `json:"statusCodes,omitempty"`
}
HTTPHealthMonitor defines the HTTP health check configuration.
func (*HTTPHealthMonitor) DeepCopy ¶
func (in *HTTPHealthMonitor) DeepCopy() *HTTPHealthMonitor
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPHealthMonitor.
func (*HTTPHealthMonitor) DeepCopyInto ¶
func (in *HTTPHealthMonitor) DeepCopyInto(out *HTTPHealthMonitor)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (HTTPHealthMonitor) GetMethod ¶
func (h HTTPHealthMonitor) GetMethod() string
func (HTTPHealthMonitor) GetPath ¶
func (h HTTPHealthMonitor) GetPath() string
func (HTTPHealthMonitor) GetStatusCodes ¶
func (h HTTPHealthMonitor) GetStatusCodes() []string
func (HTTPHealthMonitor) GetVersion ¶
func (h HTTPHealthMonitor) GetVersion() string
type HealthMonitor ¶
type HealthMonitor struct {
// Port is the port on which the health check is performed.
// If not specified the health check is performed on the port which is configured for the pool backend.
Port int32 `json:"port,omitempty"`
// Type defines the type of health check to perform.
// This can be one of `Ping`,`TCP`, `HTTP`, `HTTPS`, or `TLSHello`.
// Defaults to `TCP`.
//+kubebuilder:default="TCP"
//+kubebuilder:validation:Enum=Ping;TCP;HTTP;HTTPS;TLSHello
Type string `json:"type,omitempty"`
// Delay is the time between health checks.
// Defaults to 2 seconds.
//+kubebuilder:validation:Type=string
//+kubebuilder:validation:Format=duration
//+kubebuilder:default="2s"
Delay metav1.Duration `json:"delay,omitempty"`
// Timeout is the time to wait for a response from the backend server.
// Defaults to 1 second.
//+kubebuilder:validation:Type=string
//+kubebuilder:validation:Format=duration
//+kubebuilder:default="1s"
Timeout metav1.Duration `json:"timeout,omitempty"`
// SuccessThreshold is the number of consecutive successful health checks
// required before a backend server is considered healthy.
// Defaults to 2.
//+kubebuilder:validation:Minimum=1
//+kubebuilder:default=2
SuccessThreshold int `json:"successThreshold,omitempty"`
// FailureThreshold is the number of consecutive failed health checks
// required before a backend server is considered unhealthy.
// Defaults to 3.
//+kubebuilder:validation:Minimum=1
//+kubebuilder:default=3
FailureThreshold int `json:"failureThreshold,omitempty"`
// HTTP defines the HTTP health check configuration.
HTTP HTTPHealthMonitor `json:"http,omitempty"`
}
HealthMonitor defines the health check configuration for the load balancer.
func (*HealthMonitor) DeepCopy ¶
func (in *HealthMonitor) DeepCopy() *HealthMonitor
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthMonitor.
func (*HealthMonitor) DeepCopyInto ¶
func (in *HealthMonitor) DeepCopyInto(out *HealthMonitor)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (HealthMonitor) GetDelay ¶
func (h HealthMonitor) GetDelay() time.Duration
func (HealthMonitor) GetDownThreshold ¶
func (h HealthMonitor) GetDownThreshold() int
func (HealthMonitor) GetTimeout ¶
func (h HealthMonitor) GetTimeout() time.Duration
func (HealthMonitor) GetType ¶
func (h HealthMonitor) GetType() string
func (HealthMonitor) GetUpThreshold ¶
func (h HealthMonitor) GetUpThreshold() int
type LoadBalancer ¶
type LoadBalancer struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec LoadBalancerSpec `json:"spec,omitempty"`
Status LoadBalancerStatus `json:"status,omitempty"`
}
LoadBalancer is the Schema for the LoadBalancers API
func (*LoadBalancer) DeepCopy ¶
func (in *LoadBalancer) DeepCopy() *LoadBalancer
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoadBalancer.
func (*LoadBalancer) DeepCopyInto ¶
func (in *LoadBalancer) DeepCopyInto(out *LoadBalancer)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (*LoadBalancer) DeepCopyObject ¶
func (in *LoadBalancer) DeepCopyObject() runtime.Object
DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
type LoadBalancerList ¶
type LoadBalancerList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []LoadBalancer `json:"items"`
}
LoadBalancerList contains a list of LoadBalancer
func (*LoadBalancerList) DeepCopy ¶
func (in *LoadBalancerList) DeepCopy() *LoadBalancerList
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoadBalancerList.
func (*LoadBalancerList) DeepCopyInto ¶
func (in *LoadBalancerList) DeepCopyInto(out *LoadBalancerList)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (*LoadBalancerList) DeepCopyObject ¶
func (in *LoadBalancerList) DeepCopyObject() runtime.Object
DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
type LoadBalancerSpec ¶
type LoadBalancerSpec struct {
// LoadBalancerUUID uniquely identifies the loadbalancer. This field
// should not be provided by the customer, unless the adoption of an
// existing load balancer is desired.
//
// In all other cases, this value is set by the CCM after creating the
// load balancer, to ensure that we track it with a proper ID and not
// a name that might change without our knowledge.
UUID string `json:"uuid,omitempty"`
// Zone denotes the availability zone where the load balancer is deployed.
// This defaults to the zone of the Nodes (if there is only one).
//
// This can not be changed once the LoadBalancer custom resource is created.
Zone string `json:"zone,omitempty"`
// VirtualIPAddresses defines the virtual IP addresses through which
// incoming traffic is received. this defaults to an automatically assigned
// public IPv4 and IPv6 address.
//
// If you want to use a specific private subnet instead, to load balance
// inside your cluster, you have to specify the subnet the loadbalancer
// should bind to, and optionally what IP address it should use (if you
// don't want an automatically assigned one).
//
// Currently limited to one virtual IP address per load balancer.
// See: https://www.cloudscale.ch/en/api/v1#vip_addresses-attribute-specification
//
//+kubebuilder:validation:MaxItems=1
VirtualIPAddresses []VirtualIPAddress `json:"virtualIPAddresses,omitempty"`
// FloatingIPAddresses assigns the given Floating IPs to the
// load balancer. The expected value is a list of addresses of the
// Floating IPs in CIDR notation. For example:
//
// ["5.102.150.123/32", "2a06:c01::123/128"]
//
// Floating IPs already assigned to the loadbalancer, but no longer
// present in this field, stay on the loadbalancer until another
// service requests them. This is due to the fact that it is not possible
// to unassign Floating IPs to point to nowhere.
//
// The Floating IPs are only assigned to the LoadBalancer once it has
// been fully created.
FloatingIPAddresses []FloatingIPAddress `json:"floatingIPAddresses,omitempty"`
// Pools defines the pools that are part of the load balancer.
Pools []Pool `json:"pools,omitempty"`
}
LoadBalancerSpec defines the desired state of LoadBalancer
func (*LoadBalancerSpec) DeepCopy ¶
func (in *LoadBalancerSpec) DeepCopy() *LoadBalancerSpec
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoadBalancerSpec.
func (*LoadBalancerSpec) DeepCopyInto ¶
func (in *LoadBalancerSpec) DeepCopyInto(out *LoadBalancerSpec)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type LoadBalancerStatus ¶
type LoadBalancerStatus struct {
// CloudscaleStatus is the raw status of the load balancer as reported by Cloudscale.
CloudscaleStatus string `json:"cloudscaleStatus,omitempty"`
// VirtualIPAddresses contains the IP addresses through which the load balancer can be accessed.
VirtualIPAddresses []StatusVirtualIPAddress `json:"virtualIPAddresses,omitempty"`
// FloatingIPAddresses contains the floating IP addresses that are assigned to the load balancer.
// This is a list of IP addresses in CIDR notation.
FloatingIPAddresses []StatusFloatingIPAddress `json:"floatingIPAddresses,omitempty"`
// Pools contains the status of the pools that are part of the load balancer.
Pools []StatusPool `json:"pools,omitempty"`
}
LoadBalancerStatus defines the observed state of LoadBalancer
func (*LoadBalancerStatus) DeepCopy ¶
func (in *LoadBalancerStatus) DeepCopy() *LoadBalancerStatus
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoadBalancerStatus.
func (*LoadBalancerStatus) DeepCopyInto ¶
func (in *LoadBalancerStatus) DeepCopyInto(out *LoadBalancerStatus)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type Pool ¶
type Pool struct {
// Name is the name of the pool.
// Changing the name of the pool will cause short downtime as the pool is recreated.
//+required
Name string `json:"name"`
// Algorithm defines the algorithm used to distribute traffic across
// the backend servers.
// This can be one of `RoundRobin`, `LeastConnections`, or `SourceIP`.
// * `RoundRobin` distributes traffic evenly across all servers.
// * `LeastConnections` sends traffic to the server with the least active
// connections.
// * `SourceIP` uses the source IP address to determine which server to
// send the traffic to. `SourceIP` maintains session persistence across
// multiple requests and is useful for applications that require it.
//
// The default is `RoundRobin`.
//
// Changing the algorithm of the pool will cause short downtime as the pool is recreated.
//
//+kubebuilder:validation:Enum=RoundRobin;LeastConnections;SourceIP
//+kubebuilder:default="RoundRobin"
Algorithm string `json:"algorithm,omitempty"`
// Frontend configures the frontend of the pool.
Frontend PoolFrontend `json:"frontend,omitempty"`
// Backend configures the backend of the pool.
Backend PoolBackend `json:"backend,omitempty"`
}
func (*Pool) DeepCopy ¶
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Pool.
func (*Pool) DeepCopyInto ¶
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (Pool) GetAlgorithm ¶
type PoolBackend ¶
type PoolBackend struct {
// Port is the port on which the traffic is sent on the backend servers.
//+required
Port int32 `json:"port"`
// Protocol defines the protocol used by the backend servers.
// This can be one of `TCP`, `Proxy`, or `ProxyV2`.
// * `TCP` no connection information is sent to the backend servers.
// * `Proxy` wraps the connection in a proxy protocol header.
// The load balancer sends an initial series of octets describing the
// connection to the backend server.
// * `ProxyV2` is similar to `Proxy`, but uses a different version of the
// proxy protocol header.
//
// The default is `TCP`.
//
// Changing the protocol of the pool will cause short downtime as the pool is recreated.
//
//+kubebuilder:validation:Enum=TCP;Proxy;ProxyV2
//+kubebuilder:default="TCP"
Protocol string `json:"protocol,omitempty"`
// HealthMonitor defines the health check configuration for the load balancer.
HealthMonitor HealthMonitor `json:"healthMonitor,omitempty"`
// NodeSelector defines the node selector for the load balancer.
// The controller automatically updates the pool members to match
// the nodes matching this selector.
NodeSelector metav1.LabelSelector `json:"nodeSelector,omitempty"`
// DataTimeout defines the milliseconds until inactive backend connections are dropped.
// Defaults to 50 seconds.
//+kubebuilder:validation:Type=string
//+kubebuilder:validation:Format=duration
//+kubebuilder:default="50s"
DataTimeout metav1.Duration `json:"dataTimeout,omitempty"`
// ConnectTimeout denotes the time it should maximally take to connect to a backend server
// before the connection is considered failed.
// Defaults to 5 seconds.
//+kubebuilder:validation:Type=string
//+kubebuilder:validation:Format=duration
//+kubebuilder:default="5s"
ConnectTimeout metav1.Duration `json:"connectTimeout,omitempty"`
// AllowedSubnets is a JSON list of subnet UUIDs that the
// loadbalancer should use. By default, all subnets of a node are used.
//
// If set, nodes without a matching subnet are ignored.
AllowedSubnets []AllowedSubnet `json:"allowedSubnets,omitempty"`
}
func (*PoolBackend) DeepCopy ¶
func (in *PoolBackend) DeepCopy() *PoolBackend
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PoolBackend.
func (*PoolBackend) DeepCopyInto ¶
func (in *PoolBackend) DeepCopyInto(out *PoolBackend)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (PoolBackend) GetConnectTimeout ¶
func (l PoolBackend) GetConnectTimeout() time.Duration
func (PoolBackend) GetDataTimeout ¶
func (l PoolBackend) GetDataTimeout() time.Duration
func (PoolBackend) GetProtocol ¶
func (p PoolBackend) GetProtocol() string
type PoolFrontend ¶
type PoolFrontend struct {
// Protocol defines the protocol used by the listener.
// Currently, only `TCP` is supported.
// Defaults to `TCP`.
//+kubebuilder:validation:Enum=TCP
//+kubebuilder:default="TCP"
Protocol string `json:"protocol,omitempty"`
// Port is the port on which the listener will accept traffic.
//+required
Port int32 `json:"port"`
// AllowedCIDRs defines the source IPs that are allowed to access the listener.
// This is a list of source IP addresses in CIDR notation, for example:
// ["1.1.1.1", "104.132.228.0/24"]
// If not specified, all source IP addresses are allowed to access the
// listener.
// If specified, only the source IP addresses that match the CIDRs
// in this list are allowed to access the listener.
AllowedCIDRs []AllowedCIDR `json:"allowedCIDRs,omitempty"`
// DataTimeout defines the milliseconds until inactive client connections are dropped.
// Defaults to 50 seconds.
//+kubebuilder:validation:Type=string
//+kubebuilder:validation:Format=duration
//+kubebuilder:default="50s"
DataTimeout metav1.Duration `json:"dataTimeout,omitempty"`
}
func (*PoolFrontend) DeepCopy ¶
func (in *PoolFrontend) DeepCopy() *PoolFrontend
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PoolFrontend.
func (*PoolFrontend) DeepCopyInto ¶
func (in *PoolFrontend) DeepCopyInto(out *PoolFrontend)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (PoolFrontend) GetDataTimeout ¶
func (l PoolFrontend) GetDataTimeout() time.Duration
func (PoolFrontend) GetProtocol ¶
func (l PoolFrontend) GetProtocol() string
type StatusBackend ¶
type StatusBackend struct {
// NodeName is the name of the node.
NodeName string `json:"nodeName,omitempty"`
// ServerName is the name of the server.
ServerName string `json:"serverName,omitempty"`
// Address is the IP address of the backend node.
Address string `json:"address,omitempty"`
// Status is the status of the backend node as reported by the health monitor.
Status string `json:"status,omitempty"`
}
StatusBackend defines a backend node in the load balancer status.
func (*StatusBackend) DeepCopy ¶
func (in *StatusBackend) DeepCopy() *StatusBackend
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatusBackend.
func (*StatusBackend) DeepCopyInto ¶
func (in *StatusBackend) DeepCopyInto(out *StatusBackend)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type StatusFloatingIPAddress ¶
type StatusFloatingIPAddress struct {
// CIDR is the floating IP address in CIDR notation.
CIDR string `json:"cidr,omitempty"`
}
func (*StatusFloatingIPAddress) DeepCopy ¶
func (in *StatusFloatingIPAddress) DeepCopy() *StatusFloatingIPAddress
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatusFloatingIPAddress.
func (*StatusFloatingIPAddress) DeepCopyInto ¶
func (in *StatusFloatingIPAddress) DeepCopyInto(out *StatusFloatingIPAddress)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type StatusPool ¶
type StatusPool struct {
// Name is the name of the pool.
Name string `json:"name,omitempty"`
// Backends contains all nodes that are currently part of the load balancer.
Backends []StatusBackend `json:"backends,omitempty"`
}
func (*StatusPool) DeepCopy ¶
func (in *StatusPool) DeepCopy() *StatusPool
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatusPool.
func (*StatusPool) DeepCopyInto ¶
func (in *StatusPool) DeepCopyInto(out *StatusPool)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type StatusVirtualIPAddress ¶
type StatusVirtualIPAddress struct {
// Address is the IP address of the frontend.
Address string `json:"address,omitempty"`
}
func (*StatusVirtualIPAddress) DeepCopy ¶
func (in *StatusVirtualIPAddress) DeepCopy() *StatusVirtualIPAddress
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StatusVirtualIPAddress.
func (*StatusVirtualIPAddress) DeepCopyInto ¶
func (in *StatusVirtualIPAddress) DeepCopyInto(out *StatusVirtualIPAddress)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
type VirtualIPAddress ¶
type VirtualIPAddress struct {
// Address is the actual IP address that should be assigned to the loadbalancer.
Address string `json:"address,omitempty"`
// SubnetID is the ID of the subnet where this IP address resides.
//+required
SubnetID string `json:"subnetID"`
}
VirtualIPAddress defines a virtual IP address for the load balancer.
func (*VirtualIPAddress) DeepCopy ¶
func (in *VirtualIPAddress) DeepCopy() *VirtualIPAddress
DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VirtualIPAddress.
func (*VirtualIPAddress) DeepCopyInto ¶
func (in *VirtualIPAddress) DeepCopyInto(out *VirtualIPAddress)
DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.