Skip to content

Commit

Permalink
Merge 2f5b5d1 into 5126bd0
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisdoherty4 authored Mar 18, 2023
2 parents 5126bd0 + 2f5b5d1 commit 616a9c5
Show file tree
Hide file tree
Showing 12 changed files with 1,613 additions and 4 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ GOPROXY ?= $(shell go env GOPROXY)
# Runnable tools
GO ?= go
BUF := $(GO) run github.com/bufbuild/buf/cmd/[email protected]
CONTROLLER_GEN := $(GO) run sigs.k8s.io/controller-tools/cmd/controller-gen@v0.10
CONTROLLER_GEN := $(GO) run sigs.k8s.io/controller-tools/cmd/controller-gen@v0.11
GOFUMPT := $(GO) run mvdan.cc/[email protected]
KUSTOMIZE := $(GO) run sigs.k8s.io/kustomize/kustomize/[email protected]
SETUP_ENVTEST := $(GO) run sigs.k8s.io/controller-runtime/tools/[email protected]
Expand Down
45 changes: 45 additions & 0 deletions api/v1alpha2/conditions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package v1alpha2

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

// ConditionType identifies the type of condition.
type ConditionType string

// ConditionStatus expresses the current state of the condition.
type ConditionStatus string

const (
// ConditionStatusUnknown is the default status and indicates the condition cannot be
// evaluated as True or False.
ConditionStatusUnknown ConditionStatus = "Unknown"

// ConditionStatusTrue indicates the condition has been evaluated as true.
ConditionStatusTrue ConditionStatus = "True"

// ConditionStatusFalse indicates the condition has been evaluated as false.
ConditionStatusFalse ConditionStatus = "False"
)

// Condition defines an observation on a resource that is generally attainable by inspecting
// other status fields.
type Condition struct {
// Type of condition.
Type ConditionType `json:"type"`

// Status of the condition.
Status ConditionStatus `json:"status"`

// LastTransition is the last time the condition transitioned from one status to another.
LastTransition *metav1.Time `json:"lastTransitionTime"`

// Reason is a short CamelCase description for the conditions last transition.
// +optional
Reason *string `json:"reason,omitempty"`

// Message is a human readable message indicating details about the last transition.
// +optional
Message *string `json:"message,omitempty"`
}

// Conditions define a list of observations of a particular resource.
type Conditions []Condition
20 changes: 20 additions & 0 deletions api/v1alpha2/groupversion_info.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// +groupName=tinkerbell.org
// +kubebuilder:object:generate=true

package v1alpha2

import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"
)

var (
// GroupVersion is group version used to register these objects.
GroupVersion = schema.GroupVersion{Group: "tinkerbell.org", Version: "v1alpha2"}

// 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
)
178 changes: 178 additions & 0 deletions api/v1alpha2/hardware.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
package v1alpha2

import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type HardwareSpec struct {
// NetworkInterfaces defines the desired DHCP and netboot configuration for a network interface.
// +kubebuilder:validation:MinPoperties=1
NetworkInterfaces NetworkInterfaces `json:"networkInterfaces,omitempty"`

// IPXE provides iPXE script override fields. This is useful for debugging or netboot
// customization.
// +optional.
IPXE *IPXE `json:"ipxe,omitempty"`

// OSIE describes the Operating System Installation Environment to be netbooted.
OSIE corev1.LocalObjectReference `json:"osie,omitempty"`

// KernelParams passed to the kernel when launching the OSIE. Parameters are joined with a
// space.
// +optional
KernelParams []string `json:"kernelParams,omitempty"`

// Instance describes instance specific data that is generally unused by Tinkerbell core.
// +optional
Instance *Instance `json:"instance,omitempty"`

// StorageDevices is a list of storage devices that will be available in the OSIE.
// +optional.
StorageDevices []StorageDevice `json:"storageDevices,omitempty"`

// BMCRef references a Rufio Machine object.
// +optional.
BMCRef *corev1.LocalObjectReference `json:"bmcRef,omitempty"`
}

// NetworkInterfaces maps a MAC address to a NetworkInterface.
type NetworkInterfaces map[MAC]NetworkInterface

// NetworkInterface is the desired configuration for a particular network interface.
type NetworkInterface struct {
// DHCP is the basic network information for serving DHCP requests.
DHCP DHCP `json:"dhcp,omitempty"`

// DisableDHCP disables DHCP for this interface. Implies DisableNetboot.
// +kubebuilder:default=false
DisableDHCP bool `json:"disableDhcp,omitempty"`

// DisableNetboot disables netbooting for this interface. The interface will still receive
// network information speified on by DHCP.
// +kubebuilder:default=false
DisableNetboot bool `json:"disableNetboot,omitempty"`
}

// DHCP describes basic network configuration to be served in DHCP OFFER responses. It can be
// considered a DHCP reservation.
type DHCP struct {
// IP is an IPv4 address to serve.
// +kubebuilder:validation:Pattern=`(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}`
IP string `json:"ip,omitempty"`

// Netmask is an IPv4 netmask to serve.
// +kubebuilder+validation:Pattern=`^(255)\.(0|128|192|224|240|248|252|254|255)\.(0|128|192|224|240|248|252|254|255)\.(0|128|192|224|240|248|252|254|255)`
Netmask string `json:"netmask,omitempty"`

// Gateway is the default gateway address to serve.
// +kubebuilder:validation:Pattern=`(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}`
// +optional
Gateway *string `json:"gateway,omitempty"`

// +kubebuilder:validation:Pattern=`^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9]"[A-Za-z0-9\-]*[A-Za-z0-9])$`
// +optional
Hostname *string `json:"hostname,omitempty"`

// VLANID is a VLAN ID between 0 and 4096.
// +kubebuilder:validation:Pattern=`^(([0-9][0-9]{0,2}|[1-3][0-9][0-9][0-9]|40([0-8][0-9]|9[0-6]))(,[1-9][0-9]{0,2}|[1-3][0-9][0-9][0-9]|40([0-8][0-9]|9[0-6]))*)$`
// +optional
VLANID *string `json:"vlanId,omitempty"`

// Nameservers to serve.
// +optional
Nameservers []Nameserver `json:"nameservers,omitempty"`

// Timeservers to serve.
// +optional
Timeservers []Timeserver `json:"timeservers,omitempty"`

// LeaseTimeSeconds to serve. 24h default. Maximum equates to max uint32 as defined by RFC 2132
// § 9.2 (https://www.rfc-editor.org/rfc/rfc2132.html#section-9.2).
// +kubebuilder:default=86400
// +kubebuilder:validation:Minimum=0
// +kubebuilder:validation:Maximum=4294967295
// +optional
LeaseTimeSeconds *int64 `json:"leaseTimeSeconds"`
}

// IPXE describes overrides for IPXE scripts. At least 1 option must be specified.
type IPXE struct {
// Content is an inline iPXE script.
// +optional
Content *string `json:"inline,omitempty"`

// URL is a URL to a hosted iPXE script.
// +optional
URL *string `json:"url,omitempty"`
}

// Instance describes instance specific data. Instance specific data is typically dependent on the
// permanent OS that a piece of hardware runs. This data is often served by an instance metadata
// service such as Tinkerbell's Hegel. The core Tinkerbell stack does not leverage this data.
type Instance struct {
// Userdata is data with a structure understood by the producer and consumer of the data.
// +optional
Userdata *string `json:"userdata,omitempty"`

// Vendordata is data with a structure understood by the producer and consumer of the data.
// +optional
Vendordata *string `json:"vendordata,omitempty"`
}

// MAC is a Media Access Control address. MACs must use lower case letters.
// +kubebuilder:validation:Pattern=`^([0-9a-f]{2}:){5}([0-9a-f]{2})$`
type MAC string

// Nameserver is an IP or hostname.
// +kubebuilder:validation:Pattern=`^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$|^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$`
type Nameserver string

// Timeserver is an IP or hostname.
// +kubebuilder:validation:Pattern=`^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$|^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$`
type Timeserver string

// StorageDevice describes a storage device path that will be present in the OSIE.
// StorageDevices must be valid Linux paths. They should not contain partitions.
//
// Good
//
// /dev/sda
// /dev/nvme0n1
//
// Bad (contains partitions)
//
// /dev/sda1
// /dev/nvme0n1p1
//
// Bad (invalid Linux path)
//
// \dev\sda
//
// +kubebuilder:validation:Pattern=`^(/[^/ ]*)+/?$`
type StorageDevice string

// +kubebuilder:object:root=true
// +kubebuilder:resource:categories=tinkerbell,path=hardware,shortName=hw
// +kubebuilder:printcolumn:name="BMC",type="string",JSONPath=".spec.bmcRef",description="Baseboard management computer attached to the Hardware"
// +kubebuilder:unservedversion

// Hardware is a logical representation of a machine that can execute Workflows.
type Hardware struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec HardwareSpec `json:"spec,omitempty"`
}

// +kubebuilder:object:root=true

type HardwareList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Hardware `json:"items"`
}

func init() {
SchemeBuilder.Register(&Hardware{}, &HardwareList{})
}
36 changes: 36 additions & 0 deletions api/v1alpha2/osie.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package v1alpha2

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

type OSIESpec struct {
// KernelURL is a URL to a kernel image.
KernelURL string `json:"kernelUrl,omitempty"`

// InitrdURL is a URL to an initrd image.
InitrdURL string `json:"initrdUrl,omitempty"`
}

// +kubebuilder:object:root=true
// +kubebuilder:storageversion
// +kubebuilder:resource:categories=tinkerbell

// OSIE describes an Operating System Installation Environment. It is used by Tinkerbell
// to provision machines and should launch the Tink Worker component.
type OSIE struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec OSIESpec `json:"spec,omitempty"`
}

// +kubebuilder:object:root=true

type OSIEList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []OSIE `json:"items"`
}

func init() {
SchemeBuilder.Register(&OSIE{}, &OSIEList{})
}
96 changes: 96 additions & 0 deletions api/v1alpha2/template.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package v1alpha2

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type TemplateSpec struct {
// Actions defines the set of actions to be run on a target machine. Actions are run sequentially
// in the order they are specified. At least 1 action must be specified. Names of actions
// must be unique within a Template.
// +kubebuilder:validation:MinItems=1
Actions []Action `json:"actions,omitempty"`

// Volumes to be mounted on all actions. If an action specifies the same volume it will take
// precedence.
// +optional
Volumes []Volume `json:"volumes,omitempty"`

// Env defines environment variables to be available in all actions. If an action specifies
// the same environment variable it will take precedence.
// +optional
Env map[string]string `json:"env,omitempty"`
}

// Action defines an individual action to be run on a target machine.
type Action struct {
// Name is a name for the action.
Name string `json:"name"`

// Image is an OCI image.
Image string `json:"image"`

// Cmd defines the command to use when launching the image.
// +optional
Cmd *string `json:"cmd,omitempty"`

// Args are a set of arguments to be passed to the container on launch.
// +optional
Args []string `json:"args,omitempty"`

// Env defines environment variables used when launching the container.
//+optional
Env map[string]string `json:"env,omitempty"`

// Volumes defines the volumes to mount into the container.
// +optional
Volumes []Volume `json:"volumes,omitempty"`

// NetworkNamespace defines the network namespace to run the container in. This enables access
// to the host network namespace.
// See https://man7.org/linux/man-pages/man7/namespaces.7.html.
// +optional
NetworkNamespace *string `json:"networkNamespace,omitempty"`
}

// Volume is a specification for mounting a volume in an action. Volumes take the form
// {SRC-VOLUME-NAME | SRC-HOST-DIR}:TGT-CONTAINER-DIR:OPTIONS. When specifying a VOLUME-NAME that
// does not exist it will be created for you. Examples:
//
// Read-only bind mount bound to /data
//
// /etc/data:/data:ro
//
// Writable volume name bound to /data
//
// shared_volume:/data
//
// See https://docs.docker.com/storage/volumes/ for additional details.
type Volume string

// +kubebuilder:object:root=true
// +kubebuilder:resource:categories=tinkerbell,shortName=tpl
// +kubebuilder:unservedversion

// Template defines a set of actions to be run on a target machine. The template is rendered
// prior to execution where it is exposed to Hardware and user defined data. Most fields within the
// TemplateSpec may contain templates values excluding .TemplateSpec.Actions[].Name.
// See https://pkg.go.dev/text/template for more details.
type Template struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`

Spec TemplateSpec `json:"spec,omitempty"`
}

// +kubebuilder:object:root=true

type TemplateList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Template `json:"items"`
}

func init() {
SchemeBuilder.Register(&Template{}, &TemplateList{})
}
Loading

0 comments on commit 616a9c5

Please sign in to comment.