From 4b5543614717fa5c5643495dad974d32982104c1 Mon Sep 17 00:00:00 2001 From: sailorvii Date: Thu, 7 Jul 2022 09:50:40 +0800 Subject: [PATCH 1/3] Proposal of adding metal3host operator. --- design/images/createDataTemplate.png | Bin 0 -> 20880 bytes design/images/createMetal3Host.png | Bin 0 -> 33375 bytes design/images/createMetal3HostDeployment.png | Bin 0 -> 12808 bytes design/images/metal3hostModules.png | Bin 0 -> 12042 bytes design/metal3host-controller.md | 286 +++++++++++++++++++ 5 files changed, 286 insertions(+) create mode 100644 design/images/createDataTemplate.png create mode 100644 design/images/createMetal3Host.png create mode 100644 design/images/createMetal3HostDeployment.png create mode 100644 design/images/metal3hostModules.png create mode 100644 design/metal3host-controller.md diff --git a/design/images/createDataTemplate.png b/design/images/createDataTemplate.png new file mode 100644 index 0000000000000000000000000000000000000000..52da8c72d8efd782dbc1dbe64a0e4a5bf62f2e35 GIT binary patch literal 20880 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 T^8W@rVv)hq)z4*}Q$iB}0+kHB literal 0 HcmV?d00001 diff --git a/design/images/createMetal3Host.png b/design/images/createMetal3Host.png new file mode 100644 index 0000000000000000000000000000000000000000..0f570992d285b12b85a9fb69002c182b569ec05b GIT binary patch literal 33375 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

P`Ed()ns731!3=gyA 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 b+q?Vn2+z7MkDX`zwnOK(;jQW$_a6NpQt|4s literal 0 HcmV?d00001 diff --git a/design/images/metal3hostModules.png b/design/images/metal3hostModules.png new file mode 100644 index 0000000000000000000000000000000000000000..690dd7f0238a54899de731d278ed5b35a3352bdc GIT binary patch literal 12042 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

DtL^JF&xjmF(34 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 Ksgg4P_P+q`Nmlp( literal 0 HcmV?d00001 diff --git a/design/metal3host-controller.md b/design/metal3host-controller.md new file mode 100644 index 00000000..7a489697 --- /dev/null +++ b/design/metal3host-controller.md @@ -0,0 +1,286 @@ +# Baremetal host single instance and multi-instance operator +## Introduction +Currently, the metal3 system is to set up a Kubernetes cluster on bare-metal hosts which is tightly bound with cluster-api and Kubernetes. We target to allocate bare-metal hosts that just pre-installing the OS, or pre-installing the applications as required. +## Motivation +To meet the scenery that only requires a pure bare-metal host or with a simple application installed. +## Goals +- Allocate one pure bare-metal host +- Allocate multiple bare-metal hosts +- Allocate bare-metal host with pre-installed applications +- Specify the different configurations for different bare-metal host +## Non-goals +- Allocate different types of bare-metal hosts at one time +## Proposal +### Architecture +The operators include the metal3Host operator, metal3HostDeployment operator, and data operator. +![modules](images/metal3hostModules.png) + +The bare-metal host controller and the ironic are not newly developed. + +Metal3Host is a virtual instance. Users could define it to require a bare-metal host. In the definition, the user could specify the image to install, could set the selector to choose a specific bare-metal host, and could define the boot data to automatically start their own applications. + +Metal3HostDeployment will define a group of metal3Hosts with the same configuration. It could define the number of replicas. It could scale up/down. We even could auto-scale by some rules after the monitor function is leveraged. + +The data operator will set up the boot time configuration & routine. It includes three parts: the userData, the metaData, and the networkData. The userData includes some user-specified data such as installing a package, or running a command like "mkdir /test". The metaData defines some host-specific data such as hostname. The networkData includes the network configuration. The data is bound with the baremetal host. For example, the networkData defines a NIC with an IP, the NIC name is host related. So a dataTemplate should be pre-defined, it will be bound to the bare-metal host when a metal3host is defined and associated with a bare-metal host. +### Routine +#### Pre-define a dataTemplate +![createDataTemplate](images/createDataTemplate.png) + +#### Require a metal3host +![createMetal3Host](images/createMetal3Host.png) + +#### Require a metal3HostDeployment +![createMetal3HostDeployment](images/createMetal3HostDeployment.png) + +### Configuration +#### metal3host + + // Metal3HostSpec defines the desired state of Metal3Host + type Metal3HostSpec struct { + // ProviderID will be the Metal3Host in ProviderID format + // (://) + // +optional + ProviderID *string `json:"providerID,omitempty"` + + ConsumerRef *corev1.ObjectReference `json:"consumerRef,omitempty"` + + // UserScript is specified by user and it will run on every boot. + BootScript string `json:"bootScript,omitempty"` + + // User is the configuration used to initialize user in guest os. + // Default user is `root`. + User User `json:"user,omitempty"` + + // Image is the image to be provisioned. + Image Image `json:"image,omitempty"` + + // HostSelector specifies matching criteria for labels on BareMetalHosts. + // This is used to limit the set of BareMetalHost objects considered for + // claiming for a Metal3Host. + // +optional + HostSelector HostSelector `json:"hostSelector,omitempty"` + + // When set to disabled, automated cleaning of host disks will be skipped + // during provisioning and deprovisioning. + // +kubebuilder:validation:Enum:=metadata;disabled + // +optional + AutomatedCleaningMode *string `json:"automatedCleaningMode,omitempty"` + } + +#### metal3hostDeployment + // Metal3HostDeploymentSpec defines the desired state of Metal3HostDeployment. + type Metal3HostDeploymentSpec struct { + // Number of desired machines. Defaults to 1. + // This is a pointer to distinguish between explicit zero and not specified. + // +optional + // +kubebuilder:default=1 + Replicas *int32 `json:"replicas,omitempty"` + + // HostSelector specifies matching criteria for labels on BareMetalHosts. + // This is used to limit the set of BareMetalHost objects considered for + // claiming for a machine. + // +optional + HostSelector HostSelector `json:"hostSelector,omitempty"` + + // Template describes the metal3 hosts that will be created. + Template Metal3HostTemplateSpec `json:"template"` + + // Minimum number of seconds for which a newly created machine should + // be ready. + // Defaults to 0 (machine will be considered available as soon as it + // is ready) + // +optional + MinReadySeconds *int32 `json:"minReadySeconds,omitempty"` + + // The number of old MachineSets to retain to allow rollback. + // This is a pointer to distinguish between explicit zero and not specified. + // Defaults to 1. + // +optional + RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"` + + // Indicates that the deployment is paused. + // +optional + Paused bool `json:"paused,omitempty"` + + // The maximum time in seconds for a deployment to make progress before it + // is considered to be failed. The deployment controller will continue to + // process failed deployments and a condition with a ProgressDeadlineExceeded + // reason will be surfaced in the deployment status. Note that progress will + // not be estimated during the time a deployment is paused. Defaults to 600s. + // +optional + ProgressDeadlineSeconds *int32 `json:"progressDeadlineSeconds,omitempty"` + } + + // Metal3HostDeploymentStatus defines the observed state of Metal3HostDeployment. + type Metal3HostDeploymentStatus struct { + // The generation observed by the deployment controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // Total number of non-terminated machines targeted by this deployment + // (their labels match the selector). + // +optional + Replicas int32 `json:"replicas"` + + // Total number of non-terminated machines targeted by this deployment + // that have the desired template spec. + // +optional + UpdatedReplicas int32 `json:"updatedReplicas"` + + // Total number of ready machines targeted by this deployment. + // +optional + ReadyReplicas int32 `json:"readyReplicas"` + + // Total number of available machines (ready for at least minReadySeconds) + // targeted by this deployment. + // +optional + AvailableReplicas int32 `json:"availableReplicas"` + + // Total number of unavailable machines targeted by this deployment. + // This is the total number of machines that are still required for + // the deployment to have 100% available capacity. They may either + // be machines that are running but not yet available or machines + // that still have not been created. + // +optional + UnavailableReplicas int32 `json:"unavailableReplicas"` + + // Phase represents the current phase of a Metal3HostDeployment (ScalingUp, ScalingDown, Running, Failed, or Unknown). + // +optional + Phase string `json:"phase,omitempty"` + + // FailureReason indicates that there is a fatal problem reconciling the + // state, and will be set to a descriptive error message. + // +optional + FailureReason *string `json:"failureReason,omitempty"` + + Conditions capi.Conditions `json:"conditions,omitempty"` + } + +#### datatemplate + // DataTemplateSpec defines the desired state of DataTemplate + type DataTemplateSpec struct { + //MetaData contains the information needed to generate the metadata secret + // +optional + MetaData *MetaData `json:"metaData,omitempty"` + + //NetworkData contains the information needed to generate the networkdata + // secret + // +optional + NetworkData *NetworkData `json:"networkData,omitempty"` + + //UserData contains the information defined by user + // secret + // +optional + UserData *UserData `json:"userData,omitempty"` + } + + // NetworkData represents a networkData object + type NetworkData struct { + // Links is a structure containing lists of different types objects + // +optional + Links NetworkDataLink `json:"links,omitempty"` + + //Networks is a structure containing lists of different types objects + // +optional + Networks NetworkDataNetwork `json:"networks,omitempty"` + + //Services is a structure containing lists of different types objects + // +optional + Services NetworkDataService `json:"services,omitempty"` + } + + // UserData contains the information defined by user + type UserData struct { + //Users define the user&password information + // +optional + Users []User `json:"users"` + + //WriteFile files to be created at the boot time + // +optional + WriteFiles []WriteFile `json:"write_files"` + + //BootCmd commands to be run at the boot time + // +optional + BootCmd []string `json:"bootcmd"` + } + + // MetaData represents a keyand value of the metadata + type MetaData struct { + // Strings is the list of metadata items to be rendered from strings + // +optional + Strings []MetaDataString `json:"strings,omitempty"` + + // ObjectNames is the list of metadata items to be rendered from the name + // of objects. + // +optional + ObjectNames []MetaDataObjectName `json:"objectNames,omitempty"` + + // Indexes is the list of metadata items to be rendered from the index of the + // CUMetalData + // +optional + Indexes []MetaDataIndex `json:"indexes,omitempty"` + + // Namespaces is the list of metadata items to be rendered from the namespace + // +optional + Namespaces []MetaDataNamespace `json:"namespaces,omitempty"` + + // IPAddressesFromPool is the list of metadata items to be rendered as ip addresses. + // +optional + IPAddressesFromPool []FromPool `json:"ipAddressesFromIPPool,omitempty"` + + // PrefixesFromPool is the list of metadata items to be rendered as network prefixes. + // +optional + PrefixesFromPool []FromPool `json:"prefixesFromIPPool,omitempty"` + + // GatewaysFromPool is the list of metadata items to be rendered as gateway addresses. + // +optional + GatewaysFromPool []FromPool `json:"gatewaysFromIPPool,omitempty"` + + // DNSServersFromPool is the list of metadata items to be rendered as dns servers. + // +optional + DNSServersFromPool []FromPool `json:"dnsServersFromIPPool,omitempty"` + + // FromHostInterfaces is the list of metadata items to be rendered as MAC + // addresses of the host interfaces. + // +optional + FromHostInterfaces []MetaDataHostInterface `json:"fromHostInterfaces,omitempty"` + + // FromLabels is the list of metadata items to be fetched from object labels + // +optional + FromLabels []MetaDataFromLabel `json:"fromLabels,omitempty"` + + // FromAnnotations is the list of metadata items to be fetched from object + // Annotations + // +optional + FromAnnotations []MetaDataFromAnnotation `json:"fromAnnotations,omitempty"` + } + +#### data + // DataSpec defines the desired state of Data + type DataSpec struct { + // DataTemplate is the CUMetalDataTemplate this was generated from. + Template corev1.ObjectReference `json:"template"` + + // MetaData points to the rendered MetaData secret. + // +optional + MetaData *corev1.SecretReference `json:"metaData,omitempty"` + + // NetworkData points to the rendered NetworkData secret. + // +optional + NetworkData *corev1.SecretReference `json:"networkData,omitempty"` + + // NetworkData points to the rendered UserData secret. + // +optional + UserData *corev1.SecretReference `json:"userData,omitempty"` + } + + // DataStatus defines the observed state of Data + type DataStatus struct { + // Ready is a flag set to True if the secrets were rendered properly + // +optional + Ready bool `json:"ready"` + + // ErrorMessage contains the error message + // +optional + ErrorMessage *string `json:"errorMessage,omitempty"` + } From 9302c96ec482885d3883b11512300e993791221b Mon Sep 17 00:00:00 2001 From: sailorvii Date: Wed, 13 Jul 2022 09:11:52 +0800 Subject: [PATCH 2/3] Refine the format. --- design/metal3host-controller.md | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/design/metal3host-controller.md b/design/metal3host-controller.md index 7a489697..6d2ea00e 100644 --- a/design/metal3host-controller.md +++ b/design/metal3host-controller.md @@ -1,17 +1,28 @@ # Baremetal host single instance and multi-instance operator + ## Introduction + Currently, the metal3 system is to set up a Kubernetes cluster on bare-metal hosts which is tightly bound with cluster-api and Kubernetes. We target to allocate bare-metal hosts that just pre-installing the OS, or pre-installing the applications as required. + ## Motivation + To meet the scenery that only requires a pure bare-metal host or with a simple application installed. + ## Goals + - Allocate one pure bare-metal host - Allocate multiple bare-metal hosts - Allocate bare-metal host with pre-installed applications - Specify the different configurations for different bare-metal host + ## Non-goals + - Allocate different types of bare-metal hosts at one time + ## Proposal + ### Architecture + The operators include the metal3Host operator, metal3HostDeployment operator, and data operator. ![modules](images/metal3hostModules.png) @@ -22,19 +33,26 @@ Metal3Host is a virtual instance. Users could define it to require a bare-metal Metal3HostDeployment will define a group of metal3Hosts with the same configuration. It could define the number of replicas. It could scale up/down. We even could auto-scale by some rules after the monitor function is leveraged. The data operator will set up the boot time configuration & routine. It includes three parts: the userData, the metaData, and the networkData. The userData includes some user-specified data such as installing a package, or running a command like "mkdir /test". The metaData defines some host-specific data such as hostname. The networkData includes the network configuration. The data is bound with the baremetal host. For example, the networkData defines a NIC with an IP, the NIC name is host related. So a dataTemplate should be pre-defined, it will be bound to the bare-metal host when a metal3host is defined and associated with a bare-metal host. + ### Routine + #### Pre-define a dataTemplate + ![createDataTemplate](images/createDataTemplate.png) #### Require a metal3host + ![createMetal3Host](images/createMetal3Host.png) #### Require a metal3HostDeployment + ![createMetal3HostDeployment](images/createMetal3HostDeployment.png) ### Configuration + #### metal3host + '''golang // Metal3HostSpec defines the desired state of Metal3Host type Metal3HostSpec struct { // ProviderID will be the Metal3Host in ProviderID format @@ -66,9 +84,12 @@ The data operator will set up the boot time configuration & routine. It includes // +optional AutomatedCleaningMode *string `json:"automatedCleaningMode,omitempty"` } + ''' #### metal3hostDeployment - // Metal3HostDeploymentSpec defines the desired state of Metal3HostDeployment. + + '''golang + // Metal3HostDeploymentSpec defines the desired state of Metal3HostDeployment. type Metal3HostDeploymentSpec struct { // Number of desired machines. Defaults to 1. // This is a pointer to distinguish between explicit zero and not specified. @@ -155,8 +176,11 @@ The data operator will set up the boot time configuration & routine. It includes Conditions capi.Conditions `json:"conditions,omitempty"` } + ''' #### datatemplate + + '''golang // DataTemplateSpec defines the desired state of DataTemplate type DataTemplateSpec struct { //MetaData contains the information needed to generate the metadata secret @@ -254,8 +278,11 @@ The data operator will set up the boot time configuration & routine. It includes // +optional FromAnnotations []MetaDataFromAnnotation `json:"fromAnnotations,omitempty"` } + ''' #### data + + '''golang // DataSpec defines the desired state of Data type DataSpec struct { // DataTemplate is the CUMetalDataTemplate this was generated from. @@ -284,3 +311,4 @@ The data operator will set up the boot time configuration & routine. It includes // +optional ErrorMessage *string `json:"errorMessage,omitempty"` } + ''' From bf6f35ab55272f0c56ac28229afd8b21c32c4c52 Mon Sep 17 00:00:00 2001 From: sailorvii Date: Wed, 20 Jul 2022 10:09:37 +0800 Subject: [PATCH 3/3] Refine format --- design/metal3host-controller.md | 428 ++++++++++++++++---------------- 1 file changed, 214 insertions(+), 214 deletions(-) diff --git a/design/metal3host-controller.md b/design/metal3host-controller.md index 6d2ea00e..fa639c1e 100644 --- a/design/metal3host-controller.md +++ b/design/metal3host-controller.md @@ -4,16 +4,16 @@ Currently, the metal3 system is to set up a Kubernetes cluster on bare-metal hosts which is tightly bound with cluster-api and Kubernetes. We target to allocate bare-metal hosts that just pre-installing the OS, or pre-installing the applications as required. -## Motivation +## Motivation To meet the scenery that only requires a pure bare-metal host or with a simple application installed. ## Goals -- Allocate one pure bare-metal host +- Allocate one pure bare-metal host - Allocate multiple bare-metal hosts - Allocate bare-metal host with pre-installed applications -- Specify the different configurations for different bare-metal host +- Specify the different configurations for different bare-metal host ## Non-goals @@ -90,225 +90,225 @@ The data operator will set up the boot time configuration & routine. It includes '''golang // Metal3HostDeploymentSpec defines the desired state of Metal3HostDeployment. - type Metal3HostDeploymentSpec struct { - // Number of desired machines. Defaults to 1. - // This is a pointer to distinguish between explicit zero and not specified. - // +optional - // +kubebuilder:default=1 - Replicas *int32 `json:"replicas,omitempty"` - - // HostSelector specifies matching criteria for labels on BareMetalHosts. - // This is used to limit the set of BareMetalHost objects considered for - // claiming for a machine. - // +optional - HostSelector HostSelector `json:"hostSelector,omitempty"` - - // Template describes the metal3 hosts that will be created. - Template Metal3HostTemplateSpec `json:"template"` - - // Minimum number of seconds for which a newly created machine should - // be ready. - // Defaults to 0 (machine will be considered available as soon as it - // is ready) - // +optional - MinReadySeconds *int32 `json:"minReadySeconds,omitempty"` - - // The number of old MachineSets to retain to allow rollback. - // This is a pointer to distinguish between explicit zero and not specified. - // Defaults to 1. - // +optional - RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"` - - // Indicates that the deployment is paused. - // +optional - Paused bool `json:"paused,omitempty"` - - // The maximum time in seconds for a deployment to make progress before it - // is considered to be failed. The deployment controller will continue to - // process failed deployments and a condition with a ProgressDeadlineExceeded - // reason will be surfaced in the deployment status. Note that progress will - // not be estimated during the time a deployment is paused. Defaults to 600s. - // +optional - ProgressDeadlineSeconds *int32 `json:"progressDeadlineSeconds,omitempty"` - } - - // Metal3HostDeploymentStatus defines the observed state of Metal3HostDeployment. - type Metal3HostDeploymentStatus struct { - // The generation observed by the deployment controller. - // +optional - ObservedGeneration int64 `json:"observedGeneration,omitempty"` - - // Total number of non-terminated machines targeted by this deployment - // (their labels match the selector). - // +optional - Replicas int32 `json:"replicas"` - - // Total number of non-terminated machines targeted by this deployment - // that have the desired template spec. - // +optional - UpdatedReplicas int32 `json:"updatedReplicas"` - - // Total number of ready machines targeted by this deployment. - // +optional - ReadyReplicas int32 `json:"readyReplicas"` - - // Total number of available machines (ready for at least minReadySeconds) - // targeted by this deployment. - // +optional - AvailableReplicas int32 `json:"availableReplicas"` - - // Total number of unavailable machines targeted by this deployment. - // This is the total number of machines that are still required for - // the deployment to have 100% available capacity. They may either - // be machines that are running but not yet available or machines - // that still have not been created. - // +optional - UnavailableReplicas int32 `json:"unavailableReplicas"` - - // Phase represents the current phase of a Metal3HostDeployment (ScalingUp, ScalingDown, Running, Failed, or Unknown). - // +optional - Phase string `json:"phase,omitempty"` - - // FailureReason indicates that there is a fatal problem reconciling the - // state, and will be set to a descriptive error message. - // +optional - FailureReason *string `json:"failureReason,omitempty"` - - Conditions capi.Conditions `json:"conditions,omitempty"` - } + type Metal3HostDeploymentSpec struct { + // Number of desired machines. Defaults to 1. + // This is a pointer to distinguish between explicit zero and not specified. + // +optional + // +kubebuilder:default=1 + Replicas *int32 `json:"replicas,omitempty"` + + // HostSelector specifies matching criteria for labels on BareMetalHosts. + // This is used to limit the set of BareMetalHost objects considered for + // claiming for a machine. + // +optional + HostSelector HostSelector `json:"hostSelector,omitempty"` + + // Template describes the metal3 hosts that will be created. + Template Metal3HostTemplateSpec `json:"template"` + + // Minimum number of seconds for which a newly created machine should + // be ready. + // Defaults to 0 (machine will be considered available as soon as it + // is ready) + // +optional + MinReadySeconds *int32 `json:"minReadySeconds,omitempty"` + + // The number of old MachineSets to retain to allow rollback. + // This is a pointer to distinguish between explicit zero and not specified. + // Defaults to 1. + // +optional + RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"` + + // Indicates that the deployment is paused. + // +optional + Paused bool `json:"paused,omitempty"` + + // The maximum time in seconds for a deployment to make progress before it + // is considered to be failed. The deployment controller will continue to + // process failed deployments and a condition with a ProgressDeadlineExceeded + // reason will be surfaced in the deployment status. Note that progress will + // not be estimated during the time a deployment is paused. Defaults to 600s. + // +optional + ProgressDeadlineSeconds *int32 `json:"progressDeadlineSeconds,omitempty"` + } + + // Metal3HostDeploymentStatus defines the observed state of Metal3HostDeployment. + type Metal3HostDeploymentStatus struct { + // The generation observed by the deployment controller. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // Total number of non-terminated machines targeted by this deployment + // (their labels match the selector). + // +optional + Replicas int32 `json:"replicas"` + + // Total number of non-terminated machines targeted by this deployment + // that have the desired template spec. + // +optional + UpdatedReplicas int32 `json:"updatedReplicas"` + + // Total number of ready machines targeted by this deployment. + // +optional + ReadyReplicas int32 `json:"readyReplicas"` + + // Total number of available machines (ready for at least minReadySeconds) + // targeted by this deployment. + // +optional + AvailableReplicas int32 `json:"availableReplicas"` + + // Total number of unavailable machines targeted by this deployment. + // This is the total number of machines that are still required for + // the deployment to have 100% available capacity. They may either + // be machines that are running but not yet available or machines + // that still have not been created. + // +optional + UnavailableReplicas int32 `json:"unavailableReplicas"` + + // Phase represents the current phase of a Metal3HostDeployment (ScalingUp, ScalingDown, Running, Failed, or Unknown). + // +optional + Phase string `json:"phase,omitempty"` + + // FailureReason indicates that there is a fatal problem reconciling the + // state, and will be set to a descriptive error message. + // +optional + FailureReason *string `json:"failureReason,omitempty"` + + Conditions capi.Conditions `json:"conditions,omitempty"` + } ''' #### datatemplate '''golang - // DataTemplateSpec defines the desired state of DataTemplate - type DataTemplateSpec struct { - //MetaData contains the information needed to generate the metadata secret - // +optional - MetaData *MetaData `json:"metaData,omitempty"` - - //NetworkData contains the information needed to generate the networkdata - // secret - // +optional - NetworkData *NetworkData `json:"networkData,omitempty"` - - //UserData contains the information defined by user - // secret - // +optional - UserData *UserData `json:"userData,omitempty"` - } - - // NetworkData represents a networkData object - type NetworkData struct { - // Links is a structure containing lists of different types objects - // +optional - Links NetworkDataLink `json:"links,omitempty"` - - //Networks is a structure containing lists of different types objects - // +optional - Networks NetworkDataNetwork `json:"networks,omitempty"` - - //Services is a structure containing lists of different types objects - // +optional - Services NetworkDataService `json:"services,omitempty"` - } - - // UserData contains the information defined by user - type UserData struct { - //Users define the user&password information - // +optional - Users []User `json:"users"` - - //WriteFile files to be created at the boot time - // +optional - WriteFiles []WriteFile `json:"write_files"` - - //BootCmd commands to be run at the boot time - // +optional - BootCmd []string `json:"bootcmd"` - } - - // MetaData represents a keyand value of the metadata - type MetaData struct { - // Strings is the list of metadata items to be rendered from strings - // +optional - Strings []MetaDataString `json:"strings,omitempty"` - - // ObjectNames is the list of metadata items to be rendered from the name - // of objects. - // +optional - ObjectNames []MetaDataObjectName `json:"objectNames,omitempty"` - - // Indexes is the list of metadata items to be rendered from the index of the - // CUMetalData - // +optional - Indexes []MetaDataIndex `json:"indexes,omitempty"` - - // Namespaces is the list of metadata items to be rendered from the namespace - // +optional - Namespaces []MetaDataNamespace `json:"namespaces,omitempty"` - - // IPAddressesFromPool is the list of metadata items to be rendered as ip addresses. - // +optional - IPAddressesFromPool []FromPool `json:"ipAddressesFromIPPool,omitempty"` - - // PrefixesFromPool is the list of metadata items to be rendered as network prefixes. - // +optional - PrefixesFromPool []FromPool `json:"prefixesFromIPPool,omitempty"` - - // GatewaysFromPool is the list of metadata items to be rendered as gateway addresses. - // +optional - GatewaysFromPool []FromPool `json:"gatewaysFromIPPool,omitempty"` - - // DNSServersFromPool is the list of metadata items to be rendered as dns servers. - // +optional - DNSServersFromPool []FromPool `json:"dnsServersFromIPPool,omitempty"` - - // FromHostInterfaces is the list of metadata items to be rendered as MAC - // addresses of the host interfaces. - // +optional - FromHostInterfaces []MetaDataHostInterface `json:"fromHostInterfaces,omitempty"` - - // FromLabels is the list of metadata items to be fetched from object labels - // +optional - FromLabels []MetaDataFromLabel `json:"fromLabels,omitempty"` - - // FromAnnotations is the list of metadata items to be fetched from object - // Annotations - // +optional - FromAnnotations []MetaDataFromAnnotation `json:"fromAnnotations,omitempty"` - } + // DataTemplateSpec defines the desired state of DataTemplate + type DataTemplateSpec struct { + //MetaData contains the information needed to generate the metadata secret + // +optional + MetaData *MetaData `json:"metaData,omitempty"` + + //NetworkData contains the information needed to generate the networkdata + // secret + // +optional + NetworkData *NetworkData `json:"networkData,omitempty"` + + //UserData contains the information defined by user + // secret + // +optional + UserData *UserData `json:"userData,omitempty"` + } + + // NetworkData represents a networkData object + type NetworkData struct { + // Links is a structure containing lists of different types objects + // +optional + Links NetworkDataLink `json:"links,omitempty"` + + //Networks is a structure containing lists of different types objects + // +optional + Networks NetworkDataNetwork `json:"networks,omitempty"` + + //Services is a structure containing lists of different types objects + // +optional + Services NetworkDataService `json:"services,omitempty"` + } + + // UserData contains the information defined by user + type UserData struct { + //Users define the user&password information + // +optional + Users []User `json:"users"` + + //WriteFile files to be created at the boot time + // +optional + WriteFiles []WriteFile `json:"write_files"` + + //BootCmd commands to be run at the boot time + // +optional + BootCmd []string `json:"bootcmd"` + } + + // MetaData represents a keyand value of the metadata + type MetaData struct { + // Strings is the list of metadata items to be rendered from strings + // +optional + Strings []MetaDataString `json:"strings,omitempty"` + + // ObjectNames is the list of metadata items to be rendered from the name + // of objects. + // +optional + ObjectNames []MetaDataObjectName `json:"objectNames,omitempty"` + + // Indexes is the list of metadata items to be rendered from the index of the + // CUMetalData + // +optional + Indexes []MetaDataIndex `json:"indexes,omitempty"` + + // Namespaces is the list of metadata items to be rendered from the namespace + // +optional + Namespaces []MetaDataNamespace `json:"namespaces,omitempty"` + + // IPAddressesFromPool is the list of metadata items to be rendered as ip addresses. + // +optional + IPAddressesFromPool []FromPool `json:"ipAddressesFromIPPool,omitempty"` + + // PrefixesFromPool is the list of metadata items to be rendered as network prefixes. + // +optional + PrefixesFromPool []FromPool `json:"prefixesFromIPPool,omitempty"` + + // GatewaysFromPool is the list of metadata items to be rendered as gateway addresses. + // +optional + GatewaysFromPool []FromPool `json:"gatewaysFromIPPool,omitempty"` + + // DNSServersFromPool is the list of metadata items to be rendered as dns servers. + // +optional + DNSServersFromPool []FromPool `json:"dnsServersFromIPPool,omitempty"` + + // FromHostInterfaces is the list of metadata items to be rendered as MAC + // addresses of the host interfaces. + // +optional + FromHostInterfaces []MetaDataHostInterface `json:"fromHostInterfaces,omitempty"` + + // FromLabels is the list of metadata items to be fetched from object labels + // +optional + FromLabels []MetaDataFromLabel `json:"fromLabels,omitempty"` + + // FromAnnotations is the list of metadata items to be fetched from object + // Annotations + // +optional + FromAnnotations []MetaDataFromAnnotation `json:"fromAnnotations,omitempty"` + } ''' #### data '''golang - // DataSpec defines the desired state of Data - type DataSpec struct { - // DataTemplate is the CUMetalDataTemplate this was generated from. - Template corev1.ObjectReference `json:"template"` - - // MetaData points to the rendered MetaData secret. - // +optional - MetaData *corev1.SecretReference `json:"metaData,omitempty"` - - // NetworkData points to the rendered NetworkData secret. - // +optional - NetworkData *corev1.SecretReference `json:"networkData,omitempty"` - - // NetworkData points to the rendered UserData secret. - // +optional - UserData *corev1.SecretReference `json:"userData,omitempty"` - } - - // DataStatus defines the observed state of Data - type DataStatus struct { - // Ready is a flag set to True if the secrets were rendered properly - // +optional - Ready bool `json:"ready"` - - // ErrorMessage contains the error message - // +optional - ErrorMessage *string `json:"errorMessage,omitempty"` - } + // DataSpec defines the desired state of Data + type DataSpec struct { + // DataTemplate is the CUMetalDataTemplate this was generated from. + Template corev1.ObjectReference `json:"template"` + + // MetaData points to the rendered MetaData secret. + // +optional + MetaData *corev1.SecretReference `json:"metaData,omitempty"` + + // NetworkData points to the rendered NetworkData secret. + // +optional + NetworkData *corev1.SecretReference `json:"networkData,omitempty"` + + // NetworkData points to the rendered UserData secret. + // +optional + UserData *corev1.SecretReference `json:"userData,omitempty"` + } + + // DataStatus defines the observed state of Data + type DataStatus struct { + // Ready is a flag set to True if the secrets were rendered properly + // +optional + Ready bool `json:"ready"` + + // ErrorMessage contains the error message + // +optional + ErrorMessage *string `json:"errorMessage,omitempty"` + } '''