From bf99eccd4851a1c481e58d7b4ef2ee09db6beec9 Mon Sep 17 00:00:00 2001 From: Gerard de Leeuw Date: Mon, 31 Jan 2022 16:05:16 +0100 Subject: [PATCH] feat: add extended hardware information to Server and ServerClass CRDs This change adds detailed hardware information to the Server CRD. Hardware info is extracted by the agent from SMBIOS. The ServerClass CRD is also updated so more precise qualifiers can be used. Signed-off-by: Gerard de Leeuw --- Dockerfile | 1 + .../config/certmanager/certificate.yaml | 14 +- .../patches/cainjection_in_metalclusters.yaml | 2 +- .../patches/cainjection_in_metalmachines.yaml | 2 +- .../cainjection_in_metalmachinetemplates.yaml | 2 +- .../cainjection_in_serverbindings.yaml | 2 +- .../config/default/kustomization.yaml | 16 +- .../config/default/manager_webhook_patch.yaml | 2 +- .../default/webhookcainjection_patch.yaml | 6 +- .../config/webhook/kustomization.yaml | 2 +- .../config/webhook/service.yaml | 3 +- .../controllers/metalmachine_controller.go | 14 +- .../controllers/serverbinding_controller.go | 6 +- app/caps-controller-manager/main.go | 2 + app/sidero-controller-manager/PROJECT | 9 + .../api/v1alpha1/doc.go | 7 + .../api/v1alpha1/environment_conversion.go | 56 + .../api/v1alpha1/groupversion_info.go | 3 + .../api/v1alpha1/server_conversion.go | 130 ++ .../api/v1alpha1/serverclass_conversion.go | 124 ++ .../api/v1alpha1/zz_generated.conversion.go | 886 +++++++++++ .../api/v1alpha2/doc.go | 5 + .../api/v1alpha2/environment_conversion.go | 8 + .../api/v1alpha2/environment_types.go | 123 ++ .../api/v1alpha2/groupversion_info.go | 24 + .../api/v1alpha2/server_conversion.go | 8 + .../api/v1alpha2/server_types.go | 328 ++++ .../api/v1alpha2/server_types_test.go | 147 ++ .../api/v1alpha2/serverclass_conversion.go | 8 + .../api/v1alpha2/serverclass_filter.go | 110 ++ .../api/v1alpha2/serverclass_filter_test.go | 378 +++++ .../api/v1alpha2/serverclass_types.go | 84 + .../api/v1alpha2/types.go | 16 + .../api/v1alpha2/zz_generated.deepcopy.go | 771 ++++++++++ .../cmd/agent/main.go | 223 ++- .../cmd/agent/main_test.go | 14 + .../config/certmanager/certificate.yaml | 15 +- .../config/certmanager/kustomization.yaml | 5 +- .../config/certmanager/kustomizeconfig.yaml | 27 +- .../bases/metal.sidero.dev_environments.yaml | 81 + .../bases/metal.sidero.dev_serverclasses.yaml | 315 ++++ .../crd/bases/metal.sidero.dev_servers.yaml | 446 ++++++ .../config/crd/kustomization.yaml | 30 +- .../config/crd/kustomizeconfig.yaml | 22 +- .../patches/cainjection_in_environments.yaml | 4 +- .../patches/cainjection_in_serverclasses.yaml | 4 +- .../crd/patches/cainjection_in_servers.yaml | 4 +- .../crd/patches/webhook_in_environments.yaml | 20 +- .../crd/patches/webhook_in_serverclasses.yaml | 20 +- .../crd/patches/webhook_in_servers.yaml | 20 +- .../config/default/kustomization.yaml | 65 + .../config/default/kustomizeconfig.yaml | 4 + .../config/default/manager_webhook_patch.yaml | 23 + .../webhookcainjection_patch.yaml | 6 +- .../config/kustomization.yaml | 67 - .../config/manager/manager.yaml | 2 + .../config/manager_webhook_patch.yaml | 23 - .../config/prometheus/monitor.yaml | 4 +- .../config/rbac/auth_proxy_service.yaml | 4 +- .../config/samples/metal_v1alpha1_server.yaml | 27 - .../samples/metal_v1alpha1_serverclass.yaml | 29 - ...t.yaml => metal_v1alpha2_environment.yaml} | 2 +- .../config/samples/metal_v1alpha2_server.yaml | 77 + .../samples/metal_v1alpha2_serverclass.yaml | 27 + .../config/webhook/service.yaml | 4 +- .../controllers/environment_controller.go | 24 +- .../controllers/server_controller.go | 20 +- .../controllers/serverclass_controller.go | 28 +- .../controllers/suite_test.go | 6 +- .../internal/api/api.pb.go | 1359 ++++++++++++++--- .../internal/api/api.proto | 84 +- .../internal/ipxe/ipxe_server.go | 48 +- .../internal/metadata/metadata_server.go | 26 +- .../internal/power/api/api.go | 4 +- .../internal/power/factory.go | 4 +- .../internal/power/ipmi/ipmi.go | 4 +- .../internal/server/server.go | 145 +- app/sidero-controller-manager/main.go | 6 +- config/kustomization.yaml | 2 +- go.mod | 2 +- go.sum | 4 +- internal/client/client.go | 8 +- sfyra/go.sum | 1 + sfyra/pkg/capi/capi.go | 1 + sfyra/pkg/capi/cluster.go | 8 +- sfyra/pkg/capi/metalclient.go | 8 +- sfyra/pkg/constants/constants.go | 2 +- sfyra/pkg/loadbalancer/loadbalancer.go | 8 +- sfyra/pkg/tests/compatibility.go | 14 +- sfyra/pkg/tests/environment.go | 27 +- sfyra/pkg/tests/match.go | 4 +- sfyra/pkg/tests/reconcile.go | 14 +- sfyra/pkg/tests/reset.go | 8 +- sfyra/pkg/tests/server.go | 100 +- sfyra/pkg/tests/server_class.go | 56 +- templates/cluster-template-talos-v0.13.4.yaml | 4 +- templates/cluster-template.yaml | 4 +- .../Getting Started/install-clusterapi.md | 1 + .../content/docs/v0.5/Guides/bootstrapping.md | 1 + website/content/docs/v0.5/Guides/patching.md | 2 +- .../docs/v0.5/Guides/sidero-on-rpi4.md | 2 +- .../docs/v0.5/Overview/installation.md | 1 + .../Resource Configuration/environments.md | 6 +- .../v0.5/Resource Configuration/metadata.md | 26 +- .../Resource Configuration/serverclasses.md | 35 +- .../v0.5/Resource Configuration/servers.md | 75 +- 106 files changed, 6263 insertions(+), 832 deletions(-) create mode 100644 app/sidero-controller-manager/api/v1alpha1/doc.go create mode 100644 app/sidero-controller-manager/api/v1alpha1/environment_conversion.go create mode 100644 app/sidero-controller-manager/api/v1alpha1/server_conversion.go create mode 100644 app/sidero-controller-manager/api/v1alpha1/serverclass_conversion.go create mode 100644 app/sidero-controller-manager/api/v1alpha1/zz_generated.conversion.go create mode 100644 app/sidero-controller-manager/api/v1alpha2/doc.go create mode 100644 app/sidero-controller-manager/api/v1alpha2/environment_conversion.go create mode 100644 app/sidero-controller-manager/api/v1alpha2/environment_types.go create mode 100644 app/sidero-controller-manager/api/v1alpha2/groupversion_info.go create mode 100644 app/sidero-controller-manager/api/v1alpha2/server_conversion.go create mode 100644 app/sidero-controller-manager/api/v1alpha2/server_types.go create mode 100644 app/sidero-controller-manager/api/v1alpha2/server_types_test.go create mode 100644 app/sidero-controller-manager/api/v1alpha2/serverclass_conversion.go create mode 100644 app/sidero-controller-manager/api/v1alpha2/serverclass_filter.go create mode 100644 app/sidero-controller-manager/api/v1alpha2/serverclass_filter_test.go create mode 100644 app/sidero-controller-manager/api/v1alpha2/serverclass_types.go create mode 100644 app/sidero-controller-manager/api/v1alpha2/types.go create mode 100644 app/sidero-controller-manager/api/v1alpha2/zz_generated.deepcopy.go create mode 100644 app/sidero-controller-manager/cmd/agent/main_test.go create mode 100644 app/sidero-controller-manager/config/default/kustomization.yaml create mode 100644 app/sidero-controller-manager/config/default/kustomizeconfig.yaml create mode 100644 app/sidero-controller-manager/config/default/manager_webhook_patch.yaml rename app/sidero-controller-manager/config/{ => default}/webhookcainjection_patch.yaml (54%) delete mode 100644 app/sidero-controller-manager/config/kustomization.yaml delete mode 100644 app/sidero-controller-manager/config/manager_webhook_patch.yaml delete mode 100644 app/sidero-controller-manager/config/samples/metal_v1alpha1_server.yaml delete mode 100644 app/sidero-controller-manager/config/samples/metal_v1alpha1_serverclass.yaml rename app/sidero-controller-manager/config/samples/{metal_v1alpha1_environment.yaml => metal_v1alpha2_environment.yaml} (95%) create mode 100644 app/sidero-controller-manager/config/samples/metal_v1alpha2_server.yaml create mode 100644 app/sidero-controller-manager/config/samples/metal_v1alpha2_serverclass.yaml diff --git a/Dockerfile b/Dockerfile index 24b427f44..0678bbc1c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -79,6 +79,7 @@ RUN protoc -I/src/app/sidero-controller-manager/internal/api \ api.proto RUN --mount=type=cache,target=/.cache controller-gen object:headerFile="./hack/boilerplate.go.txt" paths="./..." RUN --mount=type=cache,target=/.cache conversion-gen --input-dirs="./app/caps-controller-manager/api/v1alpha2" --output-base ./ --output-file-base="zz_generated.conversion" --go-header-file="./hack/boilerplate.go.txt" +RUN --mount=type=cache,target=/.cache conversion-gen --input-dirs="./app/sidero-controller-manager/api/v1alpha1" --output-base ./ --output-file-base="zz_generated.conversion" --go-header-file="./hack/boilerplate.go.txt" ARG MODULE RUN --mount=type=cache,target=/.cache gofumports -w -local ${MODULE} . diff --git a/app/caps-controller-manager/config/certmanager/certificate.yaml b/app/caps-controller-manager/config/certmanager/certificate.yaml index ffcc81068..6f2d8bb24 100644 --- a/app/caps-controller-manager/config/certmanager/certificate.yaml +++ b/app/caps-controller-manager/config/certmanager/certificate.yaml @@ -3,7 +3,7 @@ apiVersion: cert-manager.io/v1 kind: Issuer metadata: - name: selfsigned-issuer + name: caps-selfsigned-issuer namespace: system spec: selfSigned: {} @@ -11,14 +11,14 @@ spec: apiVersion: cert-manager.io/v1 kind: Certificate metadata: - name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml + name: caps-serving-cert # this name should match the one appeared in kustomizeconfig.yaml namespace: system spec: - # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize + # $(CAPS_WEBHOOK_SERVICE_NAME) and $(CAPS_WEBHOOK_SERVICE_NAMESPACE) will be substituted by kustomize dnsNames: - - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc - - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local + - $(CAPS_WEBHOOK_SERVICE_NAME).$(CAPS_WEBHOOK_SERVICE_NAMESPACE).svc + - $(CAPS_WEBHOOK_SERVICE_NAME).$(CAPS_WEBHOOK_SERVICE_NAMESPACE).svc.cluster.local issuerRef: kind: Issuer - name: selfsigned-issuer - secretName: $(SERVICE_NAME)-cert + name: caps-selfsigned-issuer + secretName: $(CAPS_WEBHOOK_SERVICE_NAME)-cert diff --git a/app/caps-controller-manager/config/crd/patches/cainjection_in_metalclusters.yaml b/app/caps-controller-manager/config/crd/patches/cainjection_in_metalclusters.yaml index 15eca0ad9..934af3d5c 100644 --- a/app/caps-controller-manager/config/crd/patches/cainjection_in_metalclusters.yaml +++ b/app/caps-controller-manager/config/crd/patches/cainjection_in_metalclusters.yaml @@ -4,5 +4,5 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + cert-manager.io/inject-ca-from: $(CAPS_CERTIFICATE_NAMESPACE)/$(CAPS_CERTIFICATE_NAME) name: metalclusters.infrastructure.cluster.x-k8s.io diff --git a/app/caps-controller-manager/config/crd/patches/cainjection_in_metalmachines.yaml b/app/caps-controller-manager/config/crd/patches/cainjection_in_metalmachines.yaml index 60e45bb08..cb74e55ee 100644 --- a/app/caps-controller-manager/config/crd/patches/cainjection_in_metalmachines.yaml +++ b/app/caps-controller-manager/config/crd/patches/cainjection_in_metalmachines.yaml @@ -4,5 +4,5 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + cert-manager.io/inject-ca-from: $(CAPS_CERTIFICATE_NAMESPACE)/$(CAPS_CERTIFICATE_NAME) name: metalmachines.infrastructure.cluster.x-k8s.io diff --git a/app/caps-controller-manager/config/crd/patches/cainjection_in_metalmachinetemplates.yaml b/app/caps-controller-manager/config/crd/patches/cainjection_in_metalmachinetemplates.yaml index 4cde96e95..fe04a9d22 100644 --- a/app/caps-controller-manager/config/crd/patches/cainjection_in_metalmachinetemplates.yaml +++ b/app/caps-controller-manager/config/crd/patches/cainjection_in_metalmachinetemplates.yaml @@ -4,5 +4,5 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + cert-manager.io/inject-ca-from: $(CAPS_CERTIFICATE_NAMESPACE)/$(CAPS_CERTIFICATE_NAME) name: metalmachinetemplates.infrastructure.cluster.x-k8s.io diff --git a/app/caps-controller-manager/config/crd/patches/cainjection_in_serverbindings.yaml b/app/caps-controller-manager/config/crd/patches/cainjection_in_serverbindings.yaml index a09654b20..242c41e14 100644 --- a/app/caps-controller-manager/config/crd/patches/cainjection_in_serverbindings.yaml +++ b/app/caps-controller-manager/config/crd/patches/cainjection_in_serverbindings.yaml @@ -4,5 +4,5 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + cert-manager.io/inject-ca-from: $(CAPS_CERTIFICATE_NAMESPACE)/$(CAPS_CERTIFICATE_NAME) name: serverbindings.infrastructure.cluster.x-k8s.io diff --git a/app/caps-controller-manager/config/default/kustomization.yaml b/app/caps-controller-manager/config/default/kustomization.yaml index 806f302ef..74410fca9 100644 --- a/app/caps-controller-manager/config/default/kustomization.yaml +++ b/app/caps-controller-manager/config/default/kustomization.yaml @@ -18,32 +18,32 @@ patchesStrategicMerge: # - webhookcainjection_patch.yaml vars: - - name: CERTIFICATE_NAMESPACE # namespace of the certificate CR + - name: CAPS_CERTIFICATE_NAMESPACE # namespace of the certificate CR objref: kind: Certificate group: cert-manager.io version: v1 - name: serving-cert # this name should match the one in certificate.yaml + name: caps-serving-cert # this name should match the one in certificate.yaml fieldref: fieldpath: metadata.namespace - - name: CERTIFICATE_NAME + - name: CAPS_CERTIFICATE_NAME objref: kind: Certificate group: cert-manager.io version: v1 - name: serving-cert # this name should match the one in certificate.yaml - - name: SERVICE_NAMESPACE # namespace of the service + name: caps-serving-cert # this name should match the one in certificate.yaml + - name: CAPS_WEBHOOK_SERVICE_NAMESPACE # namespace of the service objref: kind: Service version: v1 - name: webhook-service + name: caps-webhook-service fieldref: fieldpath: metadata.namespace - - name: SERVICE_NAME + - name: CAPS_WEBHOOK_SERVICE_NAME objref: kind: Service version: v1 - name: webhook-service + name: caps-webhook-service configurations: - kustomizeconfig.yaml diff --git a/app/caps-controller-manager/config/default/manager_webhook_patch.yaml b/app/caps-controller-manager/config/default/manager_webhook_patch.yaml index 35e2de074..bb5580913 100644 --- a/app/caps-controller-manager/config/default/manager_webhook_patch.yaml +++ b/app/caps-controller-manager/config/default/manager_webhook_patch.yaml @@ -20,4 +20,4 @@ spec: - name: cert secret: defaultMode: 420 - secretName: $(SERVICE_NAME)-cert + secretName: $(CAPS_WEBHOOK_SERVICE_NAME)-cert diff --git a/app/caps-controller-manager/config/default/webhookcainjection_patch.yaml b/app/caps-controller-manager/config/default/webhookcainjection_patch.yaml index 7e79bf995..0f6a3fd03 100644 --- a/app/caps-controller-manager/config/default/webhookcainjection_patch.yaml +++ b/app/caps-controller-manager/config/default/webhookcainjection_patch.yaml @@ -1,15 +1,15 @@ # This patch add annotation to admission webhook config and -# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. +# the variables $(CAPS_CERTIFICATE_NAMESPACE) and $(CAPS_CERTIFICATE_NAME) will be substituted by kustomize. apiVersion: admissionregistration.k8s.io/v1beta1 kind: MutatingWebhookConfiguration metadata: name: mutating-webhook-configuration annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + cert-manager.io/inject-ca-from: $(CAPS_CERTIFICATE_NAMESPACE)/$(CAPS_CERTIFICATE_NAME) --- apiVersion: admissionregistration.k8s.io/v1beta1 kind: ValidatingWebhookConfiguration metadata: name: validating-webhook-configuration annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + cert-manager.io/inject-ca-from: $(CAPS_CERTIFICATE_NAMESPACE)/$(CAPS_CERTIFICATE_NAME) diff --git a/app/caps-controller-manager/config/webhook/kustomization.yaml b/app/caps-controller-manager/config/webhook/kustomization.yaml index 40947312a..7ed6560ae 100644 --- a/app/caps-controller-manager/config/webhook/kustomization.yaml +++ b/app/caps-controller-manager/config/webhook/kustomization.yaml @@ -2,4 +2,4 @@ resources: - service.yaml configurations: - - kustomizeconfig.yaml \ No newline at end of file + - kustomizeconfig.yaml diff --git a/app/caps-controller-manager/config/webhook/service.yaml b/app/caps-controller-manager/config/webhook/service.yaml index d4e830243..7a9881f66 100644 --- a/app/caps-controller-manager/config/webhook/service.yaml +++ b/app/caps-controller-manager/config/webhook/service.yaml @@ -1,8 +1,7 @@ - apiVersion: v1 kind: Service metadata: - name: webhook-service + name: caps-webhook-service namespace: system spec: ports: diff --git a/app/caps-controller-manager/controllers/metalmachine_controller.go b/app/caps-controller-manager/controllers/metalmachine_controller.go index 8e53e3703..9c61ccc95 100644 --- a/app/caps-controller-manager/controllers/metalmachine_controller.go +++ b/app/caps-controller-manager/controllers/metalmachine_controller.go @@ -35,7 +35,7 @@ import ( infrav1 "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" "github.com/talos-systems/sidero/app/caps-controller-manager/pkg/constants" - metalv1alpha1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" ) var ErrNoServersInServerClass = errors.New("no servers available in serverclass") @@ -265,7 +265,7 @@ func (r *MetalMachineReconciler) SetupWithManager(ctx context.Context, mgr ctrl. Complete(r) } -func (r *MetalMachineReconciler) fetchServerFromClass(ctx context.Context, logger logr.Logger, classRef *corev1.ObjectReference, metalMachine *infrav1.MetalMachine) (*metalv1alpha1.Server, error) { +func (r *MetalMachineReconciler) fetchServerFromClass(ctx context.Context, logger logr.Logger, classRef *corev1.ObjectReference, metalMachine *infrav1.MetalMachine) (*metalv1.Server, error) { // First, check if there is already existing serverBinding for this metalmachine var serverBindingList infrav1.ServerBindingList @@ -276,7 +276,7 @@ func (r *MetalMachineReconciler) fetchServerFromClass(ctx context.Context, logge for _, serverBinding := range serverBindingList.Items { if serverBinding.Spec.MetalMachineRef.Namespace == metalMachine.Namespace && serverBinding.Spec.MetalMachineRef.Name == metalMachine.Name { // found existing serverBinding for this metalMachine - var server metalv1alpha1.Server + var server metalv1.Server if err := r.Get(ctx, types.NamespacedName{Namespace: serverBinding.Namespace, Name: serverBinding.Name}, &server); err != nil { return nil, err @@ -302,7 +302,7 @@ func (r *MetalMachineReconciler) fetchServerFromClass(ctx context.Context, logge // NB: we added this loop to double check that an available server isn't "in use" because // we saw raciness between server selection and it being removed from the ServersAvailable list. for _, availServer := range serverClassResource.Status.ServersAvailable { - serverObj := &metalv1alpha1.Server{} + serverObj := &metalv1.Server{} namespacedName := types.NamespacedName{ Namespace: "", @@ -408,7 +408,7 @@ func (r *MetalMachineReconciler) patchProviderID(ctx context.Context, cluster *c } // createServerBinding updates a server to mark it as "in use" via ServerBinding resource. -func (r *MetalMachineReconciler) createServerBinding(ctx context.Context, serverClass *metalv1alpha1.ServerClass, serverObj *metalv1alpha1.Server, metalMachine *infrav1.MetalMachine) error { +func (r *MetalMachineReconciler) createServerBinding(ctx context.Context, serverClass *metalv1.ServerClass, serverObj *metalv1.Server, metalMachine *infrav1.MetalMachine) error { serverRef, err := reference.GetReference(r.Scheme, serverObj) if err != nil { return err @@ -445,8 +445,8 @@ func (r *MetalMachineReconciler) createServerBinding(ctx context.Context, server return err } -func (r *MetalMachineReconciler) fetchServerClass(ctx context.Context, classRef *corev1.ObjectReference) (*metalv1alpha1.ServerClass, error) { - serverClassResource := &metalv1alpha1.ServerClass{} +func (r *MetalMachineReconciler) fetchServerClass(ctx context.Context, classRef *corev1.ObjectReference) (*metalv1.ServerClass, error) { + serverClassResource := &metalv1.ServerClass{} namespacedName := types.NamespacedName{ Namespace: classRef.Namespace, diff --git a/app/caps-controller-manager/controllers/serverbinding_controller.go b/app/caps-controller-manager/controllers/serverbinding_controller.go index 0917bf6c2..27cfab8a6 100644 --- a/app/caps-controller-manager/controllers/serverbinding_controller.go +++ b/app/caps-controller-manager/controllers/serverbinding_controller.go @@ -23,7 +23,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/source" infrav1 "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" - metalv1alpha1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" ) // ServerBindingReconciler reconciles a ServerBinding object. @@ -75,7 +75,7 @@ func (r *ServerBindingReconciler) Reconcile(ctx context.Context, req ctrl.Reques } }() - var server metalv1alpha1.Server + var server metalv1.Server err = r.Get(ctx, req.NamespacedName, &server) if err != nil { @@ -190,7 +190,7 @@ func (r *ServerBindingReconciler) reconcileTransition(ctx context.Context, logge return ctrl.Result{}, nil } - var server metalv1alpha1.Server + var server metalv1.Server if err = r.Get(ctx, req.NamespacedName, &server); err != nil { if apierrors.IsNotFound(err) { diff --git a/app/caps-controller-manager/main.go b/app/caps-controller-manager/main.go index 4a53b13e8..cba399491 100644 --- a/app/caps-controller-manager/main.go +++ b/app/caps-controller-manager/main.go @@ -25,6 +25,7 @@ import ( infrav1alpha3 "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" "github.com/talos-systems/sidero/app/caps-controller-manager/controllers" metalv1alpha1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + metalv1alpha2 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" // +kubebuilder:scaffold:imports ) @@ -45,6 +46,7 @@ func init() { _ = infrav1alpha2.AddToScheme(scheme) _ = infrav1alpha3.AddToScheme(scheme) _ = metalv1alpha1.AddToScheme(scheme) + _ = metalv1alpha2.AddToScheme(scheme) // +kubebuilder:scaffold:scheme } diff --git a/app/sidero-controller-manager/PROJECT b/app/sidero-controller-manager/PROJECT index 6bf695d0a..1472e279c 100644 --- a/app/sidero-controller-manager/PROJECT +++ b/app/sidero-controller-manager/PROJECT @@ -10,4 +10,13 @@ resources: - group: metal kind: ServerClass version: v1alpha1 +- group: metal + kind: Environment + version: v1alpha2 +- group: metal + kind: Server + version: v1alpha2 +- group: metal + kind: ServerClass + version: v1alpha2 version: "2" diff --git a/app/sidero-controller-manager/api/v1alpha1/doc.go b/app/sidero-controller-manager/api/v1alpha1/doc.go new file mode 100644 index 000000000..5aac563b1 --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha1/doc.go @@ -0,0 +1,7 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package v1alpha1 + +// +k8s:conversion-gen=github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2 diff --git a/app/sidero-controller-manager/api/v1alpha1/environment_conversion.go b/app/sidero-controller-manager/api/v1alpha1/environment_conversion.go new file mode 100644 index 000000000..924bc0b2f --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha1/environment_conversion.go @@ -0,0 +1,56 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +//nolint:golint,stylecheck +package v1alpha1 + +import ( + utilconversion "sigs.k8s.io/cluster-api/util/conversion" + "sigs.k8s.io/controller-runtime/pkg/conversion" + + metalv1alpha2 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" +) + +// ConvertTo converts this Environment to the Hub version (v1alpha2). +func (src *Environment) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*metalv1alpha2.Environment) + if err := Convert_v1alpha1_Environment_To_v1alpha2_Environment(src, dst, nil); err != nil { + return err + } + + // Manually restore data from annotations + restored := &metalv1alpha2.Environment{} + if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { + return err + } + + return nil +} + +// ConvertFrom converts from the Hub version (v1alpha3) to this version. +func (dst *Environment) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*metalv1alpha2.Environment) + if err := Convert_v1alpha2_Environment_To_v1alpha1_Environment(src, dst, nil); err != nil { + return err + } + + // Preserve Hub data on down-conversion. + if err := utilconversion.MarshalData(src, dst); err != nil { + return err + } + + return nil +} + +// ConvertTo converts this MetalMachineTemplateList to the Hub version (v1alpha3). +func (src *EnvironmentList) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*metalv1alpha2.EnvironmentList) + return Convert_v1alpha1_EnvironmentList_To_v1alpha2_EnvironmentList(src, dst, nil) +} + +// ConvertFrom converts from the Hub version (v1alpha3) to this version. +func (dst *EnvironmentList) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*metalv1alpha2.EnvironmentList) + return Convert_v1alpha2_EnvironmentList_To_v1alpha1_EnvironmentList(src, dst, nil) +} diff --git a/app/sidero-controller-manager/api/v1alpha1/groupversion_info.go b/app/sidero-controller-manager/api/v1alpha1/groupversion_info.go index 201054aa4..44d835731 100644 --- a/app/sidero-controller-manager/api/v1alpha1/groupversion_info.go +++ b/app/sidero-controller-manager/api/v1alpha1/groupversion_info.go @@ -21,4 +21,7 @@ var ( // AddToScheme adds the types in this group-version to the given scheme. AddToScheme = SchemeBuilder.AddToScheme + + // localSchemeBuilder is used for type conversions. + localSchemeBuilder = SchemeBuilder.SchemeBuilder ) diff --git a/app/sidero-controller-manager/api/v1alpha1/server_conversion.go b/app/sidero-controller-manager/api/v1alpha1/server_conversion.go new file mode 100644 index 000000000..4d909569a --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha1/server_conversion.go @@ -0,0 +1,130 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +//nolint:golint,stylecheck +package v1alpha1 + +import ( + apiconversion "k8s.io/apimachinery/pkg/conversion" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" + "sigs.k8s.io/controller-runtime/pkg/conversion" + + metalv1alpha2 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" +) + +// ConvertTo converts this Server to the Hub version (v1alpha2). +func (src *Server) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*metalv1alpha2.Server) + if err := Convert_v1alpha1_Server_To_v1alpha2_Server(src, dst, nil); err != nil { + return err + } + + // Manually restore data from annotations + restored := &metalv1alpha2.Server{} + if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { + return err + } + + return nil +} + +// ConvertFrom converts from the Hub version (v1alpha3) to this version. +func (dst *Server) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*metalv1alpha2.Server) + if err := Convert_v1alpha2_Server_To_v1alpha1_Server(src, dst, nil); err != nil { + return err + } + + // Preserve Hub data on down-conversion. + if err := utilconversion.MarshalData(src, dst); err != nil { + return err + } + + return nil +} + +// ConvertTo converts this MetalMachineTemplateList to the Hub version (v1alpha3). +func (src *ServerList) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*metalv1alpha2.ServerList) + return Convert_v1alpha1_ServerList_To_v1alpha2_ServerList(src, dst, nil) +} + +// ConvertFrom converts from the Hub version (v1alpha3) to this version. +func (dst *ServerList) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*metalv1alpha2.ServerList) + return Convert_v1alpha2_ServerList_To_v1alpha1_ServerList(src, dst, nil) +} + +// Convert_v1alpha1_ServerSpec_To_v1alpha2_ServerSpec converts to the Hub version (v1alpha2). +func Convert_v1alpha1_ServerSpec_To_v1alpha2_ServerSpec(in *ServerSpec, out *metalv1alpha2.ServerSpec, s apiconversion.Scope) error { + if err := autoConvert_v1alpha1_ServerSpec_To_v1alpha2_ServerSpec(in, out, s); err != nil { + return err + } + + // Manually convert SystemInformation to Hardware. + if in.SystemInformation != nil { + if out.Hardware == nil { + out.Hardware = &metalv1alpha2.HardwareInformation{} + } + out.Hardware.System = &metalv1alpha2.SystemInformation{ + Manufacturer: in.SystemInformation.Manufacturer, + ProductName: in.SystemInformation.ProductName, + Version: in.SystemInformation.Version, + SerialNumber: in.SystemInformation.SerialNumber, + SKUNumber: in.SystemInformation.SKUNumber, + Family: in.SystemInformation.Family, + } + } + + // Manually convert CPU to Hardware. + if in.CPU != nil { + if out.Hardware == nil { + out.Hardware = &metalv1alpha2.HardwareInformation{} + } + out.Hardware.Compute = &metalv1alpha2.ComputeInformation{ + Processors: []*metalv1alpha2.Processor{ + { + Manufacturer: in.CPU.Manufacturer, + ProductName: in.CPU.Version, + }, + }, + } + } + + return nil +} + +// Convert_v1alpha2_ServerSpec_To_v1alpha1_ServerSpec converts from the Hub version (v1alpha2). +func Convert_v1alpha2_ServerSpec_To_v1alpha1_ServerSpec(in *metalv1alpha2.ServerSpec, out *ServerSpec, s apiconversion.Scope) error { + if err := autoConvert_v1alpha2_ServerSpec_To_v1alpha1_ServerSpec(in, out, s); err != nil { + return err + } + + // Manually convert Hardware to SystemInformation. + if in.Hardware != nil && in.Hardware.System != nil { + out.SystemInformation = &SystemInformation{ + Manufacturer: in.Hardware.System.Manufacturer, + ProductName: in.Hardware.System.ProductName, + Version: in.Hardware.System.Version, + SerialNumber: in.Hardware.System.SerialNumber, + SKUNumber: in.Hardware.System.SKUNumber, + Family: in.Hardware.System.Family, + } + } + + // Manually convert Hardware to CPU. + if in.Hardware != nil && in.Hardware.Compute != nil && len(in.Hardware.Compute.Processors) > 0 { + cpu := in.Hardware.Compute.Processors[0] + out.CPU = &CPUInformation{ + Manufacturer: cpu.Manufacturer, + Version: cpu.ProductName, + } + } + + return nil +} + +func Convert_v1alpha2_SystemInformation_To_v1alpha1_SystemInformation(in *metalv1alpha2.SystemInformation, out *SystemInformation, s apiconversion.Scope) error { + return autoConvert_v1alpha2_SystemInformation_To_v1alpha1_SystemInformation(in, out, s) +} diff --git a/app/sidero-controller-manager/api/v1alpha1/serverclass_conversion.go b/app/sidero-controller-manager/api/v1alpha1/serverclass_conversion.go new file mode 100644 index 000000000..ea54850be --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha1/serverclass_conversion.go @@ -0,0 +1,124 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +//nolint:golint,stylecheck +package v1alpha1 + +import ( + apiconversion "k8s.io/apimachinery/pkg/conversion" + utilconversion "sigs.k8s.io/cluster-api/util/conversion" + "sigs.k8s.io/controller-runtime/pkg/conversion" + + metalv1alpha2 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" +) + +// ConvertTo converts this ServerClass to the Hub version (v1alpha2). +func (src *ServerClass) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*metalv1alpha2.ServerClass) + if err := Convert_v1alpha1_ServerClass_To_v1alpha2_ServerClass(src, dst, nil); err != nil { + return err + } + + // Manually restore data from annotations + restored := &metalv1alpha2.ServerClass{} + if ok, err := utilconversion.UnmarshalData(src, restored); err != nil || !ok { + return err + } + + return nil +} + +// ConvertFrom converts from the Hub version (v1alpha3) to this version. +func (dst *ServerClass) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*metalv1alpha2.ServerClass) + if err := Convert_v1alpha2_ServerClass_To_v1alpha1_ServerClass(src, dst, nil); err != nil { + return err + } + + // Preserve Hub data on down-conversion. + if err := utilconversion.MarshalData(src, dst); err != nil { + return err + } + + return nil +} + +// ConvertTo converts this MetalMachineTemplateList to the Hub version (v1alpha3). +func (src *ServerClassList) ConvertTo(dstRaw conversion.Hub) error { + dst := dstRaw.(*metalv1alpha2.ServerClassList) + return Convert_v1alpha1_ServerClassList_To_v1alpha2_ServerClassList(src, dst, nil) +} + +// ConvertFrom converts from the Hub version (v1alpha3) to this version. +func (dst *ServerClassList) ConvertFrom(srcRaw conversion.Hub) error { + src := srcRaw.(*metalv1alpha2.ServerClassList) + return Convert_v1alpha2_ServerClassList_To_v1alpha1_ServerClassList(src, dst, nil) +} + +// Convert_v1alpha1_Qualifiers_To_v1alpha2_Qualifiers converts to the Hub version (v1alpha2). +func Convert_v1alpha1_Qualifiers_To_v1alpha2_Qualifiers(in *Qualifiers, out *metalv1alpha2.Qualifiers, s apiconversion.Scope) error { + if err := autoConvert_v1alpha1_Qualifiers_To_v1alpha2_Qualifiers(in, out, s); err != nil { + return err + } + + // Manually convert SystemInformation to Hardware. + for _, v := range in.SystemInformation { + out.Hardware = append(out.Hardware, metalv1alpha2.HardwareInformation{ + System: &metalv1alpha2.SystemInformation{ + Manufacturer: v.Manufacturer, + ProductName: v.ProductName, + Version: v.Version, + SerialNumber: v.SerialNumber, + SKUNumber: v.SKUNumber, + Family: v.Family, + }, + }) + } + + // Manually convert CPU to Hardware. + for _, v := range in.CPU { + out.Hardware = append(out.Hardware, metalv1alpha2.HardwareInformation{ + Compute: &metalv1alpha2.ComputeInformation{ + Processors: []*metalv1alpha2.Processor{ + { + Manufacturer: v.Manufacturer, + ProductName: v.Version, + }, + }, + }, + }) + } + + return nil +} + +// Convert_v1alpha2_Qualifiers_To_v1alpha1_Qualifiers converts from the Hub version (v1alpha2). +func Convert_v1alpha2_Qualifiers_To_v1alpha1_Qualifiers(in *metalv1alpha2.Qualifiers, out *Qualifiers, s apiconversion.Scope) error { + if err := autoConvert_v1alpha2_Qualifiers_To_v1alpha1_Qualifiers(in, out, s); err != nil { + return err + } + + // Manually convert Hardware to SystemInformation or CPU. + for _, v := range in.Hardware { + if v.System != nil { + out.SystemInformation = append(out.SystemInformation, SystemInformation{ + Manufacturer: v.System.Manufacturer, + ProductName: v.System.ProductName, + Version: v.System.Version, + SerialNumber: v.System.SerialNumber, + SKUNumber: v.System.SKUNumber, + Family: v.System.Family, + }) + } + if v.Compute != nil && len(v.Compute.Processors) > 0 { + cpu := v.Compute.Processors[0] + out.CPU = append(out.CPU, CPUInformation{ + Manufacturer: cpu.Manufacturer, + Version: cpu.ProductName, + }) + } + } + + return nil +} diff --git a/app/sidero-controller-manager/api/v1alpha1/zz_generated.conversion.go b/app/sidero-controller-manager/api/v1alpha1/zz_generated.conversion.go new file mode 100644 index 000000000..ac273f357 --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha1/zz_generated.conversion.go @@ -0,0 +1,886 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// Code generated by conversion-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + unsafe "unsafe" + + v1 "k8s.io/api/core/v1" + conversion "k8s.io/apimachinery/pkg/conversion" + runtime "k8s.io/apimachinery/pkg/runtime" + v1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" + + v1alpha2 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" + types "github.com/talos-systems/sidero/app/sidero-controller-manager/pkg/types" +) + +func init() { + localSchemeBuilder.Register(RegisterConversions) +} + +// RegisterConversions adds conversion functions to the given scheme. +// Public to allow building arbitrary schemes. +func RegisterConversions(s *runtime.Scheme) error { + if err := s.AddGeneratedConversionFunc((*Asset)(nil), (*v1alpha2.Asset)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_Asset_To_v1alpha2_Asset(a.(*Asset), b.(*v1alpha2.Asset), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.Asset)(nil), (*Asset)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_Asset_To_v1alpha1_Asset(a.(*v1alpha2.Asset), b.(*Asset), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*AssetCondition)(nil), (*v1alpha2.AssetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_AssetCondition_To_v1alpha2_AssetCondition(a.(*AssetCondition), b.(*v1alpha2.AssetCondition), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.AssetCondition)(nil), (*AssetCondition)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_AssetCondition_To_v1alpha1_AssetCondition(a.(*v1alpha2.AssetCondition), b.(*AssetCondition), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*BMC)(nil), (*v1alpha2.BMC)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_BMC_To_v1alpha2_BMC(a.(*BMC), b.(*v1alpha2.BMC), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.BMC)(nil), (*BMC)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_BMC_To_v1alpha1_BMC(a.(*v1alpha2.BMC), b.(*BMC), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ConfigPatches)(nil), (*v1alpha2.ConfigPatches)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ConfigPatches_To_v1alpha2_ConfigPatches(a.(*ConfigPatches), b.(*v1alpha2.ConfigPatches), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.ConfigPatches)(nil), (*ConfigPatches)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_ConfigPatches_To_v1alpha1_ConfigPatches(a.(*v1alpha2.ConfigPatches), b.(*ConfigPatches), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*CredentialSource)(nil), (*v1alpha2.CredentialSource)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_CredentialSource_To_v1alpha2_CredentialSource(a.(*CredentialSource), b.(*v1alpha2.CredentialSource), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.CredentialSource)(nil), (*CredentialSource)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_CredentialSource_To_v1alpha1_CredentialSource(a.(*v1alpha2.CredentialSource), b.(*CredentialSource), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Environment)(nil), (*v1alpha2.Environment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_Environment_To_v1alpha2_Environment(a.(*Environment), b.(*v1alpha2.Environment), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.Environment)(nil), (*Environment)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_Environment_To_v1alpha1_Environment(a.(*v1alpha2.Environment), b.(*Environment), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*EnvironmentList)(nil), (*v1alpha2.EnvironmentList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_EnvironmentList_To_v1alpha2_EnvironmentList(a.(*EnvironmentList), b.(*v1alpha2.EnvironmentList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.EnvironmentList)(nil), (*EnvironmentList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_EnvironmentList_To_v1alpha1_EnvironmentList(a.(*v1alpha2.EnvironmentList), b.(*EnvironmentList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*EnvironmentSpec)(nil), (*v1alpha2.EnvironmentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_EnvironmentSpec_To_v1alpha2_EnvironmentSpec(a.(*EnvironmentSpec), b.(*v1alpha2.EnvironmentSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.EnvironmentSpec)(nil), (*EnvironmentSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_EnvironmentSpec_To_v1alpha1_EnvironmentSpec(a.(*v1alpha2.EnvironmentSpec), b.(*EnvironmentSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*EnvironmentStatus)(nil), (*v1alpha2.EnvironmentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_EnvironmentStatus_To_v1alpha2_EnvironmentStatus(a.(*EnvironmentStatus), b.(*v1alpha2.EnvironmentStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.EnvironmentStatus)(nil), (*EnvironmentStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_EnvironmentStatus_To_v1alpha1_EnvironmentStatus(a.(*v1alpha2.EnvironmentStatus), b.(*EnvironmentStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Initrd)(nil), (*v1alpha2.Initrd)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_Initrd_To_v1alpha2_Initrd(a.(*Initrd), b.(*v1alpha2.Initrd), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.Initrd)(nil), (*Initrd)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_Initrd_To_v1alpha1_Initrd(a.(*v1alpha2.Initrd), b.(*Initrd), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Kernel)(nil), (*v1alpha2.Kernel)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_Kernel_To_v1alpha2_Kernel(a.(*Kernel), b.(*v1alpha2.Kernel), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.Kernel)(nil), (*Kernel)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_Kernel_To_v1alpha1_Kernel(a.(*v1alpha2.Kernel), b.(*Kernel), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ManagementAPI)(nil), (*v1alpha2.ManagementAPI)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ManagementAPI_To_v1alpha2_ManagementAPI(a.(*ManagementAPI), b.(*v1alpha2.ManagementAPI), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.ManagementAPI)(nil), (*ManagementAPI)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_ManagementAPI_To_v1alpha1_ManagementAPI(a.(*v1alpha2.ManagementAPI), b.(*ManagementAPI), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*SecretKeyRef)(nil), (*v1alpha2.SecretKeyRef)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_SecretKeyRef_To_v1alpha2_SecretKeyRef(a.(*SecretKeyRef), b.(*v1alpha2.SecretKeyRef), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.SecretKeyRef)(nil), (*SecretKeyRef)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_SecretKeyRef_To_v1alpha1_SecretKeyRef(a.(*v1alpha2.SecretKeyRef), b.(*SecretKeyRef), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*Server)(nil), (*v1alpha2.Server)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_Server_To_v1alpha2_Server(a.(*Server), b.(*v1alpha2.Server), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.Server)(nil), (*Server)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_Server_To_v1alpha1_Server(a.(*v1alpha2.Server), b.(*Server), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ServerClass)(nil), (*v1alpha2.ServerClass)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ServerClass_To_v1alpha2_ServerClass(a.(*ServerClass), b.(*v1alpha2.ServerClass), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.ServerClass)(nil), (*ServerClass)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_ServerClass_To_v1alpha1_ServerClass(a.(*v1alpha2.ServerClass), b.(*ServerClass), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ServerClassList)(nil), (*v1alpha2.ServerClassList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ServerClassList_To_v1alpha2_ServerClassList(a.(*ServerClassList), b.(*v1alpha2.ServerClassList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.ServerClassList)(nil), (*ServerClassList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_ServerClassList_To_v1alpha1_ServerClassList(a.(*v1alpha2.ServerClassList), b.(*ServerClassList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ServerClassSpec)(nil), (*v1alpha2.ServerClassSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ServerClassSpec_To_v1alpha2_ServerClassSpec(a.(*ServerClassSpec), b.(*v1alpha2.ServerClassSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.ServerClassSpec)(nil), (*ServerClassSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_ServerClassSpec_To_v1alpha1_ServerClassSpec(a.(*v1alpha2.ServerClassSpec), b.(*ServerClassSpec), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ServerClassStatus)(nil), (*v1alpha2.ServerClassStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ServerClassStatus_To_v1alpha2_ServerClassStatus(a.(*ServerClassStatus), b.(*v1alpha2.ServerClassStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.ServerClassStatus)(nil), (*ServerClassStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_ServerClassStatus_To_v1alpha1_ServerClassStatus(a.(*v1alpha2.ServerClassStatus), b.(*ServerClassStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ServerList)(nil), (*v1alpha2.ServerList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ServerList_To_v1alpha2_ServerList(a.(*ServerList), b.(*v1alpha2.ServerList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.ServerList)(nil), (*ServerList)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_ServerList_To_v1alpha1_ServerList(a.(*v1alpha2.ServerList), b.(*ServerList), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*ServerStatus)(nil), (*v1alpha2.ServerStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ServerStatus_To_v1alpha2_ServerStatus(a.(*ServerStatus), b.(*v1alpha2.ServerStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*v1alpha2.ServerStatus)(nil), (*ServerStatus)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_ServerStatus_To_v1alpha1_ServerStatus(a.(*v1alpha2.ServerStatus), b.(*ServerStatus), scope) + }); err != nil { + return err + } + if err := s.AddGeneratedConversionFunc((*SystemInformation)(nil), (*v1alpha2.SystemInformation)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_SystemInformation_To_v1alpha2_SystemInformation(a.(*SystemInformation), b.(*v1alpha2.SystemInformation), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*Qualifiers)(nil), (*v1alpha2.Qualifiers)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_Qualifiers_To_v1alpha2_Qualifiers(a.(*Qualifiers), b.(*v1alpha2.Qualifiers), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*ServerSpec)(nil), (*v1alpha2.ServerSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha1_ServerSpec_To_v1alpha2_ServerSpec(a.(*ServerSpec), b.(*v1alpha2.ServerSpec), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1alpha2.Qualifiers)(nil), (*Qualifiers)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_Qualifiers_To_v1alpha1_Qualifiers(a.(*v1alpha2.Qualifiers), b.(*Qualifiers), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1alpha2.ServerSpec)(nil), (*ServerSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_ServerSpec_To_v1alpha1_ServerSpec(a.(*v1alpha2.ServerSpec), b.(*ServerSpec), scope) + }); err != nil { + return err + } + if err := s.AddConversionFunc((*v1alpha2.SystemInformation)(nil), (*SystemInformation)(nil), func(a, b interface{}, scope conversion.Scope) error { + return Convert_v1alpha2_SystemInformation_To_v1alpha1_SystemInformation(a.(*v1alpha2.SystemInformation), b.(*SystemInformation), scope) + }); err != nil { + return err + } + return nil +} + +func autoConvert_v1alpha1_Asset_To_v1alpha2_Asset(in *Asset, out *v1alpha2.Asset, s conversion.Scope) error { + out.URL = in.URL + out.SHA512 = in.SHA512 + return nil +} + +// Convert_v1alpha1_Asset_To_v1alpha2_Asset is an autogenerated conversion function. +func Convert_v1alpha1_Asset_To_v1alpha2_Asset(in *Asset, out *v1alpha2.Asset, s conversion.Scope) error { + return autoConvert_v1alpha1_Asset_To_v1alpha2_Asset(in, out, s) +} + +func autoConvert_v1alpha2_Asset_To_v1alpha1_Asset(in *v1alpha2.Asset, out *Asset, s conversion.Scope) error { + out.URL = in.URL + out.SHA512 = in.SHA512 + return nil +} + +// Convert_v1alpha2_Asset_To_v1alpha1_Asset is an autogenerated conversion function. +func Convert_v1alpha2_Asset_To_v1alpha1_Asset(in *v1alpha2.Asset, out *Asset, s conversion.Scope) error { + return autoConvert_v1alpha2_Asset_To_v1alpha1_Asset(in, out, s) +} + +func autoConvert_v1alpha1_AssetCondition_To_v1alpha2_AssetCondition(in *AssetCondition, out *v1alpha2.AssetCondition, s conversion.Scope) error { + if err := Convert_v1alpha1_Asset_To_v1alpha2_Asset(&in.Asset, &out.Asset, s); err != nil { + return err + } + out.Status = in.Status + out.Type = in.Type + return nil +} + +// Convert_v1alpha1_AssetCondition_To_v1alpha2_AssetCondition is an autogenerated conversion function. +func Convert_v1alpha1_AssetCondition_To_v1alpha2_AssetCondition(in *AssetCondition, out *v1alpha2.AssetCondition, s conversion.Scope) error { + return autoConvert_v1alpha1_AssetCondition_To_v1alpha2_AssetCondition(in, out, s) +} + +func autoConvert_v1alpha2_AssetCondition_To_v1alpha1_AssetCondition(in *v1alpha2.AssetCondition, out *AssetCondition, s conversion.Scope) error { + if err := Convert_v1alpha2_Asset_To_v1alpha1_Asset(&in.Asset, &out.Asset, s); err != nil { + return err + } + out.Status = in.Status + out.Type = in.Type + return nil +} + +// Convert_v1alpha2_AssetCondition_To_v1alpha1_AssetCondition is an autogenerated conversion function. +func Convert_v1alpha2_AssetCondition_To_v1alpha1_AssetCondition(in *v1alpha2.AssetCondition, out *AssetCondition, s conversion.Scope) error { + return autoConvert_v1alpha2_AssetCondition_To_v1alpha1_AssetCondition(in, out, s) +} + +func autoConvert_v1alpha1_BMC_To_v1alpha2_BMC(in *BMC, out *v1alpha2.BMC, s conversion.Scope) error { + out.Endpoint = in.Endpoint + out.Port = in.Port + out.User = in.User + out.UserFrom = (*v1alpha2.CredentialSource)(unsafe.Pointer(in.UserFrom)) + out.Pass = in.Pass + out.PassFrom = (*v1alpha2.CredentialSource)(unsafe.Pointer(in.PassFrom)) + out.Interface = in.Interface + return nil +} + +// Convert_v1alpha1_BMC_To_v1alpha2_BMC is an autogenerated conversion function. +func Convert_v1alpha1_BMC_To_v1alpha2_BMC(in *BMC, out *v1alpha2.BMC, s conversion.Scope) error { + return autoConvert_v1alpha1_BMC_To_v1alpha2_BMC(in, out, s) +} + +func autoConvert_v1alpha2_BMC_To_v1alpha1_BMC(in *v1alpha2.BMC, out *BMC, s conversion.Scope) error { + out.Endpoint = in.Endpoint + out.Port = in.Port + out.User = in.User + out.UserFrom = (*CredentialSource)(unsafe.Pointer(in.UserFrom)) + out.Pass = in.Pass + out.PassFrom = (*CredentialSource)(unsafe.Pointer(in.PassFrom)) + out.Interface = in.Interface + return nil +} + +// Convert_v1alpha2_BMC_To_v1alpha1_BMC is an autogenerated conversion function. +func Convert_v1alpha2_BMC_To_v1alpha1_BMC(in *v1alpha2.BMC, out *BMC, s conversion.Scope) error { + return autoConvert_v1alpha2_BMC_To_v1alpha1_BMC(in, out, s) +} + +func autoConvert_v1alpha1_ConfigPatches_To_v1alpha2_ConfigPatches(in *ConfigPatches, out *v1alpha2.ConfigPatches, s conversion.Scope) error { + out.Op = in.Op + out.Path = in.Path + out.Value = in.Value + return nil +} + +// Convert_v1alpha1_ConfigPatches_To_v1alpha2_ConfigPatches is an autogenerated conversion function. +func Convert_v1alpha1_ConfigPatches_To_v1alpha2_ConfigPatches(in *ConfigPatches, out *v1alpha2.ConfigPatches, s conversion.Scope) error { + return autoConvert_v1alpha1_ConfigPatches_To_v1alpha2_ConfigPatches(in, out, s) +} + +func autoConvert_v1alpha2_ConfigPatches_To_v1alpha1_ConfigPatches(in *v1alpha2.ConfigPatches, out *ConfigPatches, s conversion.Scope) error { + out.Op = in.Op + out.Path = in.Path + out.Value = in.Value + return nil +} + +// Convert_v1alpha2_ConfigPatches_To_v1alpha1_ConfigPatches is an autogenerated conversion function. +func Convert_v1alpha2_ConfigPatches_To_v1alpha1_ConfigPatches(in *v1alpha2.ConfigPatches, out *ConfigPatches, s conversion.Scope) error { + return autoConvert_v1alpha2_ConfigPatches_To_v1alpha1_ConfigPatches(in, out, s) +} + +func autoConvert_v1alpha1_CredentialSource_To_v1alpha2_CredentialSource(in *CredentialSource, out *v1alpha2.CredentialSource, s conversion.Scope) error { + out.SecretKeyRef = (*v1alpha2.SecretKeyRef)(unsafe.Pointer(in.SecretKeyRef)) + return nil +} + +// Convert_v1alpha1_CredentialSource_To_v1alpha2_CredentialSource is an autogenerated conversion function. +func Convert_v1alpha1_CredentialSource_To_v1alpha2_CredentialSource(in *CredentialSource, out *v1alpha2.CredentialSource, s conversion.Scope) error { + return autoConvert_v1alpha1_CredentialSource_To_v1alpha2_CredentialSource(in, out, s) +} + +func autoConvert_v1alpha2_CredentialSource_To_v1alpha1_CredentialSource(in *v1alpha2.CredentialSource, out *CredentialSource, s conversion.Scope) error { + out.SecretKeyRef = (*SecretKeyRef)(unsafe.Pointer(in.SecretKeyRef)) + return nil +} + +// Convert_v1alpha2_CredentialSource_To_v1alpha1_CredentialSource is an autogenerated conversion function. +func Convert_v1alpha2_CredentialSource_To_v1alpha1_CredentialSource(in *v1alpha2.CredentialSource, out *CredentialSource, s conversion.Scope) error { + return autoConvert_v1alpha2_CredentialSource_To_v1alpha1_CredentialSource(in, out, s) +} + +func autoConvert_v1alpha1_Environment_To_v1alpha2_Environment(in *Environment, out *v1alpha2.Environment, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha1_EnvironmentSpec_To_v1alpha2_EnvironmentSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha1_EnvironmentStatus_To_v1alpha2_EnvironmentStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha1_Environment_To_v1alpha2_Environment is an autogenerated conversion function. +func Convert_v1alpha1_Environment_To_v1alpha2_Environment(in *Environment, out *v1alpha2.Environment, s conversion.Scope) error { + return autoConvert_v1alpha1_Environment_To_v1alpha2_Environment(in, out, s) +} + +func autoConvert_v1alpha2_Environment_To_v1alpha1_Environment(in *v1alpha2.Environment, out *Environment, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha2_EnvironmentSpec_To_v1alpha1_EnvironmentSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha2_EnvironmentStatus_To_v1alpha1_EnvironmentStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha2_Environment_To_v1alpha1_Environment is an autogenerated conversion function. +func Convert_v1alpha2_Environment_To_v1alpha1_Environment(in *v1alpha2.Environment, out *Environment, s conversion.Scope) error { + return autoConvert_v1alpha2_Environment_To_v1alpha1_Environment(in, out, s) +} + +func autoConvert_v1alpha1_EnvironmentList_To_v1alpha2_EnvironmentList(in *EnvironmentList, out *v1alpha2.EnvironmentList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]v1alpha2.Environment)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_v1alpha1_EnvironmentList_To_v1alpha2_EnvironmentList is an autogenerated conversion function. +func Convert_v1alpha1_EnvironmentList_To_v1alpha2_EnvironmentList(in *EnvironmentList, out *v1alpha2.EnvironmentList, s conversion.Scope) error { + return autoConvert_v1alpha1_EnvironmentList_To_v1alpha2_EnvironmentList(in, out, s) +} + +func autoConvert_v1alpha2_EnvironmentList_To_v1alpha1_EnvironmentList(in *v1alpha2.EnvironmentList, out *EnvironmentList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + out.Items = *(*[]Environment)(unsafe.Pointer(&in.Items)) + return nil +} + +// Convert_v1alpha2_EnvironmentList_To_v1alpha1_EnvironmentList is an autogenerated conversion function. +func Convert_v1alpha2_EnvironmentList_To_v1alpha1_EnvironmentList(in *v1alpha2.EnvironmentList, out *EnvironmentList, s conversion.Scope) error { + return autoConvert_v1alpha2_EnvironmentList_To_v1alpha1_EnvironmentList(in, out, s) +} + +func autoConvert_v1alpha1_EnvironmentSpec_To_v1alpha2_EnvironmentSpec(in *EnvironmentSpec, out *v1alpha2.EnvironmentSpec, s conversion.Scope) error { + if err := Convert_v1alpha1_Kernel_To_v1alpha2_Kernel(&in.Kernel, &out.Kernel, s); err != nil { + return err + } + if err := Convert_v1alpha1_Initrd_To_v1alpha2_Initrd(&in.Initrd, &out.Initrd, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha1_EnvironmentSpec_To_v1alpha2_EnvironmentSpec is an autogenerated conversion function. +func Convert_v1alpha1_EnvironmentSpec_To_v1alpha2_EnvironmentSpec(in *EnvironmentSpec, out *v1alpha2.EnvironmentSpec, s conversion.Scope) error { + return autoConvert_v1alpha1_EnvironmentSpec_To_v1alpha2_EnvironmentSpec(in, out, s) +} + +func autoConvert_v1alpha2_EnvironmentSpec_To_v1alpha1_EnvironmentSpec(in *v1alpha2.EnvironmentSpec, out *EnvironmentSpec, s conversion.Scope) error { + if err := Convert_v1alpha2_Kernel_To_v1alpha1_Kernel(&in.Kernel, &out.Kernel, s); err != nil { + return err + } + if err := Convert_v1alpha2_Initrd_To_v1alpha1_Initrd(&in.Initrd, &out.Initrd, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha2_EnvironmentSpec_To_v1alpha1_EnvironmentSpec is an autogenerated conversion function. +func Convert_v1alpha2_EnvironmentSpec_To_v1alpha1_EnvironmentSpec(in *v1alpha2.EnvironmentSpec, out *EnvironmentSpec, s conversion.Scope) error { + return autoConvert_v1alpha2_EnvironmentSpec_To_v1alpha1_EnvironmentSpec(in, out, s) +} + +func autoConvert_v1alpha1_EnvironmentStatus_To_v1alpha2_EnvironmentStatus(in *EnvironmentStatus, out *v1alpha2.EnvironmentStatus, s conversion.Scope) error { + out.Conditions = *(*[]v1alpha2.AssetCondition)(unsafe.Pointer(&in.Conditions)) + return nil +} + +// Convert_v1alpha1_EnvironmentStatus_To_v1alpha2_EnvironmentStatus is an autogenerated conversion function. +func Convert_v1alpha1_EnvironmentStatus_To_v1alpha2_EnvironmentStatus(in *EnvironmentStatus, out *v1alpha2.EnvironmentStatus, s conversion.Scope) error { + return autoConvert_v1alpha1_EnvironmentStatus_To_v1alpha2_EnvironmentStatus(in, out, s) +} + +func autoConvert_v1alpha2_EnvironmentStatus_To_v1alpha1_EnvironmentStatus(in *v1alpha2.EnvironmentStatus, out *EnvironmentStatus, s conversion.Scope) error { + out.Conditions = *(*[]AssetCondition)(unsafe.Pointer(&in.Conditions)) + return nil +} + +// Convert_v1alpha2_EnvironmentStatus_To_v1alpha1_EnvironmentStatus is an autogenerated conversion function. +func Convert_v1alpha2_EnvironmentStatus_To_v1alpha1_EnvironmentStatus(in *v1alpha2.EnvironmentStatus, out *EnvironmentStatus, s conversion.Scope) error { + return autoConvert_v1alpha2_EnvironmentStatus_To_v1alpha1_EnvironmentStatus(in, out, s) +} + +func autoConvert_v1alpha1_Initrd_To_v1alpha2_Initrd(in *Initrd, out *v1alpha2.Initrd, s conversion.Scope) error { + if err := Convert_v1alpha1_Asset_To_v1alpha2_Asset(&in.Asset, &out.Asset, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha1_Initrd_To_v1alpha2_Initrd is an autogenerated conversion function. +func Convert_v1alpha1_Initrd_To_v1alpha2_Initrd(in *Initrd, out *v1alpha2.Initrd, s conversion.Scope) error { + return autoConvert_v1alpha1_Initrd_To_v1alpha2_Initrd(in, out, s) +} + +func autoConvert_v1alpha2_Initrd_To_v1alpha1_Initrd(in *v1alpha2.Initrd, out *Initrd, s conversion.Scope) error { + if err := Convert_v1alpha2_Asset_To_v1alpha1_Asset(&in.Asset, &out.Asset, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha2_Initrd_To_v1alpha1_Initrd is an autogenerated conversion function. +func Convert_v1alpha2_Initrd_To_v1alpha1_Initrd(in *v1alpha2.Initrd, out *Initrd, s conversion.Scope) error { + return autoConvert_v1alpha2_Initrd_To_v1alpha1_Initrd(in, out, s) +} + +func autoConvert_v1alpha1_Kernel_To_v1alpha2_Kernel(in *Kernel, out *v1alpha2.Kernel, s conversion.Scope) error { + if err := Convert_v1alpha1_Asset_To_v1alpha2_Asset(&in.Asset, &out.Asset, s); err != nil { + return err + } + out.Args = *(*[]string)(unsafe.Pointer(&in.Args)) + return nil +} + +// Convert_v1alpha1_Kernel_To_v1alpha2_Kernel is an autogenerated conversion function. +func Convert_v1alpha1_Kernel_To_v1alpha2_Kernel(in *Kernel, out *v1alpha2.Kernel, s conversion.Scope) error { + return autoConvert_v1alpha1_Kernel_To_v1alpha2_Kernel(in, out, s) +} + +func autoConvert_v1alpha2_Kernel_To_v1alpha1_Kernel(in *v1alpha2.Kernel, out *Kernel, s conversion.Scope) error { + if err := Convert_v1alpha2_Asset_To_v1alpha1_Asset(&in.Asset, &out.Asset, s); err != nil { + return err + } + out.Args = *(*[]string)(unsafe.Pointer(&in.Args)) + return nil +} + +// Convert_v1alpha2_Kernel_To_v1alpha1_Kernel is an autogenerated conversion function. +func Convert_v1alpha2_Kernel_To_v1alpha1_Kernel(in *v1alpha2.Kernel, out *Kernel, s conversion.Scope) error { + return autoConvert_v1alpha2_Kernel_To_v1alpha1_Kernel(in, out, s) +} + +func autoConvert_v1alpha1_ManagementAPI_To_v1alpha2_ManagementAPI(in *ManagementAPI, out *v1alpha2.ManagementAPI, s conversion.Scope) error { + out.Endpoint = in.Endpoint + return nil +} + +// Convert_v1alpha1_ManagementAPI_To_v1alpha2_ManagementAPI is an autogenerated conversion function. +func Convert_v1alpha1_ManagementAPI_To_v1alpha2_ManagementAPI(in *ManagementAPI, out *v1alpha2.ManagementAPI, s conversion.Scope) error { + return autoConvert_v1alpha1_ManagementAPI_To_v1alpha2_ManagementAPI(in, out, s) +} + +func autoConvert_v1alpha2_ManagementAPI_To_v1alpha1_ManagementAPI(in *v1alpha2.ManagementAPI, out *ManagementAPI, s conversion.Scope) error { + out.Endpoint = in.Endpoint + return nil +} + +// Convert_v1alpha2_ManagementAPI_To_v1alpha1_ManagementAPI is an autogenerated conversion function. +func Convert_v1alpha2_ManagementAPI_To_v1alpha1_ManagementAPI(in *v1alpha2.ManagementAPI, out *ManagementAPI, s conversion.Scope) error { + return autoConvert_v1alpha2_ManagementAPI_To_v1alpha1_ManagementAPI(in, out, s) +} + +func autoConvert_v1alpha1_Qualifiers_To_v1alpha2_Qualifiers(in *Qualifiers, out *v1alpha2.Qualifiers, s conversion.Scope) error { + // WARNING: in.CPU requires manual conversion: does not exist in peer-type + // WARNING: in.SystemInformation requires manual conversion: does not exist in peer-type + out.LabelSelectors = *(*[]map[string]string)(unsafe.Pointer(&in.LabelSelectors)) + return nil +} + +func autoConvert_v1alpha2_Qualifiers_To_v1alpha1_Qualifiers(in *v1alpha2.Qualifiers, out *Qualifiers, s conversion.Scope) error { + // WARNING: in.Hardware requires manual conversion: does not exist in peer-type + out.LabelSelectors = *(*[]map[string]string)(unsafe.Pointer(&in.LabelSelectors)) + return nil +} + +func autoConvert_v1alpha1_SecretKeyRef_To_v1alpha2_SecretKeyRef(in *SecretKeyRef, out *v1alpha2.SecretKeyRef, s conversion.Scope) error { + out.Namespace = in.Namespace + out.Name = in.Name + out.Key = in.Key + return nil +} + +// Convert_v1alpha1_SecretKeyRef_To_v1alpha2_SecretKeyRef is an autogenerated conversion function. +func Convert_v1alpha1_SecretKeyRef_To_v1alpha2_SecretKeyRef(in *SecretKeyRef, out *v1alpha2.SecretKeyRef, s conversion.Scope) error { + return autoConvert_v1alpha1_SecretKeyRef_To_v1alpha2_SecretKeyRef(in, out, s) +} + +func autoConvert_v1alpha2_SecretKeyRef_To_v1alpha1_SecretKeyRef(in *v1alpha2.SecretKeyRef, out *SecretKeyRef, s conversion.Scope) error { + out.Namespace = in.Namespace + out.Name = in.Name + out.Key = in.Key + return nil +} + +// Convert_v1alpha2_SecretKeyRef_To_v1alpha1_SecretKeyRef is an autogenerated conversion function. +func Convert_v1alpha2_SecretKeyRef_To_v1alpha1_SecretKeyRef(in *v1alpha2.SecretKeyRef, out *SecretKeyRef, s conversion.Scope) error { + return autoConvert_v1alpha2_SecretKeyRef_To_v1alpha1_SecretKeyRef(in, out, s) +} + +func autoConvert_v1alpha1_Server_To_v1alpha2_Server(in *Server, out *v1alpha2.Server, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha1_ServerSpec_To_v1alpha2_ServerSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha1_ServerStatus_To_v1alpha2_ServerStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha1_Server_To_v1alpha2_Server is an autogenerated conversion function. +func Convert_v1alpha1_Server_To_v1alpha2_Server(in *Server, out *v1alpha2.Server, s conversion.Scope) error { + return autoConvert_v1alpha1_Server_To_v1alpha2_Server(in, out, s) +} + +func autoConvert_v1alpha2_Server_To_v1alpha1_Server(in *v1alpha2.Server, out *Server, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha2_ServerSpec_To_v1alpha1_ServerSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha2_ServerStatus_To_v1alpha1_ServerStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha2_Server_To_v1alpha1_Server is an autogenerated conversion function. +func Convert_v1alpha2_Server_To_v1alpha1_Server(in *v1alpha2.Server, out *Server, s conversion.Scope) error { + return autoConvert_v1alpha2_Server_To_v1alpha1_Server(in, out, s) +} + +func autoConvert_v1alpha1_ServerClass_To_v1alpha2_ServerClass(in *ServerClass, out *v1alpha2.ServerClass, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha1_ServerClassSpec_To_v1alpha2_ServerClassSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha1_ServerClassStatus_To_v1alpha2_ServerClassStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha1_ServerClass_To_v1alpha2_ServerClass is an autogenerated conversion function. +func Convert_v1alpha1_ServerClass_To_v1alpha2_ServerClass(in *ServerClass, out *v1alpha2.ServerClass, s conversion.Scope) error { + return autoConvert_v1alpha1_ServerClass_To_v1alpha2_ServerClass(in, out, s) +} + +func autoConvert_v1alpha2_ServerClass_To_v1alpha1_ServerClass(in *v1alpha2.ServerClass, out *ServerClass, s conversion.Scope) error { + out.ObjectMeta = in.ObjectMeta + if err := Convert_v1alpha2_ServerClassSpec_To_v1alpha1_ServerClassSpec(&in.Spec, &out.Spec, s); err != nil { + return err + } + if err := Convert_v1alpha2_ServerClassStatus_To_v1alpha1_ServerClassStatus(&in.Status, &out.Status, s); err != nil { + return err + } + return nil +} + +// Convert_v1alpha2_ServerClass_To_v1alpha1_ServerClass is an autogenerated conversion function. +func Convert_v1alpha2_ServerClass_To_v1alpha1_ServerClass(in *v1alpha2.ServerClass, out *ServerClass, s conversion.Scope) error { + return autoConvert_v1alpha2_ServerClass_To_v1alpha1_ServerClass(in, out, s) +} + +func autoConvert_v1alpha1_ServerClassList_To_v1alpha2_ServerClassList(in *ServerClassList, out *v1alpha2.ServerClassList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1alpha2.ServerClass, len(*in)) + for i := range *in { + if err := Convert_v1alpha1_ServerClass_To_v1alpha2_ServerClass(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha1_ServerClassList_To_v1alpha2_ServerClassList is an autogenerated conversion function. +func Convert_v1alpha1_ServerClassList_To_v1alpha2_ServerClassList(in *ServerClassList, out *v1alpha2.ServerClassList, s conversion.Scope) error { + return autoConvert_v1alpha1_ServerClassList_To_v1alpha2_ServerClassList(in, out, s) +} + +func autoConvert_v1alpha2_ServerClassList_To_v1alpha1_ServerClassList(in *v1alpha2.ServerClassList, out *ServerClassList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ServerClass, len(*in)) + for i := range *in { + if err := Convert_v1alpha2_ServerClass_To_v1alpha1_ServerClass(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha2_ServerClassList_To_v1alpha1_ServerClassList is an autogenerated conversion function. +func Convert_v1alpha2_ServerClassList_To_v1alpha1_ServerClassList(in *v1alpha2.ServerClassList, out *ServerClassList, s conversion.Scope) error { + return autoConvert_v1alpha2_ServerClassList_To_v1alpha1_ServerClassList(in, out, s) +} + +func autoConvert_v1alpha1_ServerClassSpec_To_v1alpha2_ServerClassSpec(in *ServerClassSpec, out *v1alpha2.ServerClassSpec, s conversion.Scope) error { + out.EnvironmentRef = (*v1.ObjectReference)(unsafe.Pointer(in.EnvironmentRef)) + if err := Convert_v1alpha1_Qualifiers_To_v1alpha2_Qualifiers(&in.Qualifiers, &out.Qualifiers, s); err != nil { + return err + } + out.Selector = in.Selector + out.ConfigPatches = *(*[]v1alpha2.ConfigPatches)(unsafe.Pointer(&in.ConfigPatches)) + out.BootFromDiskMethod = types.BootFromDisk(in.BootFromDiskMethod) + return nil +} + +// Convert_v1alpha1_ServerClassSpec_To_v1alpha2_ServerClassSpec is an autogenerated conversion function. +func Convert_v1alpha1_ServerClassSpec_To_v1alpha2_ServerClassSpec(in *ServerClassSpec, out *v1alpha2.ServerClassSpec, s conversion.Scope) error { + return autoConvert_v1alpha1_ServerClassSpec_To_v1alpha2_ServerClassSpec(in, out, s) +} + +func autoConvert_v1alpha2_ServerClassSpec_To_v1alpha1_ServerClassSpec(in *v1alpha2.ServerClassSpec, out *ServerClassSpec, s conversion.Scope) error { + out.EnvironmentRef = (*v1.ObjectReference)(unsafe.Pointer(in.EnvironmentRef)) + if err := Convert_v1alpha2_Qualifiers_To_v1alpha1_Qualifiers(&in.Qualifiers, &out.Qualifiers, s); err != nil { + return err + } + out.Selector = in.Selector + out.ConfigPatches = *(*[]ConfigPatches)(unsafe.Pointer(&in.ConfigPatches)) + out.BootFromDiskMethod = types.BootFromDisk(in.BootFromDiskMethod) + return nil +} + +// Convert_v1alpha2_ServerClassSpec_To_v1alpha1_ServerClassSpec is an autogenerated conversion function. +func Convert_v1alpha2_ServerClassSpec_To_v1alpha1_ServerClassSpec(in *v1alpha2.ServerClassSpec, out *ServerClassSpec, s conversion.Scope) error { + return autoConvert_v1alpha2_ServerClassSpec_To_v1alpha1_ServerClassSpec(in, out, s) +} + +func autoConvert_v1alpha1_ServerClassStatus_To_v1alpha2_ServerClassStatus(in *ServerClassStatus, out *v1alpha2.ServerClassStatus, s conversion.Scope) error { + out.ServersAvailable = *(*[]string)(unsafe.Pointer(&in.ServersAvailable)) + out.ServersInUse = *(*[]string)(unsafe.Pointer(&in.ServersInUse)) + return nil +} + +// Convert_v1alpha1_ServerClassStatus_To_v1alpha2_ServerClassStatus is an autogenerated conversion function. +func Convert_v1alpha1_ServerClassStatus_To_v1alpha2_ServerClassStatus(in *ServerClassStatus, out *v1alpha2.ServerClassStatus, s conversion.Scope) error { + return autoConvert_v1alpha1_ServerClassStatus_To_v1alpha2_ServerClassStatus(in, out, s) +} + +func autoConvert_v1alpha2_ServerClassStatus_To_v1alpha1_ServerClassStatus(in *v1alpha2.ServerClassStatus, out *ServerClassStatus, s conversion.Scope) error { + out.ServersAvailable = *(*[]string)(unsafe.Pointer(&in.ServersAvailable)) + out.ServersInUse = *(*[]string)(unsafe.Pointer(&in.ServersInUse)) + return nil +} + +// Convert_v1alpha2_ServerClassStatus_To_v1alpha1_ServerClassStatus is an autogenerated conversion function. +func Convert_v1alpha2_ServerClassStatus_To_v1alpha1_ServerClassStatus(in *v1alpha2.ServerClassStatus, out *ServerClassStatus, s conversion.Scope) error { + return autoConvert_v1alpha2_ServerClassStatus_To_v1alpha1_ServerClassStatus(in, out, s) +} + +func autoConvert_v1alpha1_ServerList_To_v1alpha2_ServerList(in *ServerList, out *v1alpha2.ServerList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]v1alpha2.Server, len(*in)) + for i := range *in { + if err := Convert_v1alpha1_Server_To_v1alpha2_Server(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha1_ServerList_To_v1alpha2_ServerList is an autogenerated conversion function. +func Convert_v1alpha1_ServerList_To_v1alpha2_ServerList(in *ServerList, out *v1alpha2.ServerList, s conversion.Scope) error { + return autoConvert_v1alpha1_ServerList_To_v1alpha2_ServerList(in, out, s) +} + +func autoConvert_v1alpha2_ServerList_To_v1alpha1_ServerList(in *v1alpha2.ServerList, out *ServerList, s conversion.Scope) error { + out.ListMeta = in.ListMeta + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Server, len(*in)) + for i := range *in { + if err := Convert_v1alpha2_Server_To_v1alpha1_Server(&(*in)[i], &(*out)[i], s); err != nil { + return err + } + } + } else { + out.Items = nil + } + return nil +} + +// Convert_v1alpha2_ServerList_To_v1alpha1_ServerList is an autogenerated conversion function. +func Convert_v1alpha2_ServerList_To_v1alpha1_ServerList(in *v1alpha2.ServerList, out *ServerList, s conversion.Scope) error { + return autoConvert_v1alpha2_ServerList_To_v1alpha1_ServerList(in, out, s) +} + +func autoConvert_v1alpha1_ServerSpec_To_v1alpha2_ServerSpec(in *ServerSpec, out *v1alpha2.ServerSpec, s conversion.Scope) error { + out.EnvironmentRef = (*v1.ObjectReference)(unsafe.Pointer(in.EnvironmentRef)) + out.Hostname = in.Hostname + // WARNING: in.SystemInformation requires manual conversion: does not exist in peer-type + // WARNING: in.CPU requires manual conversion: does not exist in peer-type + out.BMC = (*v1alpha2.BMC)(unsafe.Pointer(in.BMC)) + out.ManagementAPI = (*v1alpha2.ManagementAPI)(unsafe.Pointer(in.ManagementAPI)) + out.ConfigPatches = *(*[]v1alpha2.ConfigPatches)(unsafe.Pointer(&in.ConfigPatches)) + out.Accepted = in.Accepted + out.Cordoned = in.Cordoned + out.PXEBootAlways = in.PXEBootAlways + out.BootFromDiskMethod = types.BootFromDisk(in.BootFromDiskMethod) + return nil +} + +func autoConvert_v1alpha2_ServerSpec_To_v1alpha1_ServerSpec(in *v1alpha2.ServerSpec, out *ServerSpec, s conversion.Scope) error { + out.EnvironmentRef = (*v1.ObjectReference)(unsafe.Pointer(in.EnvironmentRef)) + // WARNING: in.Hardware requires manual conversion: does not exist in peer-type + out.Hostname = in.Hostname + out.BMC = (*BMC)(unsafe.Pointer(in.BMC)) + out.ManagementAPI = (*ManagementAPI)(unsafe.Pointer(in.ManagementAPI)) + out.ConfigPatches = *(*[]ConfigPatches)(unsafe.Pointer(&in.ConfigPatches)) + out.Accepted = in.Accepted + out.Cordoned = in.Cordoned + out.PXEBootAlways = in.PXEBootAlways + out.BootFromDiskMethod = types.BootFromDisk(in.BootFromDiskMethod) + return nil +} + +func autoConvert_v1alpha1_ServerStatus_To_v1alpha2_ServerStatus(in *ServerStatus, out *v1alpha2.ServerStatus, s conversion.Scope) error { + out.Ready = in.Ready + out.InUse = in.InUse + out.IsClean = in.IsClean + out.Conditions = *(*[]v1beta1.Condition)(unsafe.Pointer(&in.Conditions)) + out.Addresses = *(*[]v1.NodeAddress)(unsafe.Pointer(&in.Addresses)) + out.Power = in.Power + return nil +} + +// Convert_v1alpha1_ServerStatus_To_v1alpha2_ServerStatus is an autogenerated conversion function. +func Convert_v1alpha1_ServerStatus_To_v1alpha2_ServerStatus(in *ServerStatus, out *v1alpha2.ServerStatus, s conversion.Scope) error { + return autoConvert_v1alpha1_ServerStatus_To_v1alpha2_ServerStatus(in, out, s) +} + +func autoConvert_v1alpha2_ServerStatus_To_v1alpha1_ServerStatus(in *v1alpha2.ServerStatus, out *ServerStatus, s conversion.Scope) error { + out.Ready = in.Ready + out.InUse = in.InUse + out.IsClean = in.IsClean + out.Conditions = *(*[]v1beta1.Condition)(unsafe.Pointer(&in.Conditions)) + out.Addresses = *(*[]v1.NodeAddress)(unsafe.Pointer(&in.Addresses)) + out.Power = in.Power + return nil +} + +// Convert_v1alpha2_ServerStatus_To_v1alpha1_ServerStatus is an autogenerated conversion function. +func Convert_v1alpha2_ServerStatus_To_v1alpha1_ServerStatus(in *v1alpha2.ServerStatus, out *ServerStatus, s conversion.Scope) error { + return autoConvert_v1alpha2_ServerStatus_To_v1alpha1_ServerStatus(in, out, s) +} + +func autoConvert_v1alpha1_SystemInformation_To_v1alpha2_SystemInformation(in *SystemInformation, out *v1alpha2.SystemInformation, s conversion.Scope) error { + out.Manufacturer = in.Manufacturer + out.ProductName = in.ProductName + out.Version = in.Version + out.SerialNumber = in.SerialNumber + out.SKUNumber = in.SKUNumber + out.Family = in.Family + return nil +} + +// Convert_v1alpha1_SystemInformation_To_v1alpha2_SystemInformation is an autogenerated conversion function. +func Convert_v1alpha1_SystemInformation_To_v1alpha2_SystemInformation(in *SystemInformation, out *v1alpha2.SystemInformation, s conversion.Scope) error { + return autoConvert_v1alpha1_SystemInformation_To_v1alpha2_SystemInformation(in, out, s) +} + +func autoConvert_v1alpha2_SystemInformation_To_v1alpha1_SystemInformation(in *v1alpha2.SystemInformation, out *SystemInformation, s conversion.Scope) error { + // WARNING: in.Uuid requires manual conversion: does not exist in peer-type + out.Manufacturer = in.Manufacturer + out.ProductName = in.ProductName + out.Version = in.Version + out.SerialNumber = in.SerialNumber + out.SKUNumber = in.SKUNumber + out.Family = in.Family + return nil +} diff --git a/app/sidero-controller-manager/api/v1alpha2/doc.go b/app/sidero-controller-manager/api/v1alpha2/doc.go new file mode 100644 index 000000000..fd95a0726 --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha2/doc.go @@ -0,0 +1,5 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package v1alpha2 diff --git a/app/sidero-controller-manager/api/v1alpha2/environment_conversion.go b/app/sidero-controller-manager/api/v1alpha2/environment_conversion.go new file mode 100644 index 000000000..cd8e4ebf9 --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha2/environment_conversion.go @@ -0,0 +1,8 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package v1alpha2 + +func (*Environment) Hub() {} +func (*EnvironmentList) Hub() {} diff --git a/app/sidero-controller-manager/api/v1alpha2/environment_types.go b/app/sidero-controller-manager/api/v1alpha2/environment_types.go new file mode 100644 index 000000000..0e92621df --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha2/environment_types.go @@ -0,0 +1,123 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package v1alpha2 + +import ( + "fmt" + "sort" + + "github.com/talos-systems/talos/pkg/machinery/kernel" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EnvironmentDefault is an automatically created Environment. +const EnvironmentDefault = "default" + +type Asset struct { + URL string `json:"url,omitempty"` + SHA512 string `json:"sha512,omitempty"` +} + +type Kernel struct { + Asset `json:",inline"` + + Args []string `json:"args,omitempty"` +} + +type Initrd struct { + Asset `json:",inline"` +} + +// EnvironmentSpec defines the desired state of Environment. +type EnvironmentSpec struct { + Kernel Kernel `json:"kernel,omitempty"` + Initrd Initrd `json:"initrd,omitempty"` +} + +type AssetCondition struct { + Asset `json:",inline"` + Status string `json:"status"` + Type string `json:"type"` +} + +// EnvironmentStatus defines the observed state of Environment. +type EnvironmentStatus struct { + Conditions []AssetCondition `json:"conditions,omitempty"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:resource:scope=Cluster +// +kubebuilder:printcolumn:name="Kernel",type="string",JSONPath=".spec.kernel.url",description="the kernel for the environment" +// +kubebuilder:printcolumn:name="Initrd",type="string",JSONPath=".spec.initrd.url",description="the initrd for the environment" +// +kubebuilder:printcolumn:name="Ready",type="string",JSONPath=".status.conditions[?(@.type==\"Ready\")].status",description="indicates the readiness of the environment" +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="The age of this resource" +// +kubebuilder:storageversion + +// Environment is the Schema for the environments API. +type Environment struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec EnvironmentSpec `json:"spec,omitempty"` + Status EnvironmentStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// EnvironmentList contains a list of Environment. +type EnvironmentList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Environment `json:"items"` +} + +// EnvironmentDefaultSpec returns EnvironmentDefault's spec. +func EnvironmentDefaultSpec(talosRelease, apiEndpoint string, apiPort uint16) *EnvironmentSpec { + args := make([]string, 0, len(kernel.DefaultArgs)+6) + args = append(args, kernel.DefaultArgs...) + args = append(args, "console=tty0", "console=ttyS0", "earlyprintk=ttyS0") + args = append(args, "initrd=initramfs.xz", "talos.platform=metal") + sort.Strings(args) + + return &EnvironmentSpec{ + Kernel: Kernel{ + Asset: Asset{ + URL: fmt.Sprintf("https://github.com/talos-systems/talos/releases/download/%s/vmlinuz-amd64", talosRelease), + }, + Args: args, + }, + Initrd: Initrd{ + Asset: Asset{ + URL: fmt.Sprintf("https://github.com/talos-systems/talos/releases/download/%s/initramfs-amd64.xz", talosRelease), + }, + }, + } +} + +// IsReady returns aggregated Environment readiness. +func (env *Environment) IsReady() bool { + assetURLs := map[string]struct{}{} + + if env.Spec.Kernel.URL != "" { + assetURLs[env.Spec.Kernel.URL] = struct{}{} + } + + if env.Spec.Initrd.URL != "" { + assetURLs[env.Spec.Initrd.URL] = struct{}{} + } + + for _, cond := range env.Status.Conditions { + if cond.Status == "True" && cond.Type == "Ready" { + delete(assetURLs, cond.URL) + } + } + + return len(assetURLs) == 0 +} + +func init() { + SchemeBuilder.Register(&Environment{}, &EnvironmentList{}) +} diff --git a/app/sidero-controller-manager/api/v1alpha2/groupversion_info.go b/app/sidero-controller-manager/api/v1alpha2/groupversion_info.go new file mode 100644 index 000000000..35a2bc3bc --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha2/groupversion_info.go @@ -0,0 +1,24 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// package v1alpha2 contains API Schema definitions for the metal v1alpha2 API group +// +kubebuilder:object:generate=true +// +groupName=metal.sidero.dev +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: "metal.sidero.dev", 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 +) diff --git a/app/sidero-controller-manager/api/v1alpha2/server_conversion.go b/app/sidero-controller-manager/api/v1alpha2/server_conversion.go new file mode 100644 index 000000000..f32f528a2 --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha2/server_conversion.go @@ -0,0 +1,8 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package v1alpha2 + +func (*Server) Hub() {} +func (*ServerList) Hub() {} diff --git a/app/sidero-controller-manager/api/v1alpha2/server_types.go b/app/sidero-controller-manager/api/v1alpha2/server_types.go new file mode 100644 index 000000000..e3d1e5e55 --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha2/server_types.go @@ -0,0 +1,328 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package v1alpha2 + +import ( + "context" + "fmt" + "reflect" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" + "sigs.k8s.io/controller-runtime/pkg/client" + + siderotypes "github.com/talos-systems/sidero/app/sidero-controller-manager/pkg/types" +) + +// BMC defines data about how to talk to the node via ipmitool. +type BMC struct { + // BMC endpoint. + Endpoint string `json:"endpoint"` + // BMC port. Defaults to 623. + // +optional + Port uint32 `json:"port,omitempty"` + // BMC user value. + // +optional + User string `json:"user,omitempty"` + // Source for the user value. Cannot be used if User is not empty. + // +optional + UserFrom *CredentialSource `json:"userFrom,omitempty"` + // BMC password value. + // +optional + Pass string `json:"pass,omitempty"` + // Source for the password value. Cannot be used if Pass is not empty. + // +optional + PassFrom *CredentialSource `json:"passFrom,omitempty"` + // BMC Interface Type. Defaults to lanplus. + // +optional + Interface string `json:"interface,omitempty"` +} + +// CredentialSource defines a reference to the credential value. +type CredentialSource struct { + SecretKeyRef *SecretKeyRef `json:"secretKeyRef,omitempty"` +} + +// SecretKeyRef defines a ref to a given key within a secret. +type SecretKeyRef struct { + // Namespace and name of credential secret + // nb: can't use namespacedname here b/c it doesn't have json tags in the struct :( + Namespace string `json:"namespace"` + Name string `json:"name"` + // Key to select + Key string `json:"key"` +} + +// Resolve the value using the references. +func (source *CredentialSource) Resolve(ctx context.Context, reader client.Client) (string, error) { + if source == nil { + return "", nil + } + + if source.SecretKeyRef == nil { + return "", fmt.Errorf("missing secretKeyRef") + } + + var secrets corev1.Secret + + if err := reader.Get( + ctx, + types.NamespacedName{ + Namespace: source.SecretKeyRef.Namespace, + Name: source.SecretKeyRef.Name, + }, + &secrets, + ); err != nil { + return "", fmt.Errorf("error getting secret %q: %w", source.SecretKeyRef.Name, err) + } + + rawValue, ok := secrets.Data[source.SecretKeyRef.Key] + if !ok { + return "", fmt.Errorf("secret key %q is missing in secret %q", source.SecretKeyRef.Key, source.SecretKeyRef.Name) + } + + return string(rawValue), nil +} + +// ManagementAPI defines data about how to talk to the node via simple HTTP API. +type ManagementAPI struct { + Endpoint string `json:"endpoint"` +} + +type SystemInformation struct { + Uuid string `json:"uuid,omitempty"` + Manufacturer string `json:"manufacturer,omitempty"` + ProductName string `json:"productName,omitempty"` + Version string `json:"version,omitempty"` + SerialNumber string `json:"serialNumber,omitempty"` + SKUNumber string `json:"skuNumber,omitempty"` + Family string `json:"family,omitempty"` +} + +type Processor struct { + Manufacturer string `json:"manufacturer,omitempty"` + ProductName string `json:"productName,omitempty"` + SerialNumber string `json:"serialNumber,omitempty"` + // Speed is in megahertz (Mhz) + Speed uint32 `json:"speed,omitempty"` + CoreCount uint32 `json:"coreCount,omitempty"` + ThreadCount uint32 `json:"threadCount,omitempty"` +} + +type ComputeInformation struct { + TotalCoreCount uint32 `json:"totalCoreCount,omitempty"` + TotalThreadCount uint32 `json:"totalThreadCount,omitempty"` + ProcessorCount uint32 `json:"processorCount,omitempty"` + Processors []*Processor `json:"processors,omitempty"` +} + +type MemoryModule struct { + Manufacturer string `json:"manufacturer,omitempty"` + ProductName string `json:"productName,omitempty"` + SerialNumber string `json:"serialNumber,omitempty"` + Type string `json:"type,omitempty"` + // Size is in megabytes (MB) + Size uint32 `json:"size,omitempty"` + // Speed is in megatransfers per second (MT/S) + Speed uint32 `json:"speed,omitempty"` +} + +type MemoryInformation struct { + TotalSize string `json:"totalSize,omitempty"` + ModuleCount uint32 `json:"moduleCount,omitempty"` + Modules []*MemoryModule `json:"modules,omitempty"` +} + +type StorageDevice struct { + Type string `json:"type,omitempty"` + // Size is in bytes + Size uint64 `json:"size,omitempty"` + Model string `json:"productName,omitempty"` + Serial string `json:"serialNumber,omitempty"` + Name string `json:"name,omitempty"` + DeviceName string `json:"deviceName,omitempty"` + UUID string `json:"uuid,omitempty"` + WWID string `json:"wwid,omitempty"` +} + +type StorageInformation struct { + TotalSize string `json:"totalSize,omitempty"` + DeviceCount uint32 `json:"deviceCount,omitempty"` + Devices []*StorageDevice `json:"devices,omitempty"` +} + +type NetworkInterface struct { + Index uint32 `json:"index,omitempty"` + Name string `json:"name,omitempty"` + Flags string `json:"flags,omitempty"` + MTU uint32 `json:"mtu,omitempty"` + MAC string `json:"mac,omitempty"` + Addresses []string `json:"addresses,omitempty"` +} + +type NetworkInformation struct { + InterfaceCount uint32 `json:"interfaceCount,omitempty"` + Interfaces []*NetworkInterface `json:"interfaces,omitempty"` +} + +type HardwareInformation struct { + System *SystemInformation `json:"system,omitempty"` + Compute *ComputeInformation `json:"compute,omitempty"` + Memory *MemoryInformation `json:"memory,omitempty"` + Storage *StorageInformation `json:"storage,omitempty"` + Network *NetworkInformation `json:"network,omitempty"` +} + +func (a *HardwareInformation) PartialEqual(b *HardwareInformation) bool { + return PartialEqual(a, b) +} + +func PartialEqual(a, b interface{}) bool { + old := reflect.ValueOf(a) + new := reflect.ValueOf(b) + + if old.Kind() == reflect.Ptr { + old = old.Elem() + } + + if new.Kind() == reflect.Ptr { + new = new.Elem() + } + + // Skip invalid or zero values, since that indicates that the user + // did not supply the field, and does not want to compare it. + if !old.IsValid() || old.IsZero() { + return true + } + + if old.Kind() == reflect.Struct && new.Kind() == reflect.Struct { + // Recursively compare structs + for i := 0; i < old.NumField(); i++ { + f1 := old.Field(i).Interface() + f2 := new.Field(i).Interface() + + if !PartialEqual(f1, f2) { + return false + } + } + } else if old.Kind() == reflect.Slice && new.Kind() == reflect.Slice { + // Skip slices where the requested slice is larger than the actual slice, + // as that indicates that the user wants to filter for more + // processors/memory modules/storage devices than are present. + if old.Len() > new.Len() { + return false + } + // Recursively compare slices + for i := 0; i < old.Len(); i++ { + f1 := old.Index(i).Interface() + f2 := new.Index(i).Interface() + + if !PartialEqual(f1, f2) { + return false + } + } + } else { + // Directly compare values, but only if the actual value is valid. + return new.IsValid() && old.Interface() == new.Interface() + } + + return true +} + +// ServerSpec defines the desired state of Server. +type ServerSpec struct { + EnvironmentRef *corev1.ObjectReference `json:"environmentRef,omitempty"` + Hardware *HardwareInformation `json:"hardware,omitempty"` + Hostname string `json:"hostname,omitempty"` + BMC *BMC `json:"bmc,omitempty"` + ManagementAPI *ManagementAPI `json:"managementApi,omitempty"` + ConfigPatches []ConfigPatches `json:"configPatches,omitempty"` + Accepted bool `json:"accepted"` + Cordoned bool `json:"cordoned,omitempty"` + PXEBootAlways bool `json:"pxeBootAlways,omitempty"` + // BootFromDiskMethod specifies the method to exit iPXE to force boot from disk. + // + // If not set, controller default is used. + // Valid values: ipxe-exit, http-404, ipxe-sanboot. + // + // +optional + BootFromDiskMethod siderotypes.BootFromDisk `json:"bootFromDiskMethod,omitempty"` +} + +const ( + // ConditionPowerCycle is used to control the powercycle flow. + ConditionPowerCycle clusterv1.ConditionType = "PowerCycle" + // ConditionPXEBooted is used to record the fact that server got PXE booted. + ConditionPXEBooted clusterv1.ConditionType = "PXEBooted" +) + +// ServerStatus defines the observed state of Server. +type ServerStatus struct { + // Ready is true when server is accepted and in use. + // +optional + Ready bool `json:"ready"` + + // InUse is true when server is assigned to some MetalMachine. + // +optional + InUse bool `json:"inUse"` + + // IsClean is true when server disks are wiped. + // +optional + IsClean bool `json:"isClean"` + + // Conditions defines current service state of the Server. + Conditions []clusterv1.Condition `json:"conditions,omitempty"` + + // Addresses lists discovered node IPs. + Addresses []corev1.NodeAddress `json:"addresses,omitempty"` + + // Power is the current power state of the server: "on", "off" or "unknown". + Power string `json:"power,omitempty"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:resource:scope=Cluster +// +kubebuilder:printcolumn:name="Hostname",type="string",JSONPath=".spec.hostname",description="server hostname" +// +kubebuilder:printcolumn:name="BMC IP",type="string",priority=1,JSONPath=".spec.bmc.endpoint",description="BMC IP" +// +kubebuilder:printcolumn:name="Accepted",type="boolean",JSONPath=".spec.accepted",description="indicates if the server is accepted" +// +kubebuilder:printcolumn:name="Cordoned",type="boolean",JSONPath=".spec.cordoned",description="indicates if the server is cordoned" +// +kubebuilder:printcolumn:name="Allocated",type="boolean",JSONPath=".status.inUse",description="indicates that the server has been allocated" +// +kubebuilder:printcolumn:name="Clean",type="boolean",JSONPath=".status.isClean",description="indicates if the server is clean or not" +// +kubebuilder:printcolumn:name="Power",type="string",JSONPath=".status.power",description="display the current power status" +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="The age of this resource" +// +kubebuilder:storageversion + +// Server is the Schema for the servers API. +type Server struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ServerSpec `json:"spec,omitempty"` + Status ServerStatus `json:"status,omitempty"` +} + +func (s *Server) GetConditions() clusterv1.Conditions { + return s.Status.Conditions +} + +func (s *Server) SetConditions(conditions clusterv1.Conditions) { + s.Status.Conditions = conditions +} + +// +kubebuilder:object:root=true + +// ServerList contains a list of Server. +type ServerList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Server `json:"items"` +} + +func init() { + SchemeBuilder.Register(&Server{}, &ServerList{}) +} diff --git a/app/sidero-controller-manager/api/v1alpha2/server_types_test.go b/app/sidero-controller-manager/api/v1alpha2/server_types_test.go new file mode 100644 index 000000000..92d0fe9c8 --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha2/server_types_test.go @@ -0,0 +1,147 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +//nolint:scopelint +package v1alpha2_test + +import ( + "testing" + + metal "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" +) + +func Test_PartialEqual(t *testing.T) { + info := &metal.HardwareInformation{ + System: &metal.SystemInformation{ + Uuid: "4c4c4544-0039-3010-8048-b7c04f384432", + Manufacturer: "Dell Inc.", + ProductName: "PowerEdge R630", + SerialNumber: "790H8D2", + SKUNumber: "", + Family: "", + }, + Compute: &metal.ComputeInformation{ + TotalCoreCount: 8, + TotalThreadCount: 16, + ProcessorCount: 1, + Processors: []*metal.Processor{ + { + Manufacturer: "Intel", + ProductName: "Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz", + SerialNumber: "", + Speed: 2400, + CoreCount: 8, + ThreadCount: 16, + }, + }, + }, + Memory: &metal.MemoryInformation{ + TotalSize: "32 GB", + ModuleCount: 2, + Modules: []*metal.MemoryModule{ + { + Manufacturer: "002C00B3002C", + ProductName: "18ASF2G72PDZ-2G3B1", + SerialNumber: "12BDC045", + Type: "LPDDR3", + Size: 16384, + Speed: 2400, + }, + { + Manufacturer: "002C00B3002C", + ProductName: "18ASF2G72PDZ-2G3B1", + SerialNumber: "12BDBF5D", + Type: "LPDDR3", + Size: 16384, + Speed: 2400, + }, + }, + }, + Storage: &metal.StorageInformation{ + TotalSize: "1116 GB", + DeviceCount: 1, + Devices: []*metal.StorageDevice{ + { + Type: "HDD", + Size: 1199101181952, + Model: "PERC H730 Mini", + Serial: "", + Name: "sda", + DeviceName: "/dev/sda", + UUID: "", + WWID: "naa.61866da055de070028d8e83307cc6df2", + }, + }, + }, + Network: &metal.NetworkInformation{ + InterfaceCount: 2, + Interfaces: []*metal.NetworkInterface{ + { + Index: 1, + Name: "lo", + Flags: "up|loopback", + MTU: 65536, + MAC: "", + Addresses: []string{"127.0.0.1/8", "::1/128"}, + }, + { + Index: 2, + Name: "enp3s0", + Flags: "up|broadcast|multicast", + MTU: 1500, + MAC: "40:8d:5c:86:5a:14", + Addresses: []string{"192.168.2.8/24", "fe80::dcb3:295c:755b:91bb/64"}, + }, + }, + }, + } + + tests := []struct { + name string + args *metal.HardwareInformation + want bool + }{ + { + name: "defaults are partially equal", + args: &metal.HardwareInformation{}, + want: true, + }, + { + name: "cpu is partially equal", + args: &metal.HardwareInformation{ + Compute: &metal.ComputeInformation{ + Processors: []*metal.Processor{ + { + Manufacturer: "Intel", + }, + }, + }, + // Skip all other fields to indicate that we don't want to compare it. + }, + want: true, + }, + { + name: "cpu is not partially equal", + args: &metal.HardwareInformation{ + Compute: &metal.ComputeInformation{ + Processors: []*metal.Processor{ + { + Manufacturer: "AMD", + }, + }, + }, + // Skip all other fields to indicate that we don't want to compare it. + }, + want: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := tt.args.PartialEqual(info); got != tt.want { + t.Errorf("PartialEqual() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/app/sidero-controller-manager/api/v1alpha2/serverclass_conversion.go b/app/sidero-controller-manager/api/v1alpha2/serverclass_conversion.go new file mode 100644 index 000000000..dbeb291af --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha2/serverclass_conversion.go @@ -0,0 +1,8 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package v1alpha2 + +func (*ServerClass) Hub() {} +func (*ServerClassList) Hub() {} diff --git a/app/sidero-controller-manager/api/v1alpha2/serverclass_filter.go b/app/sidero-controller-manager/api/v1alpha2/serverclass_filter.go new file mode 100644 index 000000000..f5ce08250 --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha2/serverclass_filter.go @@ -0,0 +1,110 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package v1alpha2 + +import ( + "fmt" + "sort" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +// AcceptedServerFilter matches Servers that have Spec.Accepted set to true. +func AcceptedServerFilter(s Server) (bool, error) { + return s.Spec.Accepted, nil +} + +// NotCordonedServerFilter matches Servers that have Spec.Paused set to false. +func NotCordonedServerFilter(s Server) (bool, error) { + return !s.Spec.Cordoned, nil +} + +// SelectorFilter returns a ServerFilter that matches servers against the +// serverclass's selector field. +func (sc *ServerClass) SelectorFilter() func(Server) (bool, error) { + return func(server Server) (bool, error) { + s, err := metav1.LabelSelectorAsSelector(&sc.Spec.Selector) + if err != nil { + return false, fmt.Errorf("failed to get selector from labelselector: %v", err) + } + + return s.Matches(labels.Set(server.GetLabels())), nil + } +} + +// QualifiersFilter returns a ServerFilter that matches servers against the +// serverclass's qualifiers field. +func (sc *ServerClass) QualifiersFilter() func(Server) (bool, error) { + return func(server Server) (bool, error) { + q := sc.Spec.Qualifiers + + // check hardware qualifiers if they are present + if filters := q.Hardware; len(filters) > 0 { + var match bool + + for _, filter := range filters { + if info := server.Spec.Hardware; info != nil && filter.PartialEqual(info) { + match = true + break + } + } + + if !match { + return false, nil + } + } + + if filters := q.LabelSelectors; len(filters) > 0 { + var match bool + + for _, filter := range filters { + for labelKey, labelVal := range filter { + if val, ok := server.ObjectMeta.Labels[labelKey]; ok && labelVal == val { + match = true + break + } + } + } + + if !match { + return false, nil + } + } + + return true, nil + } +} + +// FilterServers returns the subset of servers that pass all provided filters. +// In case of error the returned slice will be nil. +func FilterServers(servers []Server, filters ...func(Server) (bool, error)) ([]Server, error) { + matches := make([]Server, 0, len(servers)) + + for _, server := range servers { + match := true + + for _, filter := range filters { + var err error + + match, err = filter(server) + if err != nil { + return nil, fmt.Errorf("failed to filter server: %v", err) + } + + if !match { + break + } + } + + if match { + matches = append(matches, server) + } + } + + sort.Slice(matches, func(i, j int) bool { return matches[i].Name < matches[j].Name }) + + return matches, nil +} diff --git a/app/sidero-controller-manager/api/v1alpha2/serverclass_filter_test.go b/app/sidero-controller-manager/api/v1alpha2/serverclass_filter_test.go new file mode 100644 index 000000000..125bec1dc --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha2/serverclass_filter_test.go @@ -0,0 +1,378 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package v1alpha2_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + metal "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" +) + +func TestFilterAcceptedServers(t *testing.T) { + t.Parallel() + + atom := metal.Server{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "common-label": "true", + "zone": "central", + }, + }, + Spec: metal.ServerSpec{ + Accepted: true, + Hardware: &metal.HardwareInformation{ + Compute: &metal.ComputeInformation{ + TotalCoreCount: 4, + TotalThreadCount: 4, + ProcessorCount: 1, + Processors: []*metal.Processor{ + { + Manufacturer: "Intel(R) Corporation", + ProductName: "Intel(R) Atom(TM) CPU C3558 @ 2.20GHz", + SerialNumber: "", + Speed: 2200, + CoreCount: 4, + ThreadCount: 4, + }, + }, + }, + }, + }, + } + dualXeon := metal.Server{ + Spec: metal.ServerSpec{ + Accepted: true, + Hardware: &metal.HardwareInformation{ + Compute: &metal.ComputeInformation{ + TotalCoreCount: 16, + TotalThreadCount: 32, + ProcessorCount: 2, + Processors: []*metal.Processor{ + { + Manufacturer: "Intel(R) Corporation", + ProductName: "Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz", + SerialNumber: "", + Speed: 2400, + CoreCount: 8, + ThreadCount: 16, + }, + { + Manufacturer: "Intel(R) Corporation", + ProductName: "Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz", + SerialNumber: "", + Speed: 2400, + CoreCount: 8, + ThreadCount: 16, + }, + }, + }, + }, + }, + } + ryzen := metal.Server{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "common-label": "true", + "zone": "east", + }, + }, + Spec: metal.ServerSpec{ + Accepted: true, + Hardware: &metal.HardwareInformation{ + System: &metal.SystemInformation{ + Manufacturer: "QEMU", + }, + Compute: &metal.ComputeInformation{ + TotalCoreCount: 8, + TotalThreadCount: 16, + ProcessorCount: 1, + Processors: []*metal.Processor{ + { + Manufacturer: "Advanced Micro Devices, Inc.", + ProductName: "AMD Ryzen 7 2700X Eight-Core Processor", + SerialNumber: "", + Speed: 3700, + CoreCount: 8, + ThreadCount: 16, + }, + }, + }, + }, + }, + } + notAccepted := metal.Server{ + ObjectMeta: metav1.ObjectMeta{ + Labels: map[string]string{ + "common-label": "true", + "zone": "west", + }, + }, + Spec: metal.ServerSpec{ + Accepted: false, + Hardware: &metal.HardwareInformation{ + System: &metal.SystemInformation{ + Manufacturer: "QEMU", + }, + Compute: &metal.ComputeInformation{ + TotalCoreCount: 8, + TotalThreadCount: 16, + ProcessorCount: 1, + Processors: []*metal.Processor{ + { + Manufacturer: "Advanced Micro Devices, Inc.", + ProductName: "AMD Ryzen 7 2700X Eight-Core Processor", + SerialNumber: "", + Speed: 3700, + CoreCount: 8, + ThreadCount: 16, + }, + }, + }, + }, + }, + } + + servers := []metal.Server{atom, dualXeon, ryzen, notAccepted} + + testdata := map[string]struct { + s metav1.LabelSelector + q metal.Qualifiers + expected []metal.Server + }{ + "empty selector - empty qualifier": { + // Matches all servers + expected: []metal.Server{atom, dualXeon, ryzen}, + }, + "Intel only": { + q: metal.Qualifiers{ + Hardware: []metal.HardwareInformation{ + { + Compute: &metal.ComputeInformation{ + Processors: []*metal.Processor{ + { + Manufacturer: "Intel(R) Corporation", + }, + }, + }, + }, + }, + }, + expected: []metal.Server{atom, dualXeon}, + }, + "Intel and AMD": { + q: metal.Qualifiers{ + Hardware: []metal.HardwareInformation{ + { + Compute: &metal.ComputeInformation{ + Processors: []*metal.Processor{ + { + Manufacturer: "Intel(R) Corporation", + }, + }, + }, + }, + { + Compute: &metal.ComputeInformation{ + Processors: []*metal.Processor{ + { + Manufacturer: "Advanced Micro Devices, Inc.", + }, + }, + }, + }, + }, + }, + expected: []metal.Server{atom, dualXeon, ryzen}, + }, + "QEMU only": { + q: metal.Qualifiers{ + Hardware: []metal.HardwareInformation{ + { + System: &metal.SystemInformation{ + Manufacturer: "QEMU", + }, + }, + }, + }, + expected: []metal.Server{ryzen}, + }, + "with label": { + q: metal.Qualifiers{ + LabelSelectors: []map[string]string{ + { + "common-label": "true", + }, + }, + }, + expected: []metal.Server{atom, ryzen}, + }, + // This should probably only return atom. Leaving it as-is to + // avoid breaking changes before we remove LabelSelectors in + // favor of Selector. + "with multiple labels - single selector": { + q: metal.Qualifiers{ + LabelSelectors: []map[string]string{ + { + "common-label": "true", + "zone": "central", + }, + }, + }, + expected: []metal.Server{atom, ryzen}, + }, + "with multiple labels - multiple selectors": { + q: metal.Qualifiers{ + LabelSelectors: []map[string]string{ + { + "common-label": "true", + }, + { + "zone": "central", + }, + }, + }, + expected: []metal.Server{atom, ryzen}, + }, + "with same label key different label value": { + q: metal.Qualifiers{ + LabelSelectors: []map[string]string{ + { + "zone": "central", + }, + }, + }, + expected: []metal.Server{atom}, + }, + "selector - single MatchLabels single result": { + s: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "zone": "central", + }, + }, + expected: []metal.Server{atom}, + }, + "selector - single MatchLabels multiple results": { + s: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "common-label": "true", + }, + }, + expected: []metal.Server{atom, ryzen}, + }, + "selector - multiple MatchLabels": { + s: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "zone": "central", + "common-label": "true", + }, + }, + expected: []metal.Server{atom}, + }, + "selector - MatchExpressions common label key": { + s: metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: "common-label", + Operator: "Exists", + }, + }, + }, + expected: []metal.Server{atom, ryzen}, + }, + "selector - MatchExpressions multiple values": { + s: metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: "zone", + Operator: "In", + Values: []string{ + "east", + "west", + }, + }, + }, + }, + expected: []metal.Server{ryzen}, + }, + "selector and qualifiers both match": { + s: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "common-label": "true", + }, + }, + q: metal.Qualifiers{ + Hardware: []metal.HardwareInformation{ + { + System: &metal.SystemInformation{ + Manufacturer: "QEMU", + }, + }, + }, + }, + expected: []metal.Server{ryzen}, + }, + "selector and qualifiers with disqualifying selector": { + s: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "common-label": "no-match", + }, + }, + q: metal.Qualifiers{ + Hardware: []metal.HardwareInformation{ + { + System: &metal.SystemInformation{ + Manufacturer: "QEMU", + }, + }, + }, + }, + expected: []metal.Server{}, + }, + "selector and qualifiers with disqualifying qualifier": { + s: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "common-label": "true", + }, + }, + q: metal.Qualifiers{ + Hardware: []metal.HardwareInformation{ + { + System: &metal.SystemInformation{ + Manufacturer: "Gateway", + }, + }, + }, + }, + expected: []metal.Server{}, + }, + metal.ServerClassAny: { + expected: []metal.Server{atom, dualXeon, ryzen}, + }, + } + + for name, td := range testdata { + name, td := name, td + t.Run(name, func(t *testing.T) { + t.Parallel() + + sc := &metal.ServerClass{ + Spec: metal.ServerClassSpec{ + Selector: td.s, + Qualifiers: td.q, + }, + } + actual, err := metal.FilterServers(servers, + metal.AcceptedServerFilter, + sc.SelectorFilter(), + sc.QualifiersFilter(), + ) + assert.NoError(t, err) + assert.Equal(t, td.expected, actual) + }) + } +} diff --git a/app/sidero-controller-manager/api/v1alpha2/serverclass_types.go b/app/sidero-controller-manager/api/v1alpha2/serverclass_types.go new file mode 100644 index 000000000..45ea2ba92 --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha2/serverclass_types.go @@ -0,0 +1,84 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package v1alpha2 + +import ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + siderotypes "github.com/talos-systems/sidero/app/sidero-controller-manager/pkg/types" +) + +// ServerClassAny is an automatically created ServerClass that includes all Servers. +const ServerClassAny = "any" + +type Qualifiers struct { + Hardware []HardwareInformation `json:"hardware,omitempty"` + LabelSelectors []map[string]string `json:"labelSelectors,omitempty"` +} + +// ServerClassSpec defines the desired state of ServerClass. +type ServerClassSpec struct { + // Reference to the environment which should be used to provision the servers via this server class. + // +optional + EnvironmentRef *corev1.ObjectReference `json:"environmentRef,omitempty"` + // Qualifiers to match on the server spec. + // + // If qualifiers are empty, they match all servers. + // Server should match both qualifiers and selector conditions to be included into the server class. + // +optional + Qualifiers Qualifiers `json:"qualifiers"` + // Label selector to filter the matching servers based on labels. + // A label selector is a label query over a set of resources. The result of matchLabels and + // matchExpressions are ANDed. An empty label selector matches all objects. A null label selector matches no objects. + // +optional + Selector metav1.LabelSelector `json:"selector"` + // Set of config patches to apply to the machine configuration to the servers provisioned via this server class. + // +optional + ConfigPatches []ConfigPatches `json:"configPatches,omitempty"` + // BootFromDiskMethod specifies the method to exit iPXE to force boot from disk. + // + // If not set, controller default is used. + // Valid values: ipxe-exit, http-404, ipxe-sanboot. + // + // +optional + BootFromDiskMethod siderotypes.BootFromDisk `json:"bootFromDiskMethod,omitempty"` +} + +// ServerClassStatus defines the observed state of ServerClass. +type ServerClassStatus struct { + ServersAvailable []string `json:"serversAvailable"` + ServersInUse []string `json:"serversInUse"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:resource:scope=Cluster +// +kubebuilder:printcolumn:name="Available",type="string",JSONPath=".status.serversAvailable",description="the number of available servers" +// +kubebuilder:printcolumn:name="In Use",type="string",JSONPath=".status.serversInUse",description="the number of servers in use" +// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp",description="The age of this resource" +// +kubebuilder:storageversion + +// ServerClass is the Schema for the serverclasses API. +type ServerClass struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ServerClassSpec `json:"spec,omitempty"` + Status ServerClassStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// ServerClassList contains a list of ServerClass. +type ServerClassList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ServerClass `json:"items"` +} + +func init() { + SchemeBuilder.Register(&ServerClass{}, &ServerClassList{}) +} diff --git a/app/sidero-controller-manager/api/v1alpha2/types.go b/app/sidero-controller-manager/api/v1alpha2/types.go new file mode 100644 index 000000000..80525d27d --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha2/types.go @@ -0,0 +1,16 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package v1alpha2 + +import apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + +// nb: we use apiextensions.JSON for the value below b/c we can't use interface{} with controller-gen. +// found this workaround here: https://github.com/kubernetes-sigs/controller-tools/pull/126#issuecomment-630769075 + +type ConfigPatches struct { + Op string `json:"op"` + Path string `json:"path"` + Value apiextensions.JSON `json:"value,omitempty"` +} diff --git a/app/sidero-controller-manager/api/v1alpha2/zz_generated.deepcopy.go b/app/sidero-controller-manager/api/v1alpha2/zz_generated.deepcopy.go new file mode 100644 index 000000000..198731e69 --- /dev/null +++ b/app/sidero-controller-manager/api/v1alpha2/zz_generated.deepcopy.go @@ -0,0 +1,771 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// Code generated by controller-gen. DO NOT EDIT. + +package v1alpha2 + +import ( + v1 "k8s.io/api/core/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/cluster-api/api/v1beta1" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Asset) DeepCopyInto(out *Asset) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Asset. +func (in *Asset) DeepCopy() *Asset { + if in == nil { + return nil + } + out := new(Asset) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AssetCondition) DeepCopyInto(out *AssetCondition) { + *out = *in + out.Asset = in.Asset +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AssetCondition. +func (in *AssetCondition) DeepCopy() *AssetCondition { + if in == nil { + return nil + } + out := new(AssetCondition) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BMC) DeepCopyInto(out *BMC) { + *out = *in + if in.UserFrom != nil { + in, out := &in.UserFrom, &out.UserFrom + *out = new(CredentialSource) + (*in).DeepCopyInto(*out) + } + if in.PassFrom != nil { + in, out := &in.PassFrom, &out.PassFrom + *out = new(CredentialSource) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BMC. +func (in *BMC) DeepCopy() *BMC { + if in == nil { + return nil + } + out := new(BMC) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ComputeInformation) DeepCopyInto(out *ComputeInformation) { + *out = *in + if in.Processors != nil { + in, out := &in.Processors, &out.Processors + *out = make([]*Processor, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(Processor) + **out = **in + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComputeInformation. +func (in *ComputeInformation) DeepCopy() *ComputeInformation { + if in == nil { + return nil + } + out := new(ComputeInformation) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConfigPatches) DeepCopyInto(out *ConfigPatches) { + *out = *in + in.Value.DeepCopyInto(&out.Value) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigPatches. +func (in *ConfigPatches) DeepCopy() *ConfigPatches { + if in == nil { + return nil + } + out := new(ConfigPatches) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CredentialSource) DeepCopyInto(out *CredentialSource) { + *out = *in + if in.SecretKeyRef != nil { + in, out := &in.SecretKeyRef, &out.SecretKeyRef + *out = new(SecretKeyRef) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CredentialSource. +func (in *CredentialSource) DeepCopy() *CredentialSource { + if in == nil { + return nil + } + out := new(CredentialSource) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Environment) DeepCopyInto(out *Environment) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Environment. +func (in *Environment) DeepCopy() *Environment { + if in == nil { + return nil + } + out := new(Environment) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Environment) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EnvironmentList) DeepCopyInto(out *EnvironmentList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Environment, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvironmentList. +func (in *EnvironmentList) DeepCopy() *EnvironmentList { + if in == nil { + return nil + } + out := new(EnvironmentList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *EnvironmentList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EnvironmentSpec) DeepCopyInto(out *EnvironmentSpec) { + *out = *in + in.Kernel.DeepCopyInto(&out.Kernel) + out.Initrd = in.Initrd +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvironmentSpec. +func (in *EnvironmentSpec) DeepCopy() *EnvironmentSpec { + if in == nil { + return nil + } + out := new(EnvironmentSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EnvironmentStatus) DeepCopyInto(out *EnvironmentStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]AssetCondition, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvironmentStatus. +func (in *EnvironmentStatus) DeepCopy() *EnvironmentStatus { + if in == nil { + return nil + } + out := new(EnvironmentStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HardwareInformation) DeepCopyInto(out *HardwareInformation) { + *out = *in + if in.System != nil { + in, out := &in.System, &out.System + *out = new(SystemInformation) + **out = **in + } + if in.Compute != nil { + in, out := &in.Compute, &out.Compute + *out = new(ComputeInformation) + (*in).DeepCopyInto(*out) + } + if in.Memory != nil { + in, out := &in.Memory, &out.Memory + *out = new(MemoryInformation) + (*in).DeepCopyInto(*out) + } + if in.Storage != nil { + in, out := &in.Storage, &out.Storage + *out = new(StorageInformation) + (*in).DeepCopyInto(*out) + } + if in.Network != nil { + in, out := &in.Network, &out.Network + *out = new(NetworkInformation) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HardwareInformation. +func (in *HardwareInformation) DeepCopy() *HardwareInformation { + if in == nil { + return nil + } + out := new(HardwareInformation) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Initrd) DeepCopyInto(out *Initrd) { + *out = *in + out.Asset = in.Asset +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Initrd. +func (in *Initrd) DeepCopy() *Initrd { + if in == nil { + return nil + } + out := new(Initrd) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Kernel) DeepCopyInto(out *Kernel) { + *out = *in + out.Asset = in.Asset + if in.Args != nil { + in, out := &in.Args, &out.Args + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Kernel. +func (in *Kernel) DeepCopy() *Kernel { + if in == nil { + return nil + } + out := new(Kernel) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ManagementAPI) DeepCopyInto(out *ManagementAPI) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagementAPI. +func (in *ManagementAPI) DeepCopy() *ManagementAPI { + if in == nil { + return nil + } + out := new(ManagementAPI) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MemoryInformation) DeepCopyInto(out *MemoryInformation) { + *out = *in + if in.Modules != nil { + in, out := &in.Modules, &out.Modules + *out = make([]*MemoryModule, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(MemoryModule) + **out = **in + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemoryInformation. +func (in *MemoryInformation) DeepCopy() *MemoryInformation { + if in == nil { + return nil + } + out := new(MemoryInformation) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MemoryModule) DeepCopyInto(out *MemoryModule) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MemoryModule. +func (in *MemoryModule) DeepCopy() *MemoryModule { + if in == nil { + return nil + } + out := new(MemoryModule) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkInformation) DeepCopyInto(out *NetworkInformation) { + *out = *in + if in.Interfaces != nil { + in, out := &in.Interfaces, &out.Interfaces + *out = make([]*NetworkInterface, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(NetworkInterface) + (*in).DeepCopyInto(*out) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkInformation. +func (in *NetworkInformation) DeepCopy() *NetworkInformation { + if in == nil { + return nil + } + out := new(NetworkInformation) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkInterface) DeepCopyInto(out *NetworkInterface) { + *out = *in + if in.Addresses != nil { + in, out := &in.Addresses, &out.Addresses + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkInterface. +func (in *NetworkInterface) DeepCopy() *NetworkInterface { + if in == nil { + return nil + } + out := new(NetworkInterface) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Processor) DeepCopyInto(out *Processor) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Processor. +func (in *Processor) DeepCopy() *Processor { + if in == nil { + return nil + } + out := new(Processor) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Qualifiers) DeepCopyInto(out *Qualifiers) { + *out = *in + if in.Hardware != nil { + in, out := &in.Hardware, &out.Hardware + *out = make([]HardwareInformation, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.LabelSelectors != nil { + in, out := &in.LabelSelectors, &out.LabelSelectors + *out = make([]map[string]string, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Qualifiers. +func (in *Qualifiers) DeepCopy() *Qualifiers { + if in == nil { + return nil + } + out := new(Qualifiers) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecretKeyRef) DeepCopyInto(out *SecretKeyRef) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretKeyRef. +func (in *SecretKeyRef) DeepCopy() *SecretKeyRef { + if in == nil { + return nil + } + out := new(SecretKeyRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Server) DeepCopyInto(out *Server) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Server. +func (in *Server) DeepCopy() *Server { + if in == nil { + return nil + } + out := new(Server) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Server) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServerClass) DeepCopyInto(out *ServerClass) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerClass. +func (in *ServerClass) DeepCopy() *ServerClass { + if in == nil { + return nil + } + out := new(ServerClass) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ServerClass) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServerClassList) DeepCopyInto(out *ServerClassList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ServerClass, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerClassList. +func (in *ServerClassList) DeepCopy() *ServerClassList { + if in == nil { + return nil + } + out := new(ServerClassList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ServerClassList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServerClassSpec) DeepCopyInto(out *ServerClassSpec) { + *out = *in + if in.EnvironmentRef != nil { + in, out := &in.EnvironmentRef, &out.EnvironmentRef + *out = new(v1.ObjectReference) + **out = **in + } + in.Qualifiers.DeepCopyInto(&out.Qualifiers) + in.Selector.DeepCopyInto(&out.Selector) + if in.ConfigPatches != nil { + in, out := &in.ConfigPatches, &out.ConfigPatches + *out = make([]ConfigPatches, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerClassSpec. +func (in *ServerClassSpec) DeepCopy() *ServerClassSpec { + if in == nil { + return nil + } + out := new(ServerClassSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServerClassStatus) DeepCopyInto(out *ServerClassStatus) { + *out = *in + if in.ServersAvailable != nil { + in, out := &in.ServersAvailable, &out.ServersAvailable + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.ServersInUse != nil { + in, out := &in.ServersInUse, &out.ServersInUse + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerClassStatus. +func (in *ServerClassStatus) DeepCopy() *ServerClassStatus { + if in == nil { + return nil + } + out := new(ServerClassStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServerList) DeepCopyInto(out *ServerList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Server, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerList. +func (in *ServerList) DeepCopy() *ServerList { + if in == nil { + return nil + } + out := new(ServerList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ServerList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServerSpec) DeepCopyInto(out *ServerSpec) { + *out = *in + if in.EnvironmentRef != nil { + in, out := &in.EnvironmentRef, &out.EnvironmentRef + *out = new(v1.ObjectReference) + **out = **in + } + if in.Hardware != nil { + in, out := &in.Hardware, &out.Hardware + *out = new(HardwareInformation) + (*in).DeepCopyInto(*out) + } + if in.BMC != nil { + in, out := &in.BMC, &out.BMC + *out = new(BMC) + (*in).DeepCopyInto(*out) + } + if in.ManagementAPI != nil { + in, out := &in.ManagementAPI, &out.ManagementAPI + *out = new(ManagementAPI) + **out = **in + } + if in.ConfigPatches != nil { + in, out := &in.ConfigPatches, &out.ConfigPatches + *out = make([]ConfigPatches, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerSpec. +func (in *ServerSpec) DeepCopy() *ServerSpec { + if in == nil { + return nil + } + out := new(ServerSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServerStatus) DeepCopyInto(out *ServerStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1beta1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Addresses != nil { + in, out := &in.Addresses, &out.Addresses + *out = make([]v1.NodeAddress, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerStatus. +func (in *ServerStatus) DeepCopy() *ServerStatus { + if in == nil { + return nil + } + out := new(ServerStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StorageDevice) DeepCopyInto(out *StorageDevice) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageDevice. +func (in *StorageDevice) DeepCopy() *StorageDevice { + if in == nil { + return nil + } + out := new(StorageDevice) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StorageInformation) DeepCopyInto(out *StorageInformation) { + *out = *in + if in.Devices != nil { + in, out := &in.Devices, &out.Devices + *out = make([]*StorageDevice, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(StorageDevice) + **out = **in + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StorageInformation. +func (in *StorageInformation) DeepCopy() *StorageInformation { + if in == nil { + return nil + } + out := new(StorageInformation) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SystemInformation) DeepCopyInto(out *SystemInformation) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SystemInformation. +func (in *SystemInformation) DeepCopy() *SystemInformation { + if in == nil { + return nil + } + out := new(SystemInformation) + in.DeepCopyInto(out) + return out +} diff --git a/app/sidero-controller-manager/cmd/agent/main.go b/app/sidero-controller-manager/cmd/agent/main.go index 55ac3bd9b..f734a8acb 100644 --- a/app/sidero-controller-manager/cmd/agent/main.go +++ b/app/sidero-controller-manager/cmd/agent/main.go @@ -19,8 +19,8 @@ import ( "github.com/talos-systems/go-blockdevice/blockdevice" "github.com/talos-systems/go-blockdevice/blockdevice/util/disk" - debug "github.com/talos-systems/go-debug" - kmsg "github.com/talos-systems/go-kmsg" + "github.com/talos-systems/go-debug" + "github.com/talos-systems/go-kmsg" "github.com/talos-systems/go-procfs/procfs" "github.com/talos-systems/go-retry/retry" "github.com/talos-systems/go-smbios/smbios" @@ -30,7 +30,7 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" - "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + metal "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" "github.com/talos-systems/sidero/app/sidero-controller-manager/internal/api" "github.com/talos-systems/sidero/app/sidero-controller-manager/internal/power/ipmi" "github.com/talos-systems/sidero/app/sidero-controller-manager/pkg/constants" @@ -94,25 +94,21 @@ func setup() error { } func create(ctx context.Context, client api.AgentClient, s *smbios.SMBIOS) (*api.CreateServerResponse, error) { - uuid, err := s.SystemInformation().UUID() + disks, err := disk.List() if err != nil { - return nil, err + log.Printf("encountered error fetching disks: %q", err) + disks = make([]*disk.Disk, 0) + } + + interfaces, err := net.Interfaces() + if err != nil { + log.Printf("encountered error fetching network interfaces: %q", err) + interfaces = make([]net.Interface, 0) } req := &api.CreateServerRequest{ - SystemInformation: &api.SystemInformation{ - Uuid: uuid.String(), - Manufacturer: s.SystemInformation().Manufacturer(), - ProductName: s.SystemInformation().ProductName(), - Version: s.SystemInformation().Version(), - SerialNumber: s.SystemInformation().SerialNumber(), - SkuNumber: s.SystemInformation().SKUNumber(), - Family: s.SystemInformation().Family(), - }, - Cpu: &api.CPU{ - Manufacturer: s.ProcessorInformation().ProcessorManufacturer(), - Version: s.ProcessorInformation().ProcessorVersion(), - }, + Hardware: MapHardwareInformation(s, disks, interfaces), + Hostname: "", } hostname, err := os.Hostname() @@ -140,16 +136,11 @@ func create(ctx context.Context, client api.AgentClient, s *smbios.SMBIOS) (*api } func wipe(ctx context.Context, client api.AgentClient, s *smbios.SMBIOS) error { - uuid, err := s.SystemInformation().UUID() - if err != nil { - return err - } - return retry.Constant(5*time.Minute, retry.WithUnits(30*time.Second), retry.WithErrorLogging(true)).Retry(func() error { ctx, cancel := context.WithTimeout(ctx, 30*time.Second) defer cancel() - _, err = client.MarkServerAsWiped(ctx, &api.MarkServerAsWipedRequest{Uuid: uuid.String()}) + _, err := client.MarkServerAsWiped(ctx, &api.MarkServerAsWipedRequest{Uuid: s.SystemInformation.UUID}) if err != nil { return retry.ExpectedError(err) } @@ -159,11 +150,6 @@ func wipe(ctx context.Context, client api.AgentClient, s *smbios.SMBIOS) error { } func reconcileIPs(ctx context.Context, client api.AgentClient, s *smbios.SMBIOS, ips []net.IP) error { - uuid, err := s.SystemInformation().UUID() - if err != nil { - return err - } - addresses := make([]*api.Address, len(ips)) for i := range addresses { addresses[i] = &api.Address{ @@ -176,8 +162,8 @@ func reconcileIPs(ctx context.Context, client api.AgentClient, s *smbios.SMBIOS, ctx, cancel := context.WithTimeout(ctx, 30*time.Second) defer cancel() - _, err = client.ReconcileServerAddresses(ctx, &api.ReconcileServerAddressesRequest{ - Uuid: uuid.String(), + _, err := client.ReconcileServerAddresses(ctx, &api.ReconcileServerAddressesRequest{ + Uuid: s.SystemInformation.UUID, Address: addresses, }) if err != nil { @@ -281,11 +267,6 @@ func mainFunc() error { shutdown(err) } - uuid, err := s.SystemInformation().UUID() - if err != nil { - shutdown(err) - } - var ( eg errgroup.Group wg sync.WaitGroup @@ -305,7 +286,7 @@ func mainFunc() error { for { callCtx, cancel := context.WithTimeout(ctx, heartbeatInterval) - if _, err := client.Heartbeat(callCtx, &api.HeartbeatRequest{Uuid: uuid.String()}); err != nil { + if _, err := client.Heartbeat(callCtx, &api.HeartbeatRequest{Uuid: s.SystemInformation.UUID}); err != nil { log.Printf("Failed to send wipe heartbeat %s", err) } @@ -396,15 +377,10 @@ func main() { } func attemptBMCIP(ctx context.Context, client api.AgentClient, s *smbios.SMBIOS) error { - uuid, err := s.SystemInformation().UUID() - if err != nil { - return err - } - bmcInfo := &api.BMCInfo{} // Create "open" client - bmcSpec := v1alpha1.BMC{ + bmcSpec := metal.BMC{ Interface: "open", } @@ -442,7 +418,7 @@ func attemptBMCIP(ctx context.Context, client api.AgentClient, s *smbios.SMBIOS) _, err = client.UpdateBMCInfo( ctx, &api.UpdateBMCInfoRequest{ - Uuid: uuid.String(), + Uuid: s.SystemInformation.UUID, BmcInfo: bmcInfo, }, ) @@ -458,15 +434,10 @@ func attemptBMCIP(ctx context.Context, client api.AgentClient, s *smbios.SMBIOS) } func attemptBMCUserSetup(ctx context.Context, client api.AgentClient, s *smbios.SMBIOS) error { - uuid, err := s.SystemInformation().UUID() - if err != nil { - return err - } - bmcInfo := &api.BMCInfo{} // Create "open" client - bmcSpec := v1alpha1.BMC{ + bmcSpec := metal.BMC{ Interface: "open", } @@ -575,7 +546,7 @@ func attemptBMCUserSetup(ctx context.Context, client api.AgentClient, s *smbios. _, err = client.UpdateBMCInfo( ctx, &api.UpdateBMCInfoRequest{ - Uuid: uuid.String(), + Uuid: s.SystemInformation.UUID, BmcInfo: bmcInfo, }, ) @@ -609,3 +580,153 @@ func genPass16() (string, error) { return string(b), nil } + +func MapHardwareInformation(s *smbios.SMBIOS, disks []*disk.Disk, interfaces []net.Interface) *api.HardwareInformation { + if s != nil { + return &api.HardwareInformation{ + System: MapSystemInformation(s), + Compute: MapComputeInformation(s), + Memory: MapMemoryInformation(s), + Storage: MapStorageInformation(disks), + Network: MapNetworkInformation(interfaces), + } + } + + return &api.HardwareInformation{ + Storage: MapStorageInformation(disks), + } +} + +func MapSystemInformation(s *smbios.SMBIOS) *api.SystemInformation { + return &api.SystemInformation{ + Manufacturer: s.SystemInformation.Manufacturer, + ProductName: s.SystemInformation.ProductName, + SerialNumber: s.SystemInformation.SerialNumber, + Uuid: s.SystemInformation.UUID, + SkuNumber: s.SystemInformation.SKUNumber, + Family: s.SystemInformation.Family, + } +} + +func MapComputeInformation(s *smbios.SMBIOS) *api.ComputeInformation { + var totalCoreCount = 0 + var totalThreadCount = 0 + var processors []*api.Processor + for _, v := range s.ProcessorInformation { + if v.Status.SocketPopulated() { + totalCoreCount += int(v.CoreCount) + totalThreadCount += int(v.ThreadCount) + var processor = &api.Processor{ + Manufacturer: v.ProcessorManufacturer, + ProductName: v.ProcessorVersion, + SerialNumber: v.SerialNumber, + Speed: uint32(v.CurrentSpeed), + CoreCount: uint32(v.CoreCount), + ThreadCount: uint32(v.ThreadCount), + } + processors = append(processors, processor) + } + } + return &api.ComputeInformation{ + TotalCoreCount: uint32(totalCoreCount), + TotalThreadCount: uint32(totalThreadCount), + ProcessorCount: uint32(len(processors)), + Processors: processors, + } +} + +func MapMemoryInformation(s *smbios.SMBIOS) *api.MemoryInformation { + var totalSize = 0 + var modules []*api.MemoryModule + for _, v := range s.MemoryDevices { + if v.Size != 0 && v.Size != 0xFFFF { + var size uint32 + if v.Size == 0x7FFF { + totalSize += int(v.ExtendedSize) + size = uint32(v.ExtendedSize) + } else { + totalSize += v.Size.Megabytes() + size = uint32(v.Size) + } + var memoryModule = &api.MemoryModule{ + Manufacturer: v.Manufacturer, + ProductName: v.PartNumber, + SerialNumber: v.SerialNumber, + Type: v.MemoryType.String(), + Size: size, + Speed: uint32(v.Speed), + } + modules = append(modules, memoryModule) + } + } + return &api.MemoryInformation{ + TotalSize: uint32(totalSize), + ModuleCount: uint32(len(modules)), + Modules: modules, + } +} + +func MapStorageInformation(s []*disk.Disk) *api.StorageInformation { + var totalSize = uint64(0) + var devices []*api.StorageDevice + for _, v := range s { + totalSize += v.Size + var storageType api.StorageType + switch v.Type.String() { + case "ssd": + storageType = api.StorageType_SSD + case "hdd": + storageType = api.StorageType_HDD + case "nvme": + storageType = api.StorageType_NVMe + case "sd": + storageType = api.StorageType_SD + default: + storageType = api.StorageType_Unknown + } + var storageDevice = &api.StorageDevice{ + Model: v.Model, + Serial: v.Serial, + Type: storageType, + Size: v.Size, + Name: v.Name, + DeviceName: v.DeviceName, + Uuid: v.UUID, + Wwid: v.WWID, + } + devices = append(devices, storageDevice) + } + return &api.StorageInformation{ + TotalSize: totalSize, + DeviceCount: uint32(len(devices)), + Devices: devices, + } +} + +func MapNetworkInformation(s []net.Interface) *api.NetworkInformation { + var interfaces []*api.NetworkInterface + for _, v := range s { + var addrs, err = v.Addrs() + if err != nil { + log.Printf("encountered error fetching addresses of network interface %q: %q", v.Name, err) + addrs = make([]net.Addr, 0) + } + var addresses []string + for _, a := range addrs { + addresses = append(addresses, a.String()) + } + var networkInterface = &api.NetworkInterface{ + Index: uint32(v.Index), + Name: v.Name, + Flags: v.Flags.String(), + Mtu: uint32(v.MTU), + Mac: v.HardwareAddr.String(), + Addresses: addresses, + } + interfaces = append(interfaces, networkInterface) + } + return &api.NetworkInformation{ + InterfaceCount: uint32(len(interfaces)), + Interfaces: interfaces, + } +} diff --git a/app/sidero-controller-manager/cmd/agent/main_test.go b/app/sidero-controller-manager/cmd/agent/main_test.go new file mode 100644 index 000000000..293ec2cdd --- /dev/null +++ b/app/sidero-controller-manager/cmd/agent/main_test.go @@ -0,0 +1,14 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +//nolint:scopelint +package main + +import ( + "testing" +) + +func Test_MapHardwareInformation_DoesNotPanic(t *testing.T) { + MapHardwareInformation(nil, nil, nil) +} diff --git a/app/sidero-controller-manager/config/certmanager/certificate.yaml b/app/sidero-controller-manager/config/certmanager/certificate.yaml index fac5aa1bb..8b3cef909 100644 --- a/app/sidero-controller-manager/config/certmanager/certificate.yaml +++ b/app/sidero-controller-manager/config/certmanager/certificate.yaml @@ -1,10 +1,9 @@ # The following manifests contain a self-signed issuer CR and a certificate CR. # More document can be found at https://docs.cert-manager.io -# WARNING: Targets CertManager 0.11 check https://docs.cert-manager.io/en/latest/tasks/upgrading/index.html for breaking changes apiVersion: cert-manager.io/v1 kind: Issuer metadata: - name: selfsigned-issuer + name: sidero-selfsigned-issuer namespace: system spec: selfSigned: {} @@ -12,14 +11,14 @@ spec: apiVersion: cert-manager.io/v1 kind: Certificate metadata: - name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml + name: sidero-serving-cert # this name should match the one appeared in kustomizeconfig.yaml namespace: system spec: - # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize + # $(SIDERO_WEBHOOK_SERVICE_NAME) and $(SIDERO_WEBHOOK_SERVICE_NAMESPACE) will be substituted by kustomize dnsNames: - - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc - - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local + - $(SIDERO_WEBHOOK_SERVICE_NAME).$(SIDERO_WEBHOOK_SERVICE_NAMESPACE).svc + - $(SIDERO_WEBHOOK_SERVICE_NAME).$(SIDERO_WEBHOOK_SERVICE_NAMESPACE).svc.cluster.local issuerRef: kind: Issuer - name: selfsigned-issuer - secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize + name: sidero-selfsigned-issuer + secretName: $(SIDERO_WEBHOOK_SERVICE_NAME)-cert diff --git a/app/sidero-controller-manager/config/certmanager/kustomization.yaml b/app/sidero-controller-manager/config/certmanager/kustomization.yaml index bebea5a59..34e7e5b12 100644 --- a/app/sidero-controller-manager/config/certmanager/kustomization.yaml +++ b/app/sidero-controller-manager/config/certmanager/kustomization.yaml @@ -1,5 +1,4 @@ resources: -- certificate.yaml - + - certificate.yaml configurations: -- kustomizeconfig.yaml + - kustomizeconfig.yaml diff --git a/app/sidero-controller-manager/config/certmanager/kustomizeconfig.yaml b/app/sidero-controller-manager/config/certmanager/kustomizeconfig.yaml index 90d7c313c..c6a6c0f1e 100644 --- a/app/sidero-controller-manager/config/certmanager/kustomizeconfig.yaml +++ b/app/sidero-controller-manager/config/certmanager/kustomizeconfig.yaml @@ -1,16 +1,19 @@ -# This configuration is for teaching kustomize how to update name ref and var substitution +# This configuration is for teaching kustomize how to update name ref and var substitution nameReference: -- kind: Issuer - group: cert-manager.io - fieldSpecs: - - kind: Certificate + - kind: Issuer group: cert-manager.io - path: spec/issuerRef/name + fieldSpecs: + - kind: Certificate + group: cert-manager.io + path: spec/issuerRef/name varReference: -- kind: Certificate - group: cert-manager.io - path: spec/commonName -- kind: Certificate - group: cert-manager.io - path: spec/dnsNames + - kind: Certificate + group: cert-manager.io + path: spec/commonName + - kind: Certificate + group: cert-manager.io + path: spec/dnsNames + - kind: Certificate + group: cert-manager.io + path: spec/secretName diff --git a/app/sidero-controller-manager/config/crd/bases/metal.sidero.dev_environments.yaml b/app/sidero-controller-manager/config/crd/bases/metal.sidero.dev_environments.yaml index 654d12257..90ffc6066 100644 --- a/app/sidero-controller-manager/config/crd/bases/metal.sidero.dev_environments.yaml +++ b/app/sidero-controller-manager/config/crd/bases/metal.sidero.dev_environments.yaml @@ -94,6 +94,87 @@ spec: type: object type: object served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: the kernel for the environment + jsonPath: .spec.kernel.url + name: Kernel + type: string + - description: the initrd for the environment + jsonPath: .spec.initrd.url + name: Initrd + type: string + - description: indicates the readiness of the environment + jsonPath: .status.conditions[?(@.type=="Ready")].status + name: Ready + type: string + - description: The age of this resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: Environment is the Schema for the environments API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: EnvironmentSpec defines the desired state of Environment. + properties: + initrd: + properties: + sha512: + type: string + url: + type: string + type: object + kernel: + properties: + args: + items: + type: string + type: array + sha512: + type: string + url: + type: string + type: object + type: object + status: + description: EnvironmentStatus defines the observed state of Environment. + properties: + conditions: + items: + properties: + sha512: + type: string + status: + type: string + type: + type: string + url: + type: string + required: + - status + - type + type: object + type: array + type: object + type: object + served: true storage: true subresources: status: {} diff --git a/app/sidero-controller-manager/config/crd/bases/metal.sidero.dev_serverclasses.yaml b/app/sidero-controller-manager/config/crd/bases/metal.sidero.dev_serverclasses.yaml index ba4361a91..38e1ccc05 100644 --- a/app/sidero-controller-manager/config/crd/bases/metal.sidero.dev_serverclasses.yaml +++ b/app/sidero-controller-manager/config/crd/bases/metal.sidero.dev_serverclasses.yaml @@ -211,6 +211,321 @@ spec: type: object type: object served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: the number of available servers + jsonPath: .status.serversAvailable + name: Available + type: string + - description: the number of servers in use + jsonPath: .status.serversInUse + name: In Use + type: string + - description: The age of this resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: ServerClass is the Schema for the serverclasses API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ServerClassSpec defines the desired state of ServerClass. + properties: + bootFromDiskMethod: + description: "BootFromDiskMethod specifies the method to exit iPXE + to force boot from disk. \n If not set, controller default is used. + Valid values: ipxe-exit, http-404, ipxe-sanboot." + type: string + configPatches: + description: Set of config patches to apply to the machine configuration + to the servers provisioned via this server class. + items: + properties: + op: + type: string + path: + type: string + value: + x-kubernetes-preserve-unknown-fields: true + required: + - op + - path + type: object + type: array + environmentRef: + description: Reference to the environment which should be used to + provision the servers via this server class. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + qualifiers: + description: "Qualifiers to match on the server spec. \n If qualifiers + are empty, they match all servers. Server should match both qualifiers + and selector conditions to be included into the server class." + properties: + hardware: + items: + properties: + compute: + properties: + processorCount: + format: int32 + type: integer + processors: + items: + properties: + coreCount: + format: int32 + type: integer + manufacturer: + type: string + productName: + type: string + serialNumber: + type: string + speed: + description: Speed is in megahertz (Mhz) + format: int32 + type: integer + threadCount: + format: int32 + type: integer + type: object + type: array + totalCoreCount: + format: int32 + type: integer + totalThreadCount: + format: int32 + type: integer + type: object + memory: + properties: + moduleCount: + format: int32 + type: integer + modules: + items: + properties: + manufacturer: + type: string + productName: + type: string + serialNumber: + type: string + size: + description: Size is in megabytes (MB) + format: int32 + type: integer + speed: + description: Speed is in megatransfers per second + (MT/S) + format: int32 + type: integer + type: + type: string + type: object + type: array + totalSize: + type: string + type: object + network: + properties: + interfaceCount: + format: int32 + type: integer + interfaces: + items: + properties: + addresses: + items: + type: string + type: array + flags: + type: string + index: + format: int32 + type: integer + mac: + type: string + mtu: + format: int32 + type: integer + name: + type: string + type: object + type: array + type: object + storage: + properties: + deviceCount: + format: int32 + type: integer + devices: + items: + properties: + deviceName: + type: string + name: + type: string + productName: + type: string + serialNumber: + type: string + size: + description: Size is in bytes + format: int64 + type: integer + type: + type: string + uuid: + type: string + wwid: + type: string + type: object + type: array + totalSize: + type: string + type: object + system: + properties: + family: + type: string + manufacturer: + type: string + productName: + type: string + serialNumber: + type: string + skuNumber: + type: string + uuid: + type: string + version: + type: string + type: object + type: object + type: array + labelSelectors: + items: + additionalProperties: + type: string + type: object + type: array + type: object + selector: + description: Label selector to filter the matching servers based on + labels. A label selector is a label query over a set of resources. + The result of matchLabels and matchExpressions are ANDed. An empty + label selector matches all objects. A null label selector matches + no objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + type: object + status: + description: ServerClassStatus defines the observed state of ServerClass. + properties: + serversAvailable: + items: + type: string + type: array + serversInUse: + items: + type: string + type: array + required: + - serversAvailable + - serversInUse + type: object + type: object + served: true storage: true subresources: status: {} diff --git a/app/sidero-controller-manager/config/crd/bases/metal.sidero.dev_servers.yaml b/app/sidero-controller-manager/config/crd/bases/metal.sidero.dev_servers.yaml index 4591ba63c..9008186b8 100644 --- a/app/sidero-controller-manager/config/crd/bases/metal.sidero.dev_servers.yaml +++ b/app/sidero-controller-manager/config/crd/bases/metal.sidero.dev_servers.yaml @@ -341,6 +341,452 @@ spec: type: object type: object served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: server hostname + jsonPath: .spec.hostname + name: Hostname + type: string + - description: BMC IP + jsonPath: .spec.bmc.endpoint + name: BMC IP + priority: 1 + type: string + - description: indicates if the server is accepted + jsonPath: .spec.accepted + name: Accepted + type: boolean + - description: indicates if the server is cordoned + jsonPath: .spec.cordoned + name: Cordoned + type: boolean + - description: indicates that the server has been allocated + jsonPath: .status.inUse + name: Allocated + type: boolean + - description: indicates if the server is clean or not + jsonPath: .status.isClean + name: Clean + type: boolean + - description: display the current power status + jsonPath: .status.power + name: Power + type: string + - description: The age of this resource + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha2 + schema: + openAPIV3Schema: + description: Server is the Schema for the servers API. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ServerSpec defines the desired state of Server. + properties: + accepted: + type: boolean + bmc: + description: BMC defines data about how to talk to the node via ipmitool. + properties: + endpoint: + description: BMC endpoint. + type: string + interface: + description: BMC Interface Type. Defaults to lanplus. + type: string + pass: + description: BMC password value. + type: string + passFrom: + description: Source for the password value. Cannot be used if + Pass is not empty. + properties: + secretKeyRef: + description: SecretKeyRef defines a ref to a given key within + a secret. + properties: + key: + description: Key to select + type: string + name: + type: string + namespace: + description: 'Namespace and name of credential secret + nb: can''t use namespacedname here b/c it doesn''t have + json tags in the struct :(' + type: string + required: + - key + - name + - namespace + type: object + type: object + port: + description: BMC port. Defaults to 623. + format: int32 + type: integer + user: + description: BMC user value. + type: string + userFrom: + description: Source for the user value. Cannot be used if User + is not empty. + properties: + secretKeyRef: + description: SecretKeyRef defines a ref to a given key within + a secret. + properties: + key: + description: Key to select + type: string + name: + type: string + namespace: + description: 'Namespace and name of credential secret + nb: can''t use namespacedname here b/c it doesn''t have + json tags in the struct :(' + type: string + required: + - key + - name + - namespace + type: object + type: object + required: + - endpoint + type: object + bootFromDiskMethod: + description: "BootFromDiskMethod specifies the method to exit iPXE + to force boot from disk. \n If not set, controller default is used. + Valid values: ipxe-exit, http-404, ipxe-sanboot." + type: string + configPatches: + items: + properties: + op: + type: string + path: + type: string + value: + x-kubernetes-preserve-unknown-fields: true + required: + - op + - path + type: object + type: array + cordoned: + type: boolean + environmentRef: + description: 'ObjectReference contains enough information to let you + inspect or modify the referred object. --- New uses of this type + are discouraged because of difficulty describing its usage when + embedded in APIs. 1. Ignored fields. It includes many fields which + are not generally honored. For instance, ResourceVersion and FieldPath + are both very rarely valid in actual usage. 2. Invalid usage help. It + is impossible to add specific help for individual usage. In most + embedded usages, there are particular restrictions like, "must + refer only to types A and B" or "UID not honored" or "name must + be restricted". Those cannot be well described when embedded. 3. + Inconsistent validation. Because the usages are different, the + validation rules are different by usage, which makes it hard for + users to predict what will happen. 4. The fields are both imprecise + and overly precise. Kind is not a precise mapping to a URL. This + can produce ambiguity during interpretation and require a REST + mapping. In most cases, the dependency is on the group,resource + tuple and the version of the actual struct is irrelevant. 5. + We cannot easily change it. Because this type is embedded in many + locations, updates to this type will affect numerous schemas. Don''t + make new APIs embed an underspecified API type they do not control. + Instead of using this type, create a locally provided and used type + that is well-focused on your reference. For example, ServiceReferences + for admission registration: https://github.com/kubernetes/api/blob/release-1.17/admissionregistration/v1/types.go#L533 + .' + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: 'If referring to a piece of an object instead of + an entire object, this string should contain a valid JSON/Go + field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within + a pod, this would take on a value like: "spec.containers{name}" + (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" + (container with index 2 in this pod). This syntax is chosen + only to have some well-defined way of referencing a part of + an object. TODO: this design is not final and this field is + subject to change in the future.' + type: string + kind: + description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + namespace: + description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' + type: string + resourceVersion: + description: 'Specific resourceVersion to which this reference + is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' + type: string + uid: + description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' + type: string + type: object + hardware: + properties: + compute: + properties: + processorCount: + format: int32 + type: integer + processors: + items: + properties: + coreCount: + format: int32 + type: integer + manufacturer: + type: string + productName: + type: string + serialNumber: + type: string + speed: + description: Speed is in megahertz (Mhz) + format: int32 + type: integer + threadCount: + format: int32 + type: integer + type: object + type: array + totalCoreCount: + format: int32 + type: integer + totalThreadCount: + format: int32 + type: integer + type: object + memory: + properties: + moduleCount: + format: int32 + type: integer + modules: + items: + properties: + manufacturer: + type: string + productName: + type: string + serialNumber: + type: string + size: + description: Size is in megabytes (MB) + format: int32 + type: integer + speed: + description: Speed is in megatransfers per second (MT/S) + format: int32 + type: integer + type: + type: string + type: object + type: array + totalSize: + type: string + type: object + network: + properties: + interfaceCount: + format: int32 + type: integer + interfaces: + items: + properties: + addresses: + items: + type: string + type: array + flags: + type: string + index: + format: int32 + type: integer + mac: + type: string + mtu: + format: int32 + type: integer + name: + type: string + type: object + type: array + type: object + storage: + properties: + deviceCount: + format: int32 + type: integer + devices: + items: + properties: + deviceName: + type: string + name: + type: string + productName: + type: string + serialNumber: + type: string + size: + description: Size is in bytes + format: int64 + type: integer + type: + type: string + uuid: + type: string + wwid: + type: string + type: object + type: array + totalSize: + type: string + type: object + system: + properties: + family: + type: string + manufacturer: + type: string + productName: + type: string + serialNumber: + type: string + skuNumber: + type: string + uuid: + type: string + version: + type: string + type: object + type: object + hostname: + type: string + managementApi: + description: ManagementAPI defines data about how to talk to the node + via simple HTTP API. + properties: + endpoint: + type: string + required: + - endpoint + type: object + pxeBootAlways: + type: boolean + required: + - accepted + type: object + status: + description: ServerStatus defines the observed state of Server. + properties: + addresses: + description: Addresses lists discovered node IPs. + items: + description: NodeAddress contains information for the node's address. + properties: + address: + description: The node address. + type: string + type: + description: Node address type, one of Hostname, ExternalIP + or InternalIP. + type: string + required: + - address + - type + type: object + type: array + conditions: + description: Conditions defines current service state of the Server. + items: + description: Condition defines an observation of a Cluster API resource + operational state. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. This should be when the underlying condition changed. + If that is not known, then using the time when the API field + changed is acceptable. + format: date-time + type: string + message: + description: A human readable message indicating details about + the transition. This field may be empty. + type: string + reason: + description: The reason for the condition's last transition + in CamelCase. The specific API may choose whether or not this + field is considered a guaranteed API. This field may not be + empty. + type: string + severity: + description: Severity provides an explicit classification of + Reason code, so the users or machines can immediately understand + the current situation and act accordingly. The Severity field + MUST be set only when Status=False. + type: string + status: + description: Status of the condition, one of True, False, Unknown. + type: string + type: + description: Type of condition in CamelCase or in foo.example.com/CamelCase. + Many .condition.type values are consistent across resources + like Available, but because arbitrary conditions can be useful + (see .node.status.conditions), the ability to deconflict is + important. + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + inUse: + description: InUse is true when server is assigned to some MetalMachine. + type: boolean + isClean: + description: IsClean is true when server disks are wiped. + type: boolean + power: + description: 'Power is the current power state of the server: "on", + "off" or "unknown".' + type: string + ready: + description: Ready is true when server is accepted and in use. + type: boolean + type: object + type: object + served: true storage: true subresources: status: {} diff --git a/app/sidero-controller-manager/config/crd/kustomization.yaml b/app/sidero-controller-manager/config/crd/kustomization.yaml index eb4523e0f..02160e519 100644 --- a/app/sidero-controller-manager/config/crd/kustomization.yaml +++ b/app/sidero-controller-manager/config/crd/kustomization.yaml @@ -2,29 +2,29 @@ # since it depends on service name and namespace that are out of this kustomize package. # It should be run by config/default resources: -- bases/metal.sidero.dev_environments.yaml -- bases/metal.sidero.dev_servers.yaml -- bases/metal.sidero.dev_serverclasses.yaml + - bases/metal.sidero.dev_environments.yaml + - bases/metal.sidero.dev_servers.yaml + - bases/metal.sidero.dev_serverclasses.yaml # +kubebuilder:scaffold:crdkustomizeresource commonLabels: clusterctl.cluster.x-k8s.io/move: "" patchesStrategicMerge: -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. -# patches here are for enabling the conversion webhook for each CRD -#- patches/webhook_in_environments.yaml -#- patches/webhook_in_servers.yaml -#- patches/webhook_in_serverclasses.yaml -# +kubebuilder:scaffold:crdkustomizewebhookpatch + # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. + # patches here are for enabling the conversion webhook for each CRD + - patches/webhook_in_environments.yaml + - patches/webhook_in_servers.yaml + - patches/webhook_in_serverclasses.yaml + # +kubebuilder:scaffold:crdkustomizewebhookpatch -# [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix. -# patches here are for enabling the CA injection for each CRD -#- patches/cainjection_in_environments.yaml -#- patches/cainjection_in_servers.yaml -#- patches/cainjection_in_serverclasses.yaml + # [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix. + # patches here are for enabling the CA injection for each CRD + - patches/cainjection_in_environments.yaml + - patches/cainjection_in_servers.yaml + - patches/cainjection_in_serverclasses.yaml # +kubebuilder:scaffold:crdkustomizecainjectionpatch # the following config is for teaching kustomize how to do kustomization for CRDs. configurations: -- kustomizeconfig.yaml + - kustomizeconfig.yaml diff --git a/app/sidero-controller-manager/config/crd/kustomizeconfig.yaml b/app/sidero-controller-manager/config/crd/kustomizeconfig.yaml index 6f83d9a94..e3fd575d6 100644 --- a/app/sidero-controller-manager/config/crd/kustomizeconfig.yaml +++ b/app/sidero-controller-manager/config/crd/kustomizeconfig.yaml @@ -1,17 +1,17 @@ # This file is for teaching kustomize how to substitute name and namespace reference in CRD nameReference: -- kind: Service - version: v1 - fieldSpecs: - - kind: CustomResourceDefinition - group: apiextensions.k8s.io - path: spec/conversion/webhookClientConfig/service/name + - kind: Service + version: v1 + fieldSpecs: + - kind: CustomResourceDefinition + group: apiextensions.k8s.io + path: spec/conversion/webhook/clientConfig/service/name namespace: -- kind: CustomResourceDefinition - group: apiextensions.k8s.io - path: spec/conversion/webhookClientConfig/service/namespace - create: false + - kind: CustomResourceDefinition + group: apiextensions.k8s.io + path: spec/conversion/webhook/clientConfig/service/namespace + create: false varReference: -- path: metadata/annotations + - path: metadata/annotations diff --git a/app/sidero-controller-manager/config/crd/patches/cainjection_in_environments.yaml b/app/sidero-controller-manager/config/crd/patches/cainjection_in_environments.yaml index 91fc9ab43..e1a4b2740 100644 --- a/app/sidero-controller-manager/config/crd/patches/cainjection_in_environments.yaml +++ b/app/sidero-controller-manager/config/crd/patches/cainjection_in_environments.yaml @@ -1,8 +1,8 @@ # The following patch adds a directive for certmanager to inject CA into the CRD # CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + cert-manager.io/inject-ca-from: $(SIDERO_CERTIFICATE_NAMESPACE)/$(SIDERO_CERTIFICATE_NAME) name: environments.metal.sidero.dev diff --git a/app/sidero-controller-manager/config/crd/patches/cainjection_in_serverclasses.yaml b/app/sidero-controller-manager/config/crd/patches/cainjection_in_serverclasses.yaml index 6dc47f854..acfef6adb 100644 --- a/app/sidero-controller-manager/config/crd/patches/cainjection_in_serverclasses.yaml +++ b/app/sidero-controller-manager/config/crd/patches/cainjection_in_serverclasses.yaml @@ -1,8 +1,8 @@ # The following patch adds a directive for certmanager to inject CA into the CRD # CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + cert-manager.io/inject-ca-from: $(SIDERO_CERTIFICATE_NAMESPACE)/$(SIDERO_CERTIFICATE_NAME) name: serverclasses.metal.sidero.dev diff --git a/app/sidero-controller-manager/config/crd/patches/cainjection_in_servers.yaml b/app/sidero-controller-manager/config/crd/patches/cainjection_in_servers.yaml index d5d9a02dd..e432aa501 100644 --- a/app/sidero-controller-manager/config/crd/patches/cainjection_in_servers.yaml +++ b/app/sidero-controller-manager/config/crd/patches/cainjection_in_servers.yaml @@ -1,8 +1,8 @@ # The following patch adds a directive for certmanager to inject CA into the CRD # CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + cert-manager.io/inject-ca-from: $(SIDERO_CERTIFICATE_NAMESPACE)/$(SIDERO_CERTIFICATE_NAME) name: servers.metal.sidero.dev diff --git a/app/sidero-controller-manager/config/crd/patches/webhook_in_environments.yaml b/app/sidero-controller-manager/config/crd/patches/webhook_in_environments.yaml index 3c264e887..b66be96c2 100644 --- a/app/sidero-controller-manager/config/crd/patches/webhook_in_environments.yaml +++ b/app/sidero-controller-manager/config/crd/patches/webhook_in_environments.yaml @@ -1,17 +1,19 @@ # The following patch enables conversion webhook for CRD # CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: environments.metal.sidero.dev spec: conversion: strategy: Webhook - webhookClientConfig: - # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, - # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) - caBundle: Cg== - service: - namespace: system - name: webhook-service - path: /convert + webhook: + conversionReviewVersions: ["v1", "v1beta1"] + clientConfig: + # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, + # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) + caBundle: Cg== + service: + namespace: system + name: webhook-service + path: /convert diff --git a/app/sidero-controller-manager/config/crd/patches/webhook_in_serverclasses.yaml b/app/sidero-controller-manager/config/crd/patches/webhook_in_serverclasses.yaml index f784b1027..73196078f 100644 --- a/app/sidero-controller-manager/config/crd/patches/webhook_in_serverclasses.yaml +++ b/app/sidero-controller-manager/config/crd/patches/webhook_in_serverclasses.yaml @@ -1,17 +1,19 @@ # The following patch enables conversion webhook for CRD # CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: serverclasses.metal.sidero.dev spec: conversion: strategy: Webhook - webhookClientConfig: - # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, - # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) - caBundle: Cg== - service: - namespace: system - name: webhook-service - path: /convert + webhook: + conversionReviewVersions: ["v1", "v1beta1"] + clientConfig: + # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, + # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) + caBundle: Cg== + service: + namespace: system + name: webhook-service + path: /convert diff --git a/app/sidero-controller-manager/config/crd/patches/webhook_in_servers.yaml b/app/sidero-controller-manager/config/crd/patches/webhook_in_servers.yaml index 404ad5977..99a9aa48e 100644 --- a/app/sidero-controller-manager/config/crd/patches/webhook_in_servers.yaml +++ b/app/sidero-controller-manager/config/crd/patches/webhook_in_servers.yaml @@ -1,17 +1,19 @@ # The following patch enables conversion webhook for CRD # CRD conversion requires k8s 1.13 or later. -apiVersion: apiextensions.k8s.io/v1beta1 +apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: servers.metal.sidero.dev spec: conversion: strategy: Webhook - webhookClientConfig: - # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, - # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) - caBundle: Cg== - service: - namespace: system - name: webhook-service - path: /convert + webhook: + conversionReviewVersions: ["v1", "v1beta1"] + clientConfig: + # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, + # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) + caBundle: Cg== + service: + namespace: system + name: webhook-service + path: /convert diff --git a/app/sidero-controller-manager/config/default/kustomization.yaml b/app/sidero-controller-manager/config/default/kustomization.yaml new file mode 100644 index 000000000..1124211f7 --- /dev/null +++ b/app/sidero-controller-manager/config/default/kustomization.yaml @@ -0,0 +1,65 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: sidero-system + +namePrefix: sidero- + +# Labels to add to all resources and selectors. +commonLabels: + cluster.x-k8s.io/provider: "infrastructure-sidero" + +bases: + - ../crd + - ../certmanager + - ../webhook + - ../rbac + - ../manager +# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. +#- ../prometheus + +patchesStrategicMerge: + - manager_webhook_patch.yaml +# - webhookcainjection_patch.yaml + + # Protect the /metrics endpoint by putting it behind auth. + # Only one of manager_auth_proxy_patch.yaml and + # manager_prometheus_metrics_patch.yaml should be enabled. + #- manager_auth_proxy_patch.yaml + # If you want your controller-manager to expose the /metrics + # endpoint w/o any authn/z, uncomment the following line and + # comment manager_auth_proxy_patch.yaml. + # Only one of manager_auth_proxy_patch.yaml and + # manager_prometheus_metrics_patch.yaml should be enabled. + #- manager_prometheus_metrics_patch.yaml + +vars: + - name: SIDERO_CERTIFICATE_NAMESPACE # namespace of the certificate CR + objref: + kind: Certificate + group: cert-manager.io + version: v1 + name: sidero-serving-cert # this name should match the one in certificate.yaml + fieldref: + fieldpath: metadata.namespace + - name: SIDERO_CERTIFICATE_NAME + objref: + kind: Certificate + group: cert-manager.io + version: v1 + name: sidero-serving-cert # this name should match the one in certificate.yaml + - name: SIDERO_WEBHOOK_SERVICE_NAMESPACE # namespace of the service + objref: + kind: Service + version: v1 + name: sidero-webhook-service + fieldref: + fieldpath: metadata.namespace + - name: SIDERO_WEBHOOK_SERVICE_NAME + objref: + kind: Service + version: v1 + name: sidero-webhook-service + +configurations: + - kustomizeconfig.yaml \ No newline at end of file diff --git a/app/sidero-controller-manager/config/default/kustomizeconfig.yaml b/app/sidero-controller-manager/config/default/kustomizeconfig.yaml new file mode 100644 index 000000000..524d39cc2 --- /dev/null +++ b/app/sidero-controller-manager/config/default/kustomizeconfig.yaml @@ -0,0 +1,4 @@ +# This configuration is for teaching kustomize how to update name ref and var substitution +varReference: + - kind: Deployment + path: spec/template/spec/volumes/secret/secretName diff --git a/app/sidero-controller-manager/config/default/manager_webhook_patch.yaml b/app/sidero-controller-manager/config/default/manager_webhook_patch.yaml new file mode 100644 index 000000000..553640ff6 --- /dev/null +++ b/app/sidero-controller-manager/config/default/manager_webhook_patch.yaml @@ -0,0 +1,23 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-manager + namespace: system +spec: + template: + spec: + containers: + - name: manager + ports: + - containerPort: 9443 + name: webhook-server + protocol: TCP + volumeMounts: + - mountPath: /tmp/k8s-webhook-server/serving-certs + name: cert + readOnly: true + volumes: + - name: cert + secret: + defaultMode: 420 + secretName: $(SIDERO_WEBHOOK_SERVICE_NAME)-cert diff --git a/app/sidero-controller-manager/config/webhookcainjection_patch.yaml b/app/sidero-controller-manager/config/default/webhookcainjection_patch.yaml similarity index 54% rename from app/sidero-controller-manager/config/webhookcainjection_patch.yaml rename to app/sidero-controller-manager/config/default/webhookcainjection_patch.yaml index 7e79bf995..d27e69c41 100644 --- a/app/sidero-controller-manager/config/webhookcainjection_patch.yaml +++ b/app/sidero-controller-manager/config/default/webhookcainjection_patch.yaml @@ -1,15 +1,15 @@ # This patch add annotation to admission webhook config and -# the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. +# the variables $(SIDERO_CERTIFICATE_NAMESPACE) and $(SIDERO_CERTIFICATE_NAME) will be substituted by kustomize. apiVersion: admissionregistration.k8s.io/v1beta1 kind: MutatingWebhookConfiguration metadata: name: mutating-webhook-configuration annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + cert-manager.io/inject-ca-from: $(SIDERO_CERTIFICATE_NAMESPACE)/$(SIDERO_CERTIFICATE_NAME) --- apiVersion: admissionregistration.k8s.io/v1beta1 kind: ValidatingWebhookConfiguration metadata: name: validating-webhook-configuration annotations: - cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + cert-manager.io/inject-ca-from: $(SIDERO_CERTIFICATE_NAMESPACE)/$(SIDERO_CERTIFICATE_NAME) diff --git a/app/sidero-controller-manager/config/kustomization.yaml b/app/sidero-controller-manager/config/kustomization.yaml deleted file mode 100644 index 2d6c596c0..000000000 --- a/app/sidero-controller-manager/config/kustomization.yaml +++ /dev/null @@ -1,67 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization - -bases: - - crd - - rbac - - manager -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in crd/kustomization.yaml -#- ../webhook -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. -#- ../certmanager -# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. -#- ../prometheus - -namePrefix: sidero- - -patchesStrategicMerge: - # Protect the /metrics endpoint by putting it behind auth. - # Only one of manager_auth_proxy_patch.yaml and - # manager_prometheus_metrics_patch.yaml should be enabled. - #- manager_auth_proxy_patch.yaml - # If you want your controller-manager to expose the /metrics - # endpoint w/o any authn/z, uncomment the following line and - # comment manager_auth_proxy_patch.yaml. - # Only one of manager_auth_proxy_patch.yaml and - # manager_prometheus_metrics_patch.yaml should be enabled. -#- manager_prometheus_metrics_patch.yaml - -# [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in crd/kustomization.yaml -#- manager_webhook_patch.yaml - -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. -# Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. -# 'CERTMANAGER' needs to be enabled to use ca injection -#- webhookcainjection_patch.yaml - -# the following config is for teaching kustomize how to do var substitution -vars: -# [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. -#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR -# objref: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # this name should match the one in certificate.yaml -# fieldref: -# fieldpath: metadata.namespace -#- name: CERTIFICATE_NAME -# objref: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # this name should match the one in certificate.yaml -#- name: SERVICE_NAMESPACE # namespace of the service -# objref: -# kind: Service -# version: v1 -# name: webhook-service -# fieldref: -# fieldpath: metadata.namespace -#- name: SERVICE_NAME -# objref: -# kind: Service -# version: v1 -# name: webhook-service - -namespace: sidero-system diff --git a/app/sidero-controller-manager/config/manager/manager.yaml b/app/sidero-controller-manager/config/manager/manager.yaml index 62f556d13..389af613b 100644 --- a/app/sidero-controller-manager/config/manager/manager.yaml +++ b/app/sidero-controller-manager/config/manager/manager.yaml @@ -49,6 +49,8 @@ spec: matchLabels: control-plane: sidero-controller-manager replicas: 1 + strategy: + type: ${SIDERO_CONTROLLER_MANAGER_DEPLOYMENT_STRATEGY:=RollingUpdate} template: metadata: labels: diff --git a/app/sidero-controller-manager/config/manager_webhook_patch.yaml b/app/sidero-controller-manager/config/manager_webhook_patch.yaml deleted file mode 100644 index 738de350b..000000000 --- a/app/sidero-controller-manager/config/manager_webhook_patch.yaml +++ /dev/null @@ -1,23 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: controller-manager - namespace: system -spec: - template: - spec: - containers: - - name: manager - ports: - - containerPort: 9443 - name: webhook-server - protocol: TCP - volumeMounts: - - mountPath: /tmp/k8s-webhook-server/serving-certs - name: cert - readOnly: true - volumes: - - name: cert - secret: - defaultMode: 420 - secretName: webhook-server-cert diff --git a/app/sidero-controller-manager/config/prometheus/monitor.yaml b/app/sidero-controller-manager/config/prometheus/monitor.yaml index 77aff0521..028ccd47e 100644 --- a/app/sidero-controller-manager/config/prometheus/monitor.yaml +++ b/app/sidero-controller-manager/config/prometheus/monitor.yaml @@ -3,7 +3,7 @@ apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: labels: - control-plane: caps-controller-manager + control-plane: sidero-controller-manager name: metrics-monitor namespace: system spec: @@ -11,4 +11,4 @@ spec: - path: /metrics port: https selector: - control-plane: caps-controller-manager + control-plane: sidero-controller-manager diff --git a/app/sidero-controller-manager/config/rbac/auth_proxy_service.yaml b/app/sidero-controller-manager/config/rbac/auth_proxy_service.yaml index 7b290b306..41dcd3c90 100644 --- a/app/sidero-controller-manager/config/rbac/auth_proxy_service.yaml +++ b/app/sidero-controller-manager/config/rbac/auth_proxy_service.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: - control-plane: caps-controller-manager + control-plane: sidero-controller-manager name: controller-manager-metrics-service namespace: system spec: @@ -11,4 +11,4 @@ spec: port: 8443 targetPort: https selector: - control-plane: caps-controller-manager + control-plane: sidero-controller-manager diff --git a/app/sidero-controller-manager/config/samples/metal_v1alpha1_server.yaml b/app/sidero-controller-manager/config/samples/metal_v1alpha1_server.yaml deleted file mode 100644 index f46b21ae7..000000000 --- a/app/sidero-controller-manager/config/samples/metal_v1alpha1_server.yaml +++ /dev/null @@ -1,27 +0,0 @@ -apiVersion: metal.sidero.dev/v1alpha1 -kind: Server -metadata: - name: 00000000-0000-0000-0000-d05099d333e0 - labels: - common-label: "true" - zone: east - environment: test -spec: - accepted: false - configPatches: - - op: replace - path: /cluster/network/cni - value: - name: custom - urls: - - http://192.168.1.199/assets/cilium.yaml - cpu: - manufacturer: Intel(R) Corporation - version: Intel(R) Atom(TM) CPU C3558 @ 2.20GHz - system: - family: Unknown - manufacturer: Unknown - productName: Unknown - serialNumber: Unknown - skuNumber: Unknown - version: Unknown diff --git a/app/sidero-controller-manager/config/samples/metal_v1alpha1_serverclass.yaml b/app/sidero-controller-manager/config/samples/metal_v1alpha1_serverclass.yaml deleted file mode 100644 index f6260a88e..000000000 --- a/app/sidero-controller-manager/config/samples/metal_v1alpha1_serverclass.yaml +++ /dev/null @@ -1,29 +0,0 @@ -apiVersion: metal.sidero.dev/v1alpha1 -kind: ServerClass -metadata: - name: serverclass-sample -spec: - selector: - matchLabels: - common-label: "true" - matchExpressions: - - key: zone - operator: In - values: - - central - - east - - key: environment - operator: NotIn - values: - - prod - qualifiers: - cpu: - - manufacturer: "Intel(R) Corporation" - version: "Intel(R) Atom(TM) CPU C3558 @ 2.20GHz" - systemInformation: - - family: Unknown - manufacturer: Unknown - productName: Unknown - serialNumber: Unknown - skuNumber: Unknown - version: Unknown diff --git a/app/sidero-controller-manager/config/samples/metal_v1alpha1_environment.yaml b/app/sidero-controller-manager/config/samples/metal_v1alpha2_environment.yaml similarity index 95% rename from app/sidero-controller-manager/config/samples/metal_v1alpha1_environment.yaml rename to app/sidero-controller-manager/config/samples/metal_v1alpha2_environment.yaml index b3790ae53..d0cec81d5 100644 --- a/app/sidero-controller-manager/config/samples/metal_v1alpha1_environment.yaml +++ b/app/sidero-controller-manager/config/samples/metal_v1alpha2_environment.yaml @@ -1,4 +1,4 @@ -apiVersion: metal.sidero.dev/v1alpha1 +apiVersion: metal.sidero.dev/v1alpha2 kind: Environment metadata: name: default diff --git a/app/sidero-controller-manager/config/samples/metal_v1alpha2_server.yaml b/app/sidero-controller-manager/config/samples/metal_v1alpha2_server.yaml new file mode 100644 index 000000000..2ffb570bb --- /dev/null +++ b/app/sidero-controller-manager/config/samples/metal_v1alpha2_server.yaml @@ -0,0 +1,77 @@ +apiVersion: metal.sidero.dev/v1alpha2 +kind: Server +metadata: + name: 00000000-0000-0000-0000-d05099d333e0 + labels: + common-label: "true" + zone: east + environment: test +spec: + accepted: false + configPatches: + - op: replace + path: /cluster/network/cni + value: + name: custom + urls: + - http://192.168.1.199/assets/cilium.yaml + hardware: + system: + manufacturer: Dell Inc. + productName: PowerEdge R630 + serialNumber: 790H8D2 + compute: + totalCoreCount: 8 + totalThreadCount: 16 + processorCount: 1 + processors: + - manufacturer: Intel + productName: Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz + speed: 2400 + coreCount: 8 + threadCount: 16 + memory: + totalSize: 32 GB + moduleCount: 2 + modules: + - manufacturer: 002C00B3002C + productName: 18ASF2G72PDZ-2G3B1 + serialNumber: 12BDC045 + type: LPDDR3 + size: 16384 + speed: 2400 + - manufacturer: 002C00B3002C + productName: 18ASF2G72PDZ-2G3B1 + serialNumber: 12BDBF5D + type: LPDDR3 + size: 16384 + speed: 2400 + storage: + totalSize: 1116 GB + deviceCount: 1 + devices: + - productName: PERC H730 Mini + type: HDD + name: sda + deviceName: /dev/sda + size: 1199101181952 + wwid: naa.61866da055de070028d8e83307cc6df2 + network: + interfaceCount: 2 + interfaces: + - index: 1 + name: lo + flags: up|loopback + mtu: 65536 + mac: "" + addresses: + - 127.0.0.1/8 + - ::1/128 + - index: 2 + name: enp3s0 + flags: up|broadcast|multicast + mtu: 1500 + mac: "40:8d:5c:86:5a:14" + addresses: + - 192.168.2.8/24 + - fe80::dcb3:295c:755b:91bb/64 diff --git a/app/sidero-controller-manager/config/samples/metal_v1alpha2_serverclass.yaml b/app/sidero-controller-manager/config/samples/metal_v1alpha2_serverclass.yaml new file mode 100644 index 000000000..ab3c3336f --- /dev/null +++ b/app/sidero-controller-manager/config/samples/metal_v1alpha2_serverclass.yaml @@ -0,0 +1,27 @@ +apiVersion: metal.sidero.dev/v1alpha2 +kind: ServerClass +metadata: + name: serverclass-sample +spec: + selector: + matchLabels: + common-label: "true" + matchExpressions: + - key: zone + operator: In + values: + - central + - east + - key: environment + operator: NotIn + values: + - prod + qualifiers: + - system: + manufacturer: Dell Inc. + compute: + processors: + - manufacturer: "Intel" + productName: "Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz" + memory: + totalSize: 32 GB diff --git a/app/sidero-controller-manager/config/webhook/service.yaml b/app/sidero-controller-manager/config/webhook/service.yaml index ad5d8bab7..05b153999 100644 --- a/app/sidero-controller-manager/config/webhook/service.yaml +++ b/app/sidero-controller-manager/config/webhook/service.yaml @@ -1,11 +1,11 @@ apiVersion: v1 kind: Service metadata: - name: webhook-service + name: sidero-webhook-service namespace: system spec: ports: - port: 443 targetPort: 9443 selector: - control-plane: caps-controller-manager + control-plane: sidero-controller-manager diff --git a/app/sidero-controller-manager/controllers/environment_controller.go b/app/sidero-controller-manager/controllers/environment_controller.go index a42ea5814..460c21f70 100644 --- a/app/sidero-controller-manager/controllers/environment_controller.go +++ b/app/sidero-controller-manager/controllers/environment_controller.go @@ -24,7 +24,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller" - metalv1alpha1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" "github.com/talos-systems/sidero/app/sidero-controller-manager/pkg/constants" ) @@ -48,7 +48,7 @@ func (r *EnvironmentReconciler) Reconcile(ctx context.Context, req ctrl.Request) //nolint:godox // TODO: We probably should use admission webhooks instead (or in additional) to prevent // unwanted edits instead of "fixing" the resource after the fact. - if req.Name == metalv1alpha1.EnvironmentDefault { + if req.Name == metalv1.EnvironmentDefault { if err := ReconcileEnvironmentDefault(ctx, r.Client, r.TalosRelease, r.APIEndpoint, r.APIPort); err != nil { return ctrl.Result{}, err } @@ -56,7 +56,7 @@ func (r *EnvironmentReconciler) Reconcile(ctx context.Context, req ctrl.Request) // do not return; re-reconcile it to update status } //nolint:wsl - var env metalv1alpha1.Environment + var env metalv1.Environment if err := r.Get(ctx, req.NamespacedName, &env); err != nil { l.Error(err, "failed fetching resource") @@ -72,7 +72,7 @@ func (r *EnvironmentReconciler) Reconcile(ctx context.Context, req ctrl.Request) } var ( - conditions = []metalv1alpha1.AssetCondition{} + conditions = []metalv1.AssetCondition{} wg sync.WaitGroup mu sync.Mutex result *multierror.Error @@ -80,7 +80,7 @@ func (r *EnvironmentReconciler) Reconcile(ctx context.Context, req ctrl.Request) for _, assetTask := range []struct { BaseName string - Asset metalv1alpha1.Asset + Asset metalv1.Asset }{ { BaseName: constants.KernelAsset, @@ -101,7 +101,7 @@ func (r *EnvironmentReconciler) Reconcile(ctx context.Context, req ctrl.Request) status = "True" } - condition := metalv1alpha1.AssetCondition{ + condition := metalv1.AssetCondition{ Asset: assetTask.Asset, Status: status, Type: "Ready", @@ -183,15 +183,15 @@ func (r *EnvironmentReconciler) Reconcile(ctx context.Context, req ctrl.Request) // ReconcileEnvironmentDefault ensures that Environment "default" exist. func ReconcileEnvironmentDefault(ctx context.Context, c client.Client, talosRelease, apiEndpoint string, apiPort uint16) error { key := types.NamespacedName{ - Name: metalv1alpha1.EnvironmentDefault, + Name: metalv1.EnvironmentDefault, } - env := metalv1alpha1.Environment{} + env := metalv1.Environment{} err := c.Get(ctx, key, &env) if apierrors.IsNotFound(err) { - env.Name = metalv1alpha1.EnvironmentDefault - env.Spec = *metalv1alpha1.EnvironmentDefaultSpec(talosRelease, apiEndpoint, apiPort) + env.Name = metalv1.EnvironmentDefault + env.Spec = *metalv1.EnvironmentDefaultSpec(talosRelease, apiEndpoint, apiPort) err = c.Create(ctx, &env) } @@ -206,11 +206,11 @@ func (r *EnvironmentReconciler) SetupWithManager(ctx context.Context, mgr ctrl.M return ctrl.NewControllerManagedBy(mgr). WithOptions(options). - For(&metalv1alpha1.Environment{}). + For(&metalv1.Environment{}). Complete(r) } -func save(ctx context.Context, asset metalv1alpha1.Asset, file string) error { +func save(ctx context.Context, asset metalv1.Asset, file string) error { url := asset.URL if url == "" { diff --git a/app/sidero-controller-manager/controllers/server_controller.go b/app/sidero-controller-manager/controllers/server_controller.go index 9733f8283..f7b86ce6f 100644 --- a/app/sidero-controller-manager/controllers/server_controller.go +++ b/app/sidero-controller-manager/controllers/server_controller.go @@ -31,7 +31,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/source" infrav1 "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" - metalv1alpha1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" "github.com/talos-systems/sidero/app/sidero-controller-manager/internal/power" "github.com/talos-systems/sidero/app/sidero-controller-manager/internal/power/metal" "github.com/talos-systems/sidero/app/sidero-controller-manager/pkg/constants" @@ -65,7 +65,7 @@ type ServerReconciler struct { func (r *ServerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { log := r.Log.WithValues("server", req.NamespacedName) - s := metalv1alpha1.Server{} + s := metalv1.Server{} if err := r.APIReader.Get(ctx, req.NamespacedName, &s); err != nil { return ctrl.Result{}, client.IgnoreNotFound(err) @@ -106,7 +106,7 @@ func (r *ServerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr s.Status.Ready = ready if err := patchHelper.Patch(ctx, &s, patch.WithOwnedConditions{ - Conditions: []clusterv1.ConditionType{metalv1alpha1.ConditionPowerCycle, metalv1alpha1.ConditionPXEBooted}, + Conditions: []clusterv1.ConditionType{metalv1.ConditionPowerCycle, metalv1.ConditionPXEBooted}, }); err != nil { return result, errors.WithStack(err) } @@ -127,7 +127,7 @@ func (r *ServerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr s.Status.InUse = false - conditions.Delete(&s, metalv1alpha1.ConditionPXEBooted) + conditions.Delete(&s, metalv1.ConditionPXEBooted) } else { s.Status.InUse = true s.Status.IsClean = false @@ -138,7 +138,7 @@ func (r *ServerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr // Talos installation was successful, so mark the server as PXE booted. if conditions.IsTrue(serverBinding, infrav1.TalosInstalledCondition) { - conditions.MarkTrue(serverBinding, metalv1alpha1.ConditionPXEBooted) + conditions.MarkTrue(serverBinding, metalv1.ConditionPXEBooted) } } } @@ -232,9 +232,9 @@ func (r *ServerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr // // we check LastTransitionTime to see if the server is in the wiping state for too long and // it's time to retry the IPMI sequence - if conditions.Has(&s, metalv1alpha1.ConditionPowerCycle) && - conditions.IsFalse(&s, metalv1alpha1.ConditionPowerCycle) && - time.Since(conditions.GetLastTransitionTime(&s, metalv1alpha1.ConditionPowerCycle).Time) < r.RebootTimeout { + if conditions.Has(&s, metalv1.ConditionPowerCycle) && + conditions.IsFalse(&s, metalv1.ConditionPowerCycle) && + time.Since(conditions.GetLastTransitionTime(&s, metalv1.ConditionPowerCycle).Time) < r.RebootTimeout { // already powercycled, reboot/heartbeat timeout not elapsed, wait more return f(false, ctrl.Result{RequeueAfter: r.RebootTimeout / 3}) } @@ -280,7 +280,7 @@ func (r *ServerReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr } // make sure message is updated in case condition was already set to make sure LastTransitionTime will be updated - conditions.MarkFalse(&s, metalv1alpha1.ConditionPowerCycle, "InProgress", clusterv1.ConditionSeverityInfo, fmt.Sprintf("Server power cycled for wiping at %s.", time.Now().Format(time.RFC3339))) + conditions.MarkFalse(&s, metalv1.ConditionPowerCycle, "InProgress", clusterv1.ConditionSeverityInfo, fmt.Sprintf("Server power cycled for wiping at %s.", time.Now().Format(time.RFC3339))) } // requeue to check for wipe timeout @@ -354,7 +354,7 @@ func (r *ServerReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manage return ctrl.NewControllerManagedBy(mgr). WithOptions(options). - For(&metalv1alpha1.Server{}). + For(&metalv1.Server{}). Watches( &source.Kind{Type: &infrav1.ServerBinding{}}, handler.EnqueueRequestsFromMapFunc(mapRequests), diff --git a/app/sidero-controller-manager/controllers/serverclass_controller.go b/app/sidero-controller-manager/controllers/serverclass_controller.go index f523c5dd2..7c494c7f4 100644 --- a/app/sidero-controller-manager/controllers/serverclass_controller.go +++ b/app/sidero-controller-manager/controllers/serverclass_controller.go @@ -20,7 +20,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/reconcile" "sigs.k8s.io/controller-runtime/pkg/source" - metalv1alpha1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" ) // ServerClassReconciler reconciles a ServerClass object. @@ -42,7 +42,7 @@ func (r *ServerClassReconciler) Reconcile(ctx context.Context, req ctrl.Request) //nolint:godox // TODO: We probably should use admission webhooks instead (or in additional) to prevent // unwanted edits instead of "fixing" the resource after the fact. - if req.Name == metalv1alpha1.ServerClassAny { + if req.Name == metalv1.ServerClassAny { if err := ReconcileServerClassAny(ctx, r.Client); err != nil { return ctrl.Result{}, err } @@ -50,7 +50,7 @@ func (r *ServerClassReconciler) Reconcile(ctx context.Context, req ctrl.Request) // do not return; re-reconcile it to update status } //nolint:wsl - sc := metalv1alpha1.ServerClass{} + sc := metalv1.ServerClass{} if err := r.Get(ctx, req.NamespacedName, &sc); err != nil { l.Error(err, "failed fetching resource") @@ -62,15 +62,15 @@ func (r *ServerClassReconciler) Reconcile(ctx context.Context, req ctrl.Request) return ctrl.Result{}, err } - sl := &metalv1alpha1.ServerList{} + sl := &metalv1.ServerList{} if err := r.List(ctx, sl); err != nil { return ctrl.Result{}, fmt.Errorf("unable to get serverclass: %w", err) } - results, err := metalv1alpha1.FilterServers(sl.Items, - metalv1alpha1.AcceptedServerFilter, - metalv1alpha1.NotCordonedServerFilter, + results, err := metalv1.FilterServers(sl.Items, + metalv1.AcceptedServerFilter, + metalv1.NotCordonedServerFilter, sc.SelectorFilter(), sc.QualifiersFilter(), ) @@ -103,15 +103,15 @@ func (r *ServerClassReconciler) Reconcile(ctx context.Context, req ctrl.Request) // ReconcileServerClassAny ensures that ServerClass "any" exist and is in desired state. func ReconcileServerClassAny(ctx context.Context, c client.Client) error { key := types.NamespacedName{ - Name: metalv1alpha1.ServerClassAny, + Name: metalv1.ServerClassAny, } - sc := metalv1alpha1.ServerClass{} + sc := metalv1.ServerClass{} err := c.Get(ctx, key, &sc) switch { case apierrors.IsNotFound(err): - sc.Name = metalv1alpha1.ServerClassAny + sc.Name = metalv1.ServerClassAny return c.Create(ctx, &sc) @@ -121,7 +121,7 @@ func ReconcileServerClassAny(ctx context.Context, c client.Client) error { return err } - sc.Spec.Qualifiers = metalv1alpha1.Qualifiers{} + sc.Spec.Qualifiers = metalv1.Qualifiers{} return patchHelper.Patch(ctx, &sc) @@ -137,7 +137,7 @@ func (r *ServerClassReconciler) SetupWithManager(ctx context.Context, mgr ctrl.M mapRequests := func(a client.Object) []reconcile.Request { reqList := []reconcile.Request{} - scList := &metalv1alpha1.ServerClassList{} + scList := &metalv1.ServerClassList{} if err := r.List(ctx, scList); err != nil { return reqList @@ -160,9 +160,9 @@ func (r *ServerClassReconciler) SetupWithManager(ctx context.Context, mgr ctrl.M return ctrl.NewControllerManagedBy(mgr). WithOptions(options). - For(&metalv1alpha1.ServerClass{}). + For(&metalv1.ServerClass{}). Watches( - &source.Kind{Type: &metalv1alpha1.Server{}}, + &source.Kind{Type: &metalv1.Server{}}, handler.EnqueueRequestsFromMapFunc(mapRequests), ). Complete(r) diff --git a/app/sidero-controller-manager/controllers/suite_test.go b/app/sidero-controller-manager/controllers/suite_test.go index 2a7f40d38..057160681 100644 --- a/app/sidero-controller-manager/controllers/suite_test.go +++ b/app/sidero-controller-manager/controllers/suite_test.go @@ -18,7 +18,7 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" - metalv1alpha1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" // +kubebuilder:scaffold:imports ) @@ -54,10 +54,10 @@ var _ = BeforeSuite(func(done Done) { Expect(err).ToNot(HaveOccurred()) Expect(cfg).ToNot(BeNil()) - err = metalv1alpha1.AddToScheme(scheme.Scheme) + err = metalv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) - err = metalv1alpha1.AddToScheme(scheme.Scheme) + err = metalv1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) // +kubebuilder:scaffold:scheme diff --git a/app/sidero-controller-manager/internal/api/api.pb.go b/app/sidero-controller-manager/internal/api/api.pb.go index 614ee0e7f..19861df24 100644 --- a/app/sidero-controller-manager/internal/api/api.pb.go +++ b/app/sidero-controller-manager/internal/api/api.pb.go @@ -21,6 +21,61 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) +type StorageType int32 + +const ( + StorageType_Unknown StorageType = 0 + StorageType_SSD StorageType = 1 + StorageType_HDD StorageType = 2 + StorageType_NVMe StorageType = 3 + StorageType_SD StorageType = 4 +) + +// Enum value maps for StorageType. +var ( + StorageType_name = map[int32]string{ + 0: "Unknown", + 1: "SSD", + 2: "HDD", + 3: "NVMe", + 4: "SD", + } + StorageType_value = map[string]int32{ + "Unknown": 0, + "SSD": 1, + "HDD": 2, + "NVMe": 3, + "SD": 4, + } +) + +func (x StorageType) Enum() *StorageType { + p := new(StorageType) + *p = x + return p +} + +func (x StorageType) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (StorageType) Descriptor() protoreflect.EnumDescriptor { + return file_api_proto_enumTypes[0].Descriptor() +} + +func (StorageType) Type() protoreflect.EnumType { + return &file_api_proto_enumTypes[0] +} + +func (x StorageType) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use StorageType.Descriptor instead. +func (StorageType) EnumDescriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{0} +} + type BMCInfo struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -92,37 +147,605 @@ func (x *BMCInfo) GetPass() string { return "" } -type SystemInformation struct { +type SystemInformation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Uuid string `protobuf:"bytes,1,opt,name=uuid,proto3" json:"uuid,omitempty"` + Manufacturer string `protobuf:"bytes,2,opt,name=manufacturer,proto3" json:"manufacturer,omitempty"` + ProductName string `protobuf:"bytes,3,opt,name=product_name,json=productName,proto3" json:"product_name,omitempty"` + Version string `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"` + SerialNumber string `protobuf:"bytes,5,opt,name=serial_number,json=serialNumber,proto3" json:"serial_number,omitempty"` + SkuNumber string `protobuf:"bytes,6,opt,name=sku_number,json=skuNumber,proto3" json:"sku_number,omitempty"` + Family string `protobuf:"bytes,7,opt,name=family,proto3" json:"family,omitempty"` +} + +func (x *SystemInformation) Reset() { + *x = SystemInformation{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SystemInformation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SystemInformation) ProtoMessage() {} + +func (x *SystemInformation) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SystemInformation.ProtoReflect.Descriptor instead. +func (*SystemInformation) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{1} +} + +func (x *SystemInformation) GetUuid() string { + if x != nil { + return x.Uuid + } + return "" +} + +func (x *SystemInformation) GetManufacturer() string { + if x != nil { + return x.Manufacturer + } + return "" +} + +func (x *SystemInformation) GetProductName() string { + if x != nil { + return x.ProductName + } + return "" +} + +func (x *SystemInformation) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *SystemInformation) GetSerialNumber() string { + if x != nil { + return x.SerialNumber + } + return "" +} + +func (x *SystemInformation) GetSkuNumber() string { + if x != nil { + return x.SkuNumber + } + return "" +} + +func (x *SystemInformation) GetFamily() string { + if x != nil { + return x.Family + } + return "" +} + +type Processor struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Manufacturer string `protobuf:"bytes,1,opt,name=manufacturer,proto3" json:"manufacturer,omitempty"` + ProductName string `protobuf:"bytes,2,opt,name=product_name,json=productName,proto3" json:"product_name,omitempty"` + SerialNumber string `protobuf:"bytes,3,opt,name=serial_number,json=serialNumber,proto3" json:"serial_number,omitempty"` + Speed uint32 `protobuf:"varint,4,opt,name=speed,proto3" json:"speed,omitempty"` + CoreCount uint32 `protobuf:"varint,5,opt,name=core_count,json=coreCount,proto3" json:"core_count,omitempty"` + ThreadCount uint32 `protobuf:"varint,6,opt,name=thread_count,json=threadCount,proto3" json:"thread_count,omitempty"` +} + +func (x *Processor) Reset() { + *x = Processor{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Processor) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Processor) ProtoMessage() {} + +func (x *Processor) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Processor.ProtoReflect.Descriptor instead. +func (*Processor) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{2} +} + +func (x *Processor) GetManufacturer() string { + if x != nil { + return x.Manufacturer + } + return "" +} + +func (x *Processor) GetProductName() string { + if x != nil { + return x.ProductName + } + return "" +} + +func (x *Processor) GetSerialNumber() string { + if x != nil { + return x.SerialNumber + } + return "" +} + +func (x *Processor) GetSpeed() uint32 { + if x != nil { + return x.Speed + } + return 0 +} + +func (x *Processor) GetCoreCount() uint32 { + if x != nil { + return x.CoreCount + } + return 0 +} + +func (x *Processor) GetThreadCount() uint32 { + if x != nil { + return x.ThreadCount + } + return 0 +} + +type ComputeInformation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TotalCoreCount uint32 `protobuf:"varint,1,opt,name=total_core_count,json=totalCoreCount,proto3" json:"total_core_count,omitempty"` + TotalThreadCount uint32 `protobuf:"varint,2,opt,name=total_thread_count,json=totalThreadCount,proto3" json:"total_thread_count,omitempty"` + ProcessorCount uint32 `protobuf:"varint,3,opt,name=processor_count,json=processorCount,proto3" json:"processor_count,omitempty"` + Processors []*Processor `protobuf:"bytes,4,rep,name=processors,proto3" json:"processors,omitempty"` +} + +func (x *ComputeInformation) Reset() { + *x = ComputeInformation{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ComputeInformation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ComputeInformation) ProtoMessage() {} + +func (x *ComputeInformation) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ComputeInformation.ProtoReflect.Descriptor instead. +func (*ComputeInformation) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{3} +} + +func (x *ComputeInformation) GetTotalCoreCount() uint32 { + if x != nil { + return x.TotalCoreCount + } + return 0 +} + +func (x *ComputeInformation) GetTotalThreadCount() uint32 { + if x != nil { + return x.TotalThreadCount + } + return 0 +} + +func (x *ComputeInformation) GetProcessorCount() uint32 { + if x != nil { + return x.ProcessorCount + } + return 0 +} + +func (x *ComputeInformation) GetProcessors() []*Processor { + if x != nil { + return x.Processors + } + return nil +} + +type MemoryModule struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Manufacturer string `protobuf:"bytes,1,opt,name=manufacturer,proto3" json:"manufacturer,omitempty"` + ProductName string `protobuf:"bytes,2,opt,name=product_name,json=productName,proto3" json:"product_name,omitempty"` + SerialNumber string `protobuf:"bytes,3,opt,name=serial_number,json=serialNumber,proto3" json:"serial_number,omitempty"` + Type string `protobuf:"bytes,4,opt,name=type,proto3" json:"type,omitempty"` + Size uint32 `protobuf:"varint,5,opt,name=size,proto3" json:"size,omitempty"` + Speed uint32 `protobuf:"varint,6,opt,name=speed,proto3" json:"speed,omitempty"` +} + +func (x *MemoryModule) Reset() { + *x = MemoryModule{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MemoryModule) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MemoryModule) ProtoMessage() {} + +func (x *MemoryModule) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MemoryModule.ProtoReflect.Descriptor instead. +func (*MemoryModule) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{4} +} + +func (x *MemoryModule) GetManufacturer() string { + if x != nil { + return x.Manufacturer + } + return "" +} + +func (x *MemoryModule) GetProductName() string { + if x != nil { + return x.ProductName + } + return "" +} + +func (x *MemoryModule) GetSerialNumber() string { + if x != nil { + return x.SerialNumber + } + return "" +} + +func (x *MemoryModule) GetType() string { + if x != nil { + return x.Type + } + return "" +} + +func (x *MemoryModule) GetSize() uint32 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *MemoryModule) GetSpeed() uint32 { + if x != nil { + return x.Speed + } + return 0 +} + +type MemoryInformation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TotalSize uint32 `protobuf:"varint,1,opt,name=total_size,json=totalSize,proto3" json:"total_size,omitempty"` + ModuleCount uint32 `protobuf:"varint,2,opt,name=module_count,json=moduleCount,proto3" json:"module_count,omitempty"` + Modules []*MemoryModule `protobuf:"bytes,3,rep,name=modules,proto3" json:"modules,omitempty"` +} + +func (x *MemoryInformation) Reset() { + *x = MemoryInformation{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *MemoryInformation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MemoryInformation) ProtoMessage() {} + +func (x *MemoryInformation) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MemoryInformation.ProtoReflect.Descriptor instead. +func (*MemoryInformation) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{5} +} + +func (x *MemoryInformation) GetTotalSize() uint32 { + if x != nil { + return x.TotalSize + } + return 0 +} + +func (x *MemoryInformation) GetModuleCount() uint32 { + if x != nil { + return x.ModuleCount + } + return 0 +} + +func (x *MemoryInformation) GetModules() []*MemoryModule { + if x != nil { + return x.Modules + } + return nil +} + +type StorageDevice struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Type StorageType `protobuf:"varint,1,opt,name=type,proto3,enum=api.StorageType" json:"type,omitempty"` + Size uint64 `protobuf:"varint,2,opt,name=size,proto3" json:"size,omitempty"` + Model string `protobuf:"bytes,3,opt,name=model,proto3" json:"model,omitempty"` + Serial string `protobuf:"bytes,4,opt,name=serial,proto3" json:"serial,omitempty"` + Name string `protobuf:"bytes,5,opt,name=name,proto3" json:"name,omitempty"` + DeviceName string `protobuf:"bytes,6,opt,name=device_name,json=deviceName,proto3" json:"device_name,omitempty"` + Uuid string `protobuf:"bytes,7,opt,name=uuid,proto3" json:"uuid,omitempty"` + Wwid string `protobuf:"bytes,8,opt,name=wwid,proto3" json:"wwid,omitempty"` +} + +func (x *StorageDevice) Reset() { + *x = StorageDevice{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StorageDevice) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StorageDevice) ProtoMessage() {} + +func (x *StorageDevice) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StorageDevice.ProtoReflect.Descriptor instead. +func (*StorageDevice) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{6} +} + +func (x *StorageDevice) GetType() StorageType { + if x != nil { + return x.Type + } + return StorageType_Unknown +} + +func (x *StorageDevice) GetSize() uint64 { + if x != nil { + return x.Size + } + return 0 +} + +func (x *StorageDevice) GetModel() string { + if x != nil { + return x.Model + } + return "" +} + +func (x *StorageDevice) GetSerial() string { + if x != nil { + return x.Serial + } + return "" +} + +func (x *StorageDevice) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *StorageDevice) GetDeviceName() string { + if x != nil { + return x.DeviceName + } + return "" +} + +func (x *StorageDevice) GetUuid() string { + if x != nil { + return x.Uuid + } + return "" +} + +func (x *StorageDevice) GetWwid() string { + if x != nil { + return x.Wwid + } + return "" +} + +type StorageInformation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + TotalSize uint64 `protobuf:"varint,1,opt,name=total_size,json=totalSize,proto3" json:"total_size,omitempty"` + DeviceCount uint32 `protobuf:"varint,2,opt,name=device_count,json=deviceCount,proto3" json:"device_count,omitempty"` + Devices []*StorageDevice `protobuf:"bytes,3,rep,name=devices,proto3" json:"devices,omitempty"` +} + +func (x *StorageInformation) Reset() { + *x = StorageInformation{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StorageInformation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StorageInformation) ProtoMessage() {} + +func (x *StorageInformation) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StorageInformation.ProtoReflect.Descriptor instead. +func (*StorageInformation) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{7} +} + +func (x *StorageInformation) GetTotalSize() uint64 { + if x != nil { + return x.TotalSize + } + return 0 +} + +func (x *StorageInformation) GetDeviceCount() uint32 { + if x != nil { + return x.DeviceCount + } + return 0 +} + +func (x *StorageInformation) GetDevices() []*StorageDevice { + if x != nil { + return x.Devices + } + return nil +} + +type NetworkInterface struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Uuid string `protobuf:"bytes,1,opt,name=uuid,proto3" json:"uuid,omitempty"` - Manufacturer string `protobuf:"bytes,2,opt,name=manufacturer,proto3" json:"manufacturer,omitempty"` - ProductName string `protobuf:"bytes,3,opt,name=product_name,json=productName,proto3" json:"product_name,omitempty"` - Version string `protobuf:"bytes,4,opt,name=version,proto3" json:"version,omitempty"` - SerialNumber string `protobuf:"bytes,5,opt,name=serial_number,json=serialNumber,proto3" json:"serial_number,omitempty"` - SkuNumber string `protobuf:"bytes,6,opt,name=sku_number,json=skuNumber,proto3" json:"sku_number,omitempty"` - Family string `protobuf:"bytes,7,opt,name=family,proto3" json:"family,omitempty"` + Index uint32 `protobuf:"varint,1,opt,name=index,proto3" json:"index,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + Flags string `protobuf:"bytes,3,opt,name=flags,proto3" json:"flags,omitempty"` + Mtu uint32 `protobuf:"varint,4,opt,name=mtu,proto3" json:"mtu,omitempty"` + Mac string `protobuf:"bytes,5,opt,name=mac,proto3" json:"mac,omitempty"` + Addresses []string `protobuf:"bytes,6,rep,name=addresses,proto3" json:"addresses,omitempty"` } -func (x *SystemInformation) Reset() { - *x = SystemInformation{} +func (x *NetworkInterface) Reset() { + *x = NetworkInterface{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[1] + mi := &file_api_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *SystemInformation) String() string { +func (x *NetworkInterface) String() string { return protoimpl.X.MessageStringOf(x) } -func (*SystemInformation) ProtoMessage() {} +func (*NetworkInterface) ProtoMessage() {} -func (x *SystemInformation) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[1] +func (x *NetworkInterface) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -133,86 +756,137 @@ func (x *SystemInformation) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use SystemInformation.ProtoReflect.Descriptor instead. -func (*SystemInformation) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{1} +// Deprecated: Use NetworkInterface.ProtoReflect.Descriptor instead. +func (*NetworkInterface) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{8} } -func (x *SystemInformation) GetUuid() string { +func (x *NetworkInterface) GetIndex() uint32 { if x != nil { - return x.Uuid + return x.Index } - return "" + return 0 } -func (x *SystemInformation) GetManufacturer() string { +func (x *NetworkInterface) GetName() string { if x != nil { - return x.Manufacturer + return x.Name } return "" } -func (x *SystemInformation) GetProductName() string { +func (x *NetworkInterface) GetFlags() string { if x != nil { - return x.ProductName + return x.Flags } return "" } -func (x *SystemInformation) GetVersion() string { +func (x *NetworkInterface) GetMtu() uint32 { if x != nil { - return x.Version + return x.Mtu } - return "" + return 0 } -func (x *SystemInformation) GetSerialNumber() string { +func (x *NetworkInterface) GetMac() string { if x != nil { - return x.SerialNumber + return x.Mac } return "" } -func (x *SystemInformation) GetSkuNumber() string { +func (x *NetworkInterface) GetAddresses() []string { if x != nil { - return x.SkuNumber + return x.Addresses } - return "" + return nil } -func (x *SystemInformation) GetFamily() string { +type NetworkInformation struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + InterfaceCount uint32 `protobuf:"varint,1,opt,name=interface_count,json=interfaceCount,proto3" json:"interface_count,omitempty"` + Interfaces []*NetworkInterface `protobuf:"bytes,2,rep,name=interfaces,proto3" json:"interfaces,omitempty"` +} + +func (x *NetworkInformation) Reset() { + *x = NetworkInformation{} + if protoimpl.UnsafeEnabled { + mi := &file_api_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NetworkInformation) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NetworkInformation) ProtoMessage() {} + +func (x *NetworkInformation) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use NetworkInformation.ProtoReflect.Descriptor instead. +func (*NetworkInformation) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{9} +} + +func (x *NetworkInformation) GetInterfaceCount() uint32 { if x != nil { - return x.Family + return x.InterfaceCount } - return "" + return 0 +} + +func (x *NetworkInformation) GetInterfaces() []*NetworkInterface { + if x != nil { + return x.Interfaces + } + return nil } -type CPU struct { +type HardwareInformation struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Manufacturer string `protobuf:"bytes,1,opt,name=manufacturer,proto3" json:"manufacturer,omitempty"` - Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + System *SystemInformation `protobuf:"bytes,1,opt,name=system,proto3" json:"system,omitempty"` + Compute *ComputeInformation `protobuf:"bytes,2,opt,name=compute,proto3" json:"compute,omitempty"` + Memory *MemoryInformation `protobuf:"bytes,3,opt,name=memory,proto3" json:"memory,omitempty"` + Storage *StorageInformation `protobuf:"bytes,4,opt,name=storage,proto3" json:"storage,omitempty"` + Network *NetworkInformation `protobuf:"bytes,5,opt,name=network,proto3" json:"network,omitempty"` } -func (x *CPU) Reset() { - *x = CPU{} +func (x *HardwareInformation) Reset() { + *x = HardwareInformation{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[2] + mi := &file_api_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } } -func (x *CPU) String() string { +func (x *HardwareInformation) String() string { return protoimpl.X.MessageStringOf(x) } -func (*CPU) ProtoMessage() {} +func (*HardwareInformation) ProtoMessage() {} -func (x *CPU) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[2] +func (x *HardwareInformation) ProtoReflect() protoreflect.Message { + mi := &file_api_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -223,23 +897,44 @@ func (x *CPU) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use CPU.ProtoReflect.Descriptor instead. -func (*CPU) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{2} +// Deprecated: Use HardwareInformation.ProtoReflect.Descriptor instead. +func (*HardwareInformation) Descriptor() ([]byte, []int) { + return file_api_proto_rawDescGZIP(), []int{10} } -func (x *CPU) GetManufacturer() string { +func (x *HardwareInformation) GetSystem() *SystemInformation { if x != nil { - return x.Manufacturer + return x.System } - return "" + return nil } -func (x *CPU) GetVersion() string { +func (x *HardwareInformation) GetCompute() *ComputeInformation { if x != nil { - return x.Version + return x.Compute } - return "" + return nil +} + +func (x *HardwareInformation) GetMemory() *MemoryInformation { + if x != nil { + return x.Memory + } + return nil +} + +func (x *HardwareInformation) GetStorage() *StorageInformation { + if x != nil { + return x.Storage + } + return nil +} + +func (x *HardwareInformation) GetNetwork() *NetworkInformation { + if x != nil { + return x.Network + } + return nil } type CreateServerRequest struct { @@ -247,15 +942,14 @@ type CreateServerRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - SystemInformation *SystemInformation `protobuf:"bytes,1,opt,name=system_information,json=systemInformation,proto3" json:"system_information,omitempty"` - Cpu *CPU `protobuf:"bytes,2,opt,name=cpu,proto3" json:"cpu,omitempty"` - Hostname string `protobuf:"bytes,3,opt,name=hostname,proto3" json:"hostname,omitempty"` + Hardware *HardwareInformation `protobuf:"bytes,1,opt,name=hardware,proto3" json:"hardware,omitempty"` + Hostname string `protobuf:"bytes,3,opt,name=hostname,proto3" json:"hostname,omitempty"` } func (x *CreateServerRequest) Reset() { *x = CreateServerRequest{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[3] + mi := &file_api_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -268,7 +962,7 @@ func (x *CreateServerRequest) String() string { func (*CreateServerRequest) ProtoMessage() {} func (x *CreateServerRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[3] + mi := &file_api_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -281,19 +975,12 @@ func (x *CreateServerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateServerRequest.ProtoReflect.Descriptor instead. func (*CreateServerRequest) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{3} -} - -func (x *CreateServerRequest) GetSystemInformation() *SystemInformation { - if x != nil { - return x.SystemInformation - } - return nil + return file_api_proto_rawDescGZIP(), []int{11} } -func (x *CreateServerRequest) GetCpu() *CPU { +func (x *CreateServerRequest) GetHardware() *HardwareInformation { if x != nil { - return x.Cpu + return x.Hardware } return nil } @@ -317,7 +1004,7 @@ type Address struct { func (x *Address) Reset() { *x = Address{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[4] + mi := &file_api_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -330,7 +1017,7 @@ func (x *Address) String() string { func (*Address) ProtoMessage() {} func (x *Address) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[4] + mi := &file_api_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -343,7 +1030,7 @@ func (x *Address) ProtoReflect() protoreflect.Message { // Deprecated: Use Address.ProtoReflect.Descriptor instead. func (*Address) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{4} + return file_api_proto_rawDescGZIP(), []int{12} } func (x *Address) GetType() string { @@ -374,7 +1061,7 @@ type CreateServerResponse struct { func (x *CreateServerResponse) Reset() { *x = CreateServerResponse{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[5] + mi := &file_api_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -387,7 +1074,7 @@ func (x *CreateServerResponse) String() string { func (*CreateServerResponse) ProtoMessage() {} func (x *CreateServerResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[5] + mi := &file_api_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -400,7 +1087,7 @@ func (x *CreateServerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CreateServerResponse.ProtoReflect.Descriptor instead. func (*CreateServerResponse) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{5} + return file_api_proto_rawDescGZIP(), []int{13} } func (x *CreateServerResponse) GetWipe() bool { @@ -442,7 +1129,7 @@ type MarkServerAsWipedRequest struct { func (x *MarkServerAsWipedRequest) Reset() { *x = MarkServerAsWipedRequest{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[6] + mi := &file_api_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -455,7 +1142,7 @@ func (x *MarkServerAsWipedRequest) String() string { func (*MarkServerAsWipedRequest) ProtoMessage() {} func (x *MarkServerAsWipedRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[6] + mi := &file_api_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -468,7 +1155,7 @@ func (x *MarkServerAsWipedRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MarkServerAsWipedRequest.ProtoReflect.Descriptor instead. func (*MarkServerAsWipedRequest) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{6} + return file_api_proto_rawDescGZIP(), []int{14} } func (x *MarkServerAsWipedRequest) GetUuid() string { @@ -489,7 +1176,7 @@ type HeartbeatRequest struct { func (x *HeartbeatRequest) Reset() { *x = HeartbeatRequest{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[7] + mi := &file_api_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -502,7 +1189,7 @@ func (x *HeartbeatRequest) String() string { func (*HeartbeatRequest) ProtoMessage() {} func (x *HeartbeatRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[7] + mi := &file_api_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -515,7 +1202,7 @@ func (x *HeartbeatRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use HeartbeatRequest.ProtoReflect.Descriptor instead. func (*HeartbeatRequest) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{7} + return file_api_proto_rawDescGZIP(), []int{15} } func (x *HeartbeatRequest) GetUuid() string { @@ -534,7 +1221,7 @@ type MarkServerAsWipedResponse struct { func (x *MarkServerAsWipedResponse) Reset() { *x = MarkServerAsWipedResponse{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[8] + mi := &file_api_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -547,7 +1234,7 @@ func (x *MarkServerAsWipedResponse) String() string { func (*MarkServerAsWipedResponse) ProtoMessage() {} func (x *MarkServerAsWipedResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[8] + mi := &file_api_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -560,7 +1247,7 @@ func (x *MarkServerAsWipedResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MarkServerAsWipedResponse.ProtoReflect.Descriptor instead. func (*MarkServerAsWipedResponse) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{8} + return file_api_proto_rawDescGZIP(), []int{16} } type HeartbeatResponse struct { @@ -572,7 +1259,7 @@ type HeartbeatResponse struct { func (x *HeartbeatResponse) Reset() { *x = HeartbeatResponse{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[9] + mi := &file_api_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -585,7 +1272,7 @@ func (x *HeartbeatResponse) String() string { func (*HeartbeatResponse) ProtoMessage() {} func (x *HeartbeatResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[9] + mi := &file_api_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -598,7 +1285,7 @@ func (x *HeartbeatResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use HeartbeatResponse.ProtoReflect.Descriptor instead. func (*HeartbeatResponse) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{9} + return file_api_proto_rawDescGZIP(), []int{17} } type UpdateBMCInfoRequest struct { @@ -613,7 +1300,7 @@ type UpdateBMCInfoRequest struct { func (x *UpdateBMCInfoRequest) Reset() { *x = UpdateBMCInfoRequest{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[10] + mi := &file_api_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -626,7 +1313,7 @@ func (x *UpdateBMCInfoRequest) String() string { func (*UpdateBMCInfoRequest) ProtoMessage() {} func (x *UpdateBMCInfoRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[10] + mi := &file_api_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -639,7 +1326,7 @@ func (x *UpdateBMCInfoRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateBMCInfoRequest.ProtoReflect.Descriptor instead. func (*UpdateBMCInfoRequest) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{10} + return file_api_proto_rawDescGZIP(), []int{18} } func (x *UpdateBMCInfoRequest) GetUuid() string { @@ -665,7 +1352,7 @@ type UpdateBMCInfoResponse struct { func (x *UpdateBMCInfoResponse) Reset() { *x = UpdateBMCInfoResponse{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[11] + mi := &file_api_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -678,7 +1365,7 @@ func (x *UpdateBMCInfoResponse) String() string { func (*UpdateBMCInfoResponse) ProtoMessage() {} func (x *UpdateBMCInfoResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[11] + mi := &file_api_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -691,7 +1378,7 @@ func (x *UpdateBMCInfoResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UpdateBMCInfoResponse.ProtoReflect.Descriptor instead. func (*UpdateBMCInfoResponse) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{11} + return file_api_proto_rawDescGZIP(), []int{19} } type ReconcileServerAddressesRequest struct { @@ -706,7 +1393,7 @@ type ReconcileServerAddressesRequest struct { func (x *ReconcileServerAddressesRequest) Reset() { *x = ReconcileServerAddressesRequest{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[12] + mi := &file_api_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -719,7 +1406,7 @@ func (x *ReconcileServerAddressesRequest) String() string { func (*ReconcileServerAddressesRequest) ProtoMessage() {} func (x *ReconcileServerAddressesRequest) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[12] + mi := &file_api_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -732,7 +1419,7 @@ func (x *ReconcileServerAddressesRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReconcileServerAddressesRequest.ProtoReflect.Descriptor instead. func (*ReconcileServerAddressesRequest) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{12} + return file_api_proto_rawDescGZIP(), []int{20} } func (x *ReconcileServerAddressesRequest) GetUuid() string { @@ -758,7 +1445,7 @@ type ReconcileServerAddressesResponse struct { func (x *ReconcileServerAddressesResponse) Reset() { *x = ReconcileServerAddressesResponse{} if protoimpl.UnsafeEnabled { - mi := &file_api_proto_msgTypes[13] + mi := &file_api_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -771,7 +1458,7 @@ func (x *ReconcileServerAddressesResponse) String() string { func (*ReconcileServerAddressesResponse) ProtoMessage() {} func (x *ReconcileServerAddressesResponse) ProtoReflect() protoreflect.Message { - mi := &file_api_proto_msgTypes[13] + mi := &file_api_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -784,7 +1471,7 @@ func (x *ReconcileServerAddressesResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReconcileServerAddressesResponse.ProtoReflect.Descriptor instead. func (*ReconcileServerAddressesResponse) Descriptor() ([]byte, []int) { - return file_api_proto_rawDescGZIP(), []int{13} + return file_api_proto_rawDescGZIP(), []int{21} } var File_api_proto protoreflect.FileDescriptor @@ -810,88 +1497,186 @@ var file_api_proto_rawDesc = []byte{ 0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x6b, 0x75, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x6b, 0x75, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x22, 0x43, - 0x0a, 0x03, 0x43, 0x50, 0x55, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, - 0x74, 0x75, 0x72, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6d, 0x61, 0x6e, - 0x75, 0x66, 0x61, 0x63, 0x74, 0x75, 0x72, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x22, 0x94, 0x01, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x45, 0x0a, 0x12, 0x73, - 0x79, 0x73, 0x74, 0x65, 0x6d, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x79, - 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x11, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x03, 0x63, 0x70, 0x75, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x08, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x50, 0x55, 0x52, 0x03, 0x63, 0x70, 0x75, 0x12, 0x1a, - 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x37, 0x0a, 0x07, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x22, 0x93, 0x01, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x77, 0x69, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x77, 0x69, 0x70, 0x65, - 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, 0x77, 0x69, 0x70, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, - 0x65, 0x57, 0x69, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x74, 0x75, 0x70, 0x5f, 0x62, - 0x6d, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x65, 0x74, 0x75, 0x70, 0x42, - 0x6d, 0x63, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x5f, 0x74, 0x69, 0x6d, - 0x65, 0x6f, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0d, 0x72, 0x65, 0x62, 0x6f, - 0x6f, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x2e, 0x0a, 0x18, 0x4d, 0x61, 0x72, - 0x6b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x73, 0x57, 0x69, 0x70, 0x65, 0x64, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0x26, 0x0a, 0x10, 0x48, 0x65, 0x61, - 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, - 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, - 0x64, 0x22, 0x1b, 0x0a, 0x19, 0x4d, 0x61, 0x72, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, - 0x73, 0x57, 0x69, 0x70, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x13, - 0x0a, 0x11, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x53, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x4d, 0x43, - 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, - 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, - 0x27, 0x0a, 0x08, 0x62, 0x6d, 0x63, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x42, 0x4d, 0x43, 0x49, 0x6e, 0x66, 0x6f, 0x52, - 0x07, 0x62, 0x6d, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x17, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x42, 0x4d, 0x43, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x5d, 0x0a, 0x1f, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x65, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x26, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x22, 0x22, 0x0a, 0x20, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x65, 0x53, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x8d, 0x03, 0x0a, 0x05, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x43, - 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x12, 0x18, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, 0x11, 0x4d, 0x61, 0x72, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x41, 0x73, 0x57, 0x69, 0x70, 0x65, 0x64, 0x12, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, - 0x61, 0x72, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x73, 0x57, 0x69, 0x70, 0x65, 0x64, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x61, - 0x72, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x73, 0x57, 0x69, 0x70, 0x65, 0x64, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x67, 0x0a, 0x18, 0x52, 0x65, 0x63, 0x6f, 0x6e, - 0x63, 0x69, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x63, - 0x69, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x3a, 0x0a, 0x09, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x12, 0x15, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x48, 0x65, 0x61, 0x72, 0x74, - 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x46, 0x0a, 0x0d, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x4d, 0x43, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x19, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x4d, 0x43, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x22, 0xcf, + 0x01, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x12, 0x22, 0x0a, 0x0c, + 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, 0x74, 0x75, 0x72, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, 0x74, 0x75, 0x72, 0x65, 0x72, + 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4e, + 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x69, + 0x61, 0x6c, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x70, 0x65, 0x65, + 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x12, 0x1d, + 0x0a, 0x0a, 0x63, 0x6f, 0x72, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x09, 0x63, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x21, 0x0a, + 0x0c, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, + 0x22, 0xc5, 0x01, 0x0a, 0x12, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x49, 0x6e, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x10, 0x74, 0x6f, 0x74, 0x61, 0x6c, + 0x5f, 0x63, 0x6f, 0x72, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x0e, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x43, 0x6f, 0x72, 0x65, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x61, + 0x64, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x74, + 0x6f, 0x74, 0x61, 0x6c, 0x54, 0x68, 0x72, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, + 0x27, 0x0a, 0x0f, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x5f, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x6f, 0x72, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2e, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x6f, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x52, 0x0a, 0x70, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x73, 0x22, 0xb8, 0x01, 0x0a, 0x0c, 0x4d, 0x65, 0x6d, + 0x6f, 0x72, 0x79, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x22, 0x0a, 0x0c, 0x6d, 0x61, 0x6e, + 0x75, 0x66, 0x61, 0x63, 0x74, 0x75, 0x72, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0c, 0x6d, 0x61, 0x6e, 0x75, 0x66, 0x61, 0x63, 0x74, 0x75, 0x72, 0x65, 0x72, 0x12, 0x21, 0x0a, + 0x0c, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x23, 0x0a, 0x0d, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x73, 0x65, 0x72, 0x69, 0x61, 0x6c, 0x4e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, + 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x70, 0x65, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x73, 0x70, + 0x65, 0x65, 0x64, 0x22, 0x82, 0x01, 0x0a, 0x11, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x49, 0x6e, + 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74, + 0x61, 0x6c, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x09, 0x74, + 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x6d, 0x6f, 0x64, 0x75, + 0x6c, 0x65, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, + 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2b, 0x0a, 0x07, 0x6d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x52, + 0x07, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xd4, 0x01, 0x0a, 0x0d, 0x53, 0x74, 0x6f, + 0x72, 0x61, 0x67, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x24, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, + 0x73, 0x69, 0x7a, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, + 0x72, 0x69, 0x61, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x72, 0x69, + 0x61, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, + 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x77, + 0x77, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x77, 0x77, 0x69, 0x64, 0x22, + 0x84, 0x01, 0x0a, 0x12, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, + 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x6f, 0x74, 0x61, + 0x6c, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, + 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x64, 0x65, 0x76, + 0x69, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x64, + 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x22, 0x94, 0x01, 0x0a, 0x10, 0x4e, 0x65, 0x74, 0x77, 0x6f, + 0x72, 0x6b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, + 0x78, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x6d, + 0x74, 0x75, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6d, 0x74, 0x75, 0x12, 0x10, 0x0a, + 0x03, 0x6d, 0x61, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6d, 0x61, 0x63, 0x12, + 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x22, 0x74, 0x0a, + 0x12, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, + 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x35, 0x0a, 0x0a, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x49, 0x6e, + 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x52, 0x0a, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, + 0x63, 0x65, 0x73, 0x22, 0x8e, 0x02, 0x0a, 0x13, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, + 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x06, 0x73, + 0x79, 0x73, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x31, 0x0a, 0x07, 0x63, + 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x12, 0x2e, + 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x49, 0x6e, 0x66, 0x6f, 0x72, + 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x31, + 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, + 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, + 0x65, 0x12, 0x31, 0x0a, 0x07, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, + 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x6e, 0x65, 0x74, + 0x77, 0x6f, 0x72, 0x6b, 0x22, 0x67, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x08, 0x68, + 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x49, 0x6e, 0x66, 0x6f, + 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x08, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, + 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x37, 0x0a, + 0x07, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x22, 0x93, 0x01, 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x77, 0x69, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x77, + 0x69, 0x70, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x5f, + 0x77, 0x69, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x69, 0x6e, 0x73, 0x65, + 0x63, 0x75, 0x72, 0x65, 0x57, 0x69, 0x70, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x65, 0x74, 0x75, + 0x70, 0x5f, 0x62, 0x6d, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x73, 0x65, 0x74, + 0x75, 0x70, 0x42, 0x6d, 0x63, 0x12, 0x25, 0x0a, 0x0e, 0x72, 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x01, 0x52, 0x0d, 0x72, + 0x65, 0x62, 0x6f, 0x6f, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0x2e, 0x0a, 0x18, + 0x4d, 0x61, 0x72, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x73, 0x57, 0x69, 0x70, 0x65, + 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x22, 0x26, 0x0a, 0x10, + 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x75, 0x75, 0x69, 0x64, 0x22, 0x1b, 0x0a, 0x19, 0x4d, 0x61, 0x72, 0x6b, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x41, 0x73, 0x57, 0x69, 0x70, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x13, 0x0a, 0x11, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x53, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x42, 0x4d, 0x43, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, + 0x69, 0x64, 0x12, 0x27, 0x0a, 0x08, 0x62, 0x6d, 0x63, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x42, 0x4d, 0x43, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x07, 0x62, 0x6d, 0x63, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x17, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x4d, 0x43, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2d, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, - 0x2f, 0x73, 0x69, 0x64, 0x65, 0x72, 0x6f, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x73, 0x69, 0x64, 0x65, - 0x72, 0x6f, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, 0x2d, 0x6d, 0x61, - 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x61, - 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x5d, 0x0a, 0x1f, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, + 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x26, 0x0a, 0x07, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x22, 0x22, 0x0a, 0x20, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x65, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2a, 0x3e, 0x0a, 0x0b, 0x53, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, + 0x6e, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x53, 0x53, 0x44, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, + 0x48, 0x44, 0x44, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x4e, 0x56, 0x4d, 0x65, 0x10, 0x03, 0x12, + 0x06, 0x0a, 0x02, 0x53, 0x44, 0x10, 0x04, 0x32, 0x8d, 0x03, 0x0a, 0x05, 0x41, 0x67, 0x65, 0x6e, + 0x74, 0x12, 0x43, 0x0a, 0x0c, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, + 0x72, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, 0x11, 0x4d, 0x61, 0x72, 0x6b, 0x53, 0x65, + 0x72, 0x76, 0x65, 0x72, 0x41, 0x73, 0x57, 0x69, 0x70, 0x65, 0x64, 0x12, 0x1d, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x73, 0x57, 0x69, + 0x70, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x4d, 0x61, 0x72, 0x6b, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x73, 0x57, 0x69, 0x70, + 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x67, 0x0a, 0x18, 0x52, 0x65, + 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x63, + 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x6e, 0x63, 0x69, 0x6c, 0x65, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x3a, 0x0a, 0x09, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, + 0x12, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x48, 0x65, 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x48, 0x65, + 0x61, 0x72, 0x74, 0x62, 0x65, 0x61, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x46, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x4d, 0x43, 0x49, 0x6e, 0x66, 0x6f, + 0x12, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x4d, 0x43, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x42, 0x4d, 0x43, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x4c, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x61, 0x6c, 0x6f, 0x73, 0x2d, 0x73, 0x79, 0x73, 0x74, + 0x65, 0x6d, 0x73, 0x2f, 0x73, 0x69, 0x64, 0x65, 0x72, 0x6f, 0x2f, 0x61, 0x70, 0x70, 0x2f, 0x73, + 0x69, 0x64, 0x65, 0x72, 0x6f, 0x2d, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, 0x72, + 0x2d, 0x6d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x72, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, + 0x6c, 0x2f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -907,45 +1692,64 @@ func file_api_proto_rawDescGZIP() []byte { } var ( - file_api_proto_msgTypes = make([]protoimpl.MessageInfo, 14) - file_api_proto_goTypes = []interface{}{ - (*BMCInfo)(nil), // 0: api.BMCInfo - (*SystemInformation)(nil), // 1: api.SystemInformation - (*CPU)(nil), // 2: api.CPU - (*CreateServerRequest)(nil), // 3: api.CreateServerRequest - (*Address)(nil), // 4: api.Address - (*CreateServerResponse)(nil), // 5: api.CreateServerResponse - (*MarkServerAsWipedRequest)(nil), // 6: api.MarkServerAsWipedRequest - (*HeartbeatRequest)(nil), // 7: api.HeartbeatRequest - (*MarkServerAsWipedResponse)(nil), // 8: api.MarkServerAsWipedResponse - (*HeartbeatResponse)(nil), // 9: api.HeartbeatResponse - (*UpdateBMCInfoRequest)(nil), // 10: api.UpdateBMCInfoRequest - (*UpdateBMCInfoResponse)(nil), // 11: api.UpdateBMCInfoResponse - (*ReconcileServerAddressesRequest)(nil), // 12: api.ReconcileServerAddressesRequest - (*ReconcileServerAddressesResponse)(nil), // 13: api.ReconcileServerAddressesResponse + file_api_proto_enumTypes = make([]protoimpl.EnumInfo, 1) + file_api_proto_msgTypes = make([]protoimpl.MessageInfo, 22) + file_api_proto_goTypes = []interface{}{ + (StorageType)(0), // 0: api.StorageType + (*BMCInfo)(nil), // 1: api.BMCInfo + (*SystemInformation)(nil), // 2: api.SystemInformation + (*Processor)(nil), // 3: api.Processor + (*ComputeInformation)(nil), // 4: api.ComputeInformation + (*MemoryModule)(nil), // 5: api.MemoryModule + (*MemoryInformation)(nil), // 6: api.MemoryInformation + (*StorageDevice)(nil), // 7: api.StorageDevice + (*StorageInformation)(nil), // 8: api.StorageInformation + (*NetworkInterface)(nil), // 9: api.NetworkInterface + (*NetworkInformation)(nil), // 10: api.NetworkInformation + (*HardwareInformation)(nil), // 11: api.HardwareInformation + (*CreateServerRequest)(nil), // 12: api.CreateServerRequest + (*Address)(nil), // 13: api.Address + (*CreateServerResponse)(nil), // 14: api.CreateServerResponse + (*MarkServerAsWipedRequest)(nil), // 15: api.MarkServerAsWipedRequest + (*HeartbeatRequest)(nil), // 16: api.HeartbeatRequest + (*MarkServerAsWipedResponse)(nil), // 17: api.MarkServerAsWipedResponse + (*HeartbeatResponse)(nil), // 18: api.HeartbeatResponse + (*UpdateBMCInfoRequest)(nil), // 19: api.UpdateBMCInfoRequest + (*UpdateBMCInfoResponse)(nil), // 20: api.UpdateBMCInfoResponse + (*ReconcileServerAddressesRequest)(nil), // 21: api.ReconcileServerAddressesRequest + (*ReconcileServerAddressesResponse)(nil), // 22: api.ReconcileServerAddressesResponse } ) var file_api_proto_depIdxs = []int32{ - 1, // 0: api.CreateServerRequest.system_information:type_name -> api.SystemInformation - 2, // 1: api.CreateServerRequest.cpu:type_name -> api.CPU - 0, // 2: api.UpdateBMCInfoRequest.bmc_info:type_name -> api.BMCInfo - 4, // 3: api.ReconcileServerAddressesRequest.address:type_name -> api.Address - 3, // 4: api.Agent.CreateServer:input_type -> api.CreateServerRequest - 6, // 5: api.Agent.MarkServerAsWiped:input_type -> api.MarkServerAsWipedRequest - 12, // 6: api.Agent.ReconcileServerAddresses:input_type -> api.ReconcileServerAddressesRequest - 7, // 7: api.Agent.Heartbeat:input_type -> api.HeartbeatRequest - 10, // 8: api.Agent.UpdateBMCInfo:input_type -> api.UpdateBMCInfoRequest - 5, // 9: api.Agent.CreateServer:output_type -> api.CreateServerResponse - 8, // 10: api.Agent.MarkServerAsWiped:output_type -> api.MarkServerAsWipedResponse - 13, // 11: api.Agent.ReconcileServerAddresses:output_type -> api.ReconcileServerAddressesResponse - 9, // 12: api.Agent.Heartbeat:output_type -> api.HeartbeatResponse - 11, // 13: api.Agent.UpdateBMCInfo:output_type -> api.UpdateBMCInfoResponse - 9, // [9:14] is the sub-list for method output_type - 4, // [4:9] is the sub-list for method input_type - 4, // [4:4] is the sub-list for extension type_name - 4, // [4:4] is the sub-list for extension extendee - 0, // [0:4] is the sub-list for field type_name + 3, // 0: api.ComputeInformation.processors:type_name -> api.Processor + 5, // 1: api.MemoryInformation.modules:type_name -> api.MemoryModule + 0, // 2: api.StorageDevice.type:type_name -> api.StorageType + 7, // 3: api.StorageInformation.devices:type_name -> api.StorageDevice + 9, // 4: api.NetworkInformation.interfaces:type_name -> api.NetworkInterface + 2, // 5: api.HardwareInformation.system:type_name -> api.SystemInformation + 4, // 6: api.HardwareInformation.compute:type_name -> api.ComputeInformation + 6, // 7: api.HardwareInformation.memory:type_name -> api.MemoryInformation + 8, // 8: api.HardwareInformation.storage:type_name -> api.StorageInformation + 10, // 9: api.HardwareInformation.network:type_name -> api.NetworkInformation + 11, // 10: api.CreateServerRequest.hardware:type_name -> api.HardwareInformation + 1, // 11: api.UpdateBMCInfoRequest.bmc_info:type_name -> api.BMCInfo + 13, // 12: api.ReconcileServerAddressesRequest.address:type_name -> api.Address + 12, // 13: api.Agent.CreateServer:input_type -> api.CreateServerRequest + 15, // 14: api.Agent.MarkServerAsWiped:input_type -> api.MarkServerAsWipedRequest + 21, // 15: api.Agent.ReconcileServerAddresses:input_type -> api.ReconcileServerAddressesRequest + 16, // 16: api.Agent.Heartbeat:input_type -> api.HeartbeatRequest + 19, // 17: api.Agent.UpdateBMCInfo:input_type -> api.UpdateBMCInfoRequest + 14, // 18: api.Agent.CreateServer:output_type -> api.CreateServerResponse + 17, // 19: api.Agent.MarkServerAsWiped:output_type -> api.MarkServerAsWipedResponse + 22, // 20: api.Agent.ReconcileServerAddresses:output_type -> api.ReconcileServerAddressesResponse + 18, // 21: api.Agent.Heartbeat:output_type -> api.HeartbeatResponse + 20, // 22: api.Agent.UpdateBMCInfo:output_type -> api.UpdateBMCInfoResponse + 18, // [18:23] is the sub-list for method output_type + 13, // [13:18] is the sub-list for method input_type + 13, // [13:13] is the sub-list for extension type_name + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name } func init() { file_api_proto_init() } @@ -979,7 +1783,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CPU); i { + switch v := v.(*Processor); i { case 0: return &v.state case 1: @@ -991,7 +1795,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateServerRequest); i { + switch v := v.(*ComputeInformation); i { case 0: return &v.state case 1: @@ -1003,7 +1807,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Address); i { + switch v := v.(*MemoryModule); i { case 0: return &v.state case 1: @@ -1015,7 +1819,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateServerResponse); i { + switch v := v.(*MemoryInformation); i { case 0: return &v.state case 1: @@ -1027,7 +1831,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MarkServerAsWipedRequest); i { + switch v := v.(*StorageDevice); i { case 0: return &v.state case 1: @@ -1039,7 +1843,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HeartbeatRequest); i { + switch v := v.(*StorageInformation); i { case 0: return &v.state case 1: @@ -1051,7 +1855,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MarkServerAsWipedResponse); i { + switch v := v.(*NetworkInterface); i { case 0: return &v.state case 1: @@ -1063,7 +1867,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*HeartbeatResponse); i { + switch v := v.(*NetworkInformation); i { case 0: return &v.state case 1: @@ -1075,7 +1879,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateBMCInfoRequest); i { + switch v := v.(*HardwareInformation); i { case 0: return &v.state case 1: @@ -1087,7 +1891,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateBMCInfoResponse); i { + switch v := v.(*CreateServerRequest); i { case 0: return &v.state case 1: @@ -1099,7 +1903,7 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReconcileServerAddressesRequest); i { + switch v := v.(*Address); i { case 0: return &v.state case 1: @@ -1111,6 +1915,102 @@ func file_api_proto_init() { } } file_api_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateServerResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MarkServerAsWipedRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HeartbeatRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*MarkServerAsWipedResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HeartbeatResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateBMCInfoRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateBMCInfoResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ReconcileServerAddressesRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_api_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ReconcileServerAddressesResponse); i { case 0: return &v.state @@ -1128,13 +2028,14 @@ func file_api_proto_init() { File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_api_proto_rawDesc, - NumEnums: 0, - NumMessages: 14, + NumEnums: 1, + NumMessages: 22, NumExtensions: 0, NumServices: 1, }, GoTypes: file_api_proto_goTypes, DependencyIndexes: file_api_proto_depIdxs, + EnumInfos: file_api_proto_enumTypes, MessageInfos: file_api_proto_msgTypes, }.Build() File_api_proto = out.File diff --git a/app/sidero-controller-manager/internal/api/api.proto b/app/sidero-controller-manager/internal/api/api.proto index da142a338..9716201ba 100644 --- a/app/sidero-controller-manager/internal/api/api.proto +++ b/app/sidero-controller-manager/internal/api/api.proto @@ -32,14 +32,86 @@ message SystemInformation { string family = 7; } -message CPU { +message Processor { string manufacturer = 1; - string version = 2; + string product_name = 2; + string serial_number = 3; + uint32 speed = 4; + uint32 core_count = 5; + uint32 thread_count = 6; +} + +message ComputeInformation { + uint32 total_core_count = 1; + uint32 total_thread_count = 2; + uint32 processor_count = 3; + repeated Processor processors = 4; +} + +message MemoryModule { + string manufacturer = 1; + string product_name = 2; + string serial_number = 3; + string type = 4; + uint32 size = 5; + uint32 speed = 6; +} + +message MemoryInformation { + uint32 total_size = 1; + uint32 module_count = 2; + repeated MemoryModule modules = 3; +} + +enum StorageType { + Unknown = 0; + SSD = 1; + HDD = 2; + NVMe = 3; + SD = 4; +} + +message StorageDevice { + StorageType type = 1; + uint64 size = 2; + string model = 3; + string serial = 4; + string name = 5; + string device_name = 6; + string uuid = 7; + string wwid = 8; +} + +message StorageInformation { + uint64 total_size = 1; + uint32 device_count = 2; + repeated StorageDevice devices = 3; +} + +message NetworkInterface { + uint32 index = 1; + string name = 2; + string flags = 3; + uint32 mtu = 4; + string mac = 5; + repeated string addresses = 6; +} + +message NetworkInformation { + uint32 interface_count = 1; + repeated NetworkInterface interfaces = 2; +} + +message HardwareInformation { + SystemInformation system = 1; + ComputeInformation compute = 2; + MemoryInformation memory = 3; + StorageInformation storage = 4; + NetworkInformation network = 5; } message CreateServerRequest { - SystemInformation system_information = 1; - CPU cpu = 2; + HardwareInformation hardware = 1; string hostname = 3; } @@ -55,8 +127,8 @@ message CreateServerResponse { double reboot_timeout = 4; } -message MarkServerAsWipedRequest { string uuid = 1; } -message HeartbeatRequest { string uuid = 1; } +message MarkServerAsWipedRequest {string uuid = 1;} +message HeartbeatRequest {string uuid = 1;} message MarkServerAsWipedResponse {} message HeartbeatResponse {} diff --git a/app/sidero-controller-manager/internal/ipxe/ipxe_server.go b/app/sidero-controller-manager/internal/ipxe/ipxe_server.go index 8fd9e3f36..16a0b524e 100644 --- a/app/sidero-controller-manager/internal/ipxe/ipxe_server.go +++ b/app/sidero-controller-manager/internal/ipxe/ipxe_server.go @@ -32,7 +32,7 @@ import ( "github.com/talos-systems/talos/pkg/machinery/kernel" infrav1 "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" - metalv1alpha1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" "github.com/talos-systems/sidero/app/sidero-controller-manager/internal/siderolink" "github.com/talos-systems/sidero/app/sidero-controller-manager/pkg/constants" siderotypes "github.com/talos-systems/sidero/app/sidero-controller-manager/pkg/types" @@ -208,7 +208,7 @@ func ipxeHandler(w http.ResponseWriter, r *http.Request) { } args := struct { - Env *metalv1alpha1.Environment + Env *metalv1.Environment KernelAsset string InitrdAsset string }{ @@ -249,13 +249,13 @@ func ipxeHandler(w http.ResponseWriter, r *http.Request) { } } -func getBootFromDiskMethod(server *metalv1alpha1.Server, serverBinding *infrav1.ServerBinding) (siderotypes.BootFromDisk, error) { +func getBootFromDiskMethod(server *metalv1.Server, serverBinding *infrav1.ServerBinding) (siderotypes.BootFromDisk, error) { method := defaultBootFromDiskMethod if server.Spec.BootFromDiskMethod != "" { method = server.Spec.BootFromDiskMethod } else if serverBinding.Spec.ServerClassRef != nil { - var serverClass metalv1alpha1.ServerClass + var serverClass metalv1.ServerClass if err := c.Get( context.TODO(), @@ -343,12 +343,12 @@ func parseMAC(s string) (net.HardwareAddr, error) { return macAddr, err } -func lookupServer(uuid string) (*metalv1alpha1.Server, *infrav1.ServerBinding, error) { +func lookupServer(uuid string) (*metalv1.Server, *infrav1.ServerBinding, error) { key := client.ObjectKey{ Name: uuid, } - s := &metalv1alpha1.Server{} + s := &metalv1.Server{} if err := c.Get(context.Background(), key, s); err != nil { if apierrors.IsNotFound(err) { @@ -373,7 +373,7 @@ func lookupServer(uuid string) (*metalv1alpha1.Server, *infrav1.ServerBinding, e // newEnvironment handles which env CRD we'll respect for a given server. // specied in the server spec overrides everything, specified in the server class overrides default, default is default :). -func newEnvironment(server *metalv1alpha1.Server, serverBinding *infrav1.ServerBinding, arch string) (env *metalv1alpha1.Environment, err error) { +func newEnvironment(server *metalv1.Server, serverBinding *infrav1.ServerBinding, arch string) (env *metalv1.Environment, err error) { // NB: The order of this switch statement is important. It defines the // precedence of which environment to boot. switch { @@ -381,7 +381,7 @@ func newEnvironment(server *metalv1alpha1.Server, serverBinding *infrav1.ServerB return newAgentEnvironment(arch), nil case serverBinding == nil: return newAgentEnvironment(arch), nil - case conditions.Has(server, metalv1alpha1.ConditionPXEBooted) && !server.Spec.PXEBootAlways: + case conditions.Has(server, metalv1.ConditionPXEBooted) && !server.Spec.PXEBootAlways: return nil, ErrBootFromDisk case server.Spec.EnvironmentRef != nil: env, err = newEnvironmentFromServer(server) @@ -409,7 +409,7 @@ func newEnvironment(server *metalv1alpha1.Server, serverBinding *infrav1.ServerB return env, nil } -func newAgentEnvironment(arch string) *metalv1alpha1.Environment { +func newAgentEnvironment(arch string) *metalv1.Environment { args := append([]string(nil), kernel.DefaultArgs...) args = append(args, "console=tty0", @@ -428,12 +428,12 @@ func newAgentEnvironment(arch string) *metalv1alpha1.Environment { cmdline.Set(p.Key(), p) } - env := &metalv1alpha1.Environment{ + env := &metalv1.Environment{ ObjectMeta: metav1.ObjectMeta{ Name: fmt.Sprintf("agent-%s", arch), }, - Spec: metalv1alpha1.EnvironmentSpec{ - Kernel: metalv1alpha1.Kernel{ + Spec: metalv1.EnvironmentSpec{ + Kernel: metalv1.Kernel{ Args: cmdline.Strings(), }, }, @@ -442,10 +442,10 @@ func newAgentEnvironment(arch string) *metalv1alpha1.Environment { return env } -func newDefaultEnvironment() (env *metalv1alpha1.Environment, err error) { - env = &metalv1alpha1.Environment{} +func newDefaultEnvironment() (env *metalv1.Environment, err error) { + env = &metalv1.Environment{} - if err := c.Get(context.Background(), types.NamespacedName{Namespace: "", Name: metalv1alpha1.EnvironmentDefault}, env); err != nil { + if err := c.Get(context.Background(), types.NamespacedName{Namespace: "", Name: metalv1.EnvironmentDefault}, env); err != nil { return nil, err } @@ -454,8 +454,8 @@ func newDefaultEnvironment() (env *metalv1alpha1.Environment, err error) { return env, nil } -func newEnvironmentFromServer(server *metalv1alpha1.Server) (env *metalv1alpha1.Environment, err error) { - env = &metalv1alpha1.Environment{} +func newEnvironmentFromServer(server *metalv1.Server) (env *metalv1.Environment, err error) { + env = &metalv1.Environment{} if err := c.Get(context.Background(), types.NamespacedName{Namespace: "", Name: server.Spec.EnvironmentRef.Name}, env); err != nil { return nil, err @@ -466,8 +466,8 @@ func newEnvironmentFromServer(server *metalv1alpha1.Server) (env *metalv1alpha1. return env, nil } -func newEnvironmentFromServerClass(serverBinding *infrav1.ServerBinding) (env *metalv1alpha1.Environment, err error) { - serverClassResource := &metalv1alpha1.ServerClass{} +func newEnvironmentFromServerClass(serverBinding *infrav1.ServerBinding) (env *metalv1.Environment, err error) { + serverClassResource := &metalv1.ServerClass{} if err := c.Get(context.Background(), types.NamespacedName{Namespace: serverBinding.Spec.ServerClassRef.Namespace, Name: serverBinding.Spec.ServerClassRef.Name}, serverClassResource); err != nil { return nil, err @@ -477,7 +477,7 @@ func newEnvironmentFromServerClass(serverBinding *infrav1.ServerBinding) (env *m return env, nil } - env = &metalv1alpha1.Environment{} + env = &metalv1.Environment{} if err := c.Get(context.Background(), types.NamespacedName{Namespace: "", Name: serverClassResource.Spec.EnvironmentRef.Name}, env); err != nil { return nil, err @@ -488,7 +488,7 @@ func newEnvironmentFromServerClass(serverBinding *infrav1.ServerBinding) (env *m return env, nil } -func appendTalosArguments(env *metalv1alpha1.Environment) { +func appendTalosArguments(env *metalv1.Environment) { args := env.Spec.Kernel.Args talosConfigPrefix := talosconstants.KernelParamConfig + "=" @@ -534,16 +534,16 @@ func appendTalosArguments(env *metalv1alpha1.Environment) { } } -func markAsPXEBooted(server *metalv1alpha1.Server) error { +func markAsPXEBooted(server *metalv1.Server) error { patchHelper, err := patch.NewHelper(server, c) if err != nil { return err } - conditions.MarkTrue(server, metalv1alpha1.ConditionPXEBooted) + conditions.MarkTrue(server, metalv1.ConditionPXEBooted) return patchHelper.Patch(context.Background(), server, patch.WithOwnedConditions{ - Conditions: []clusterv1.ConditionType{metalv1alpha1.ConditionPXEBooted}, + Conditions: []clusterv1.ConditionType{metalv1.ConditionPXEBooted}, }) } diff --git a/app/sidero-controller-manager/internal/metadata/metadata_server.go b/app/sidero-controller-manager/internal/metadata/metadata_server.go index 96a4eab9b..086a5a1ae 100644 --- a/app/sidero-controller-manager/internal/metadata/metadata_server.go +++ b/app/sidero-controller-manager/internal/metadata/metadata_server.go @@ -21,8 +21,8 @@ import ( "sigs.k8s.io/cluster-api/util" runtimeclient "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" - metalv1alpha1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + infrav1 "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" ) type errorWithCode struct { @@ -141,7 +141,7 @@ func (m *metadataConfigs) FetchConfig(w http.ResponseWriter, r *http.Request) { // Get the server resource by the UUID that was passed in. // We do this to fetch serverclass and any configPatches in the server resource that we need to handle. - serverObj := &metalv1alpha1.Server{} + serverObj := &metalv1.Server{} err = m.client.Get( ctx, @@ -169,7 +169,7 @@ func (m *metadataConfigs) FetchConfig(w http.ResponseWriter, r *http.Request) { // Given a server object, see if it came from a serverclass (it will have an ownerref) // If so, fetch the serverclass so we can use configPatches from it. - serverClassObj := &metalv1alpha1.ServerClass{} + serverClassObj := &metalv1.ServerClass{} if serverBinding.Spec.ServerClassRef != nil { err = m.client.Get( @@ -245,7 +245,7 @@ func (m *metadataConfigs) FetchConfig(w http.ResponseWriter, r *http.Request) { } // patchConfigs is responsible for applying a set of configPatches to the bootstrap data. -func patchConfigs(decodedData []byte, patches []metalv1alpha1.ConfigPatches) ([]byte, errorWithCode) { +func patchConfigs(decodedData []byte, patches []metalv1.ConfigPatches) ([]byte, errorWithCode) { marshalledPatches, err := json.Marshal(patches) if err != nil { return nil, errorWithCode{http.StatusInternalServerError, fmt.Errorf("failure marshaling config patches from server: %s", err)} @@ -289,7 +289,7 @@ func labelNodes(decodedData []byte, serverName string) ([]byte, errorWithCode) { return nil, errorWithCode{http.StatusInternalServerError, fmt.Errorf("unable to case config")} } - patch := metalv1alpha1.ConfigPatches{ + patch := metalv1.ConfigPatches{ Path: "/machine/kubelet/extraArgs", Op: "replace", } @@ -313,33 +313,33 @@ func labelNodes(decodedData []byte, serverName string) ([]byte, errorWithCode) { patch.Value.Raw = value - return patchConfigs(decodedData, []metalv1alpha1.ConfigPatches{patch}) + return patchConfigs(decodedData, []metalv1.ConfigPatches{patch}) default: return nil, errorWithCode{http.StatusInternalServerError, fmt.Errorf("unknown config type")} } } // findMetalMachineServerBinding is responsible for looking up ServerBinding and MetalMachine. -func (m *metadataConfigs) findMetalMachineServerBinding(ctx context.Context, serverName string) (v1alpha3.MetalMachine, v1alpha3.ServerBinding, errorWithCode) { - var serverBinding v1alpha3.ServerBinding +func (m *metadataConfigs) findMetalMachineServerBinding(ctx context.Context, serverName string) (infrav1.MetalMachine, infrav1.ServerBinding, errorWithCode) { + var serverBinding infrav1.ServerBinding err := m.client.Get(ctx, types.NamespacedName{Name: serverName}, &serverBinding) if err != nil { if apierrors.IsNotFound(err) { - return v1alpha3.MetalMachine{}, v1alpha3.ServerBinding{}, errorWithCode{http.StatusNotFound, fmt.Errorf("server is not allocated (missing serverbinding): %w", err)} + return infrav1.MetalMachine{}, infrav1.ServerBinding{}, errorWithCode{http.StatusNotFound, fmt.Errorf("server is not allocated (missing serverbinding): %w", err)} } - return v1alpha3.MetalMachine{}, v1alpha3.ServerBinding{}, errorWithCode{http.StatusInternalServerError, fmt.Errorf("failure getting server binding: %w", err)} + return infrav1.MetalMachine{}, infrav1.ServerBinding{}, errorWithCode{http.StatusInternalServerError, fmt.Errorf("failure getting server binding: %w", err)} } - var metalMachine v1alpha3.MetalMachine + var metalMachine infrav1.MetalMachine if err = m.client.Get(ctx, types.NamespacedName{ // XXX: where is the namespace in owner refs? Namespace: serverBinding.Spec.MetalMachineRef.Namespace, Name: serverBinding.Spec.MetalMachineRef.Name, }, &metalMachine); err != nil { - return v1alpha3.MetalMachine{}, v1alpha3.ServerBinding{}, errorWithCode{http.StatusInternalServerError, fmt.Errorf("failure getting metalmachine: %w", err)} + return infrav1.MetalMachine{}, infrav1.ServerBinding{}, errorWithCode{http.StatusInternalServerError, fmt.Errorf("failure getting metalmachine: %w", err)} } return metalMachine, serverBinding, errorWithCode{} diff --git a/app/sidero-controller-manager/internal/power/api/api.go b/app/sidero-controller-manager/internal/power/api/api.go index f90ebe602..da5e08a03 100644 --- a/app/sidero-controller-manager/internal/power/api/api.go +++ b/app/sidero-controller-manager/internal/power/api/api.go @@ -14,7 +14,7 @@ import ( "net/http" "time" - metalv1alpha1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" "github.com/talos-systems/sidero/app/sidero-controller-manager/internal/power/metal" ) @@ -24,7 +24,7 @@ type Client struct { } // NewClient returns new API client to manage metal machine. -func NewClient(spec metalv1alpha1.ManagementAPI) (*Client, error) { +func NewClient(spec metalv1.ManagementAPI) (*Client, error) { return &Client{ endpoint: spec.Endpoint, }, nil diff --git a/app/sidero-controller-manager/internal/power/factory.go b/app/sidero-controller-manager/internal/power/factory.go index 7aa3091f5..808415256 100644 --- a/app/sidero-controller-manager/internal/power/factory.go +++ b/app/sidero-controller-manager/internal/power/factory.go @@ -10,7 +10,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" "github.com/talos-systems/sidero/app/sidero-controller-manager/internal/power/api" "github.com/talos-systems/sidero/app/sidero-controller-manager/internal/power/ipmi" "github.com/talos-systems/sidero/app/sidero-controller-manager/internal/power/metal" @@ -18,7 +18,7 @@ import ( ) // NewManagementClient builds ManagementClient from the server spec. -func NewManagementClient(ctx context.Context, client client.Client, spec *v1alpha1.ServerSpec) (metal.ManagementClient, error) { +func NewManagementClient(ctx context.Context, client client.Client, spec *metalv1.ServerSpec) (metal.ManagementClient, error) { switch { case spec.BMC != nil: var err error diff --git a/app/sidero-controller-manager/internal/power/ipmi/ipmi.go b/app/sidero-controller-manager/internal/power/ipmi/ipmi.go index d1dcec343..62216c707 100644 --- a/app/sidero-controller-manager/internal/power/ipmi/ipmi.go +++ b/app/sidero-controller-manager/internal/power/ipmi/ipmi.go @@ -9,7 +9,7 @@ import ( goipmi "github.com/pensando/goipmi" - metalv1alpha1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" "github.com/talos-systems/sidero/app/sidero-controller-manager/internal/power/metal" ) @@ -23,7 +23,7 @@ type Client struct { } // NewClient creates an ipmi client to use. -func NewClient(bmcInfo metalv1alpha1.BMC) (*Client, error) { +func NewClient(bmcInfo metalv1.BMC) (*Client, error) { conn := &goipmi.Connection{ Hostname: bmcInfo.Endpoint, Port: int(bmcInfo.Port), diff --git a/app/sidero-controller-manager/internal/server/server.go b/app/sidero-controller-manager/internal/server/server.go index d3a69aff5..3bad1203e 100644 --- a/app/sidero-controller-manager/internal/server/server.go +++ b/app/sidero-controller-manager/internal/server/server.go @@ -6,6 +6,7 @@ package server import ( "context" + "fmt" "log" "reflect" "time" @@ -25,7 +26,7 @@ import ( "sigs.k8s.io/cluster-api/util/patch" controllerclient "sigs.k8s.io/controller-runtime/pkg/client" - metalv1alpha1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" "github.com/talos-systems/sidero/app/sidero-controller-manager/internal/api" "github.com/talos-systems/sidero/app/sidero-controller-manager/pkg/constants" ) @@ -45,35 +46,25 @@ type server struct { // CreateServer implements api.AgentServer. func (s *server) CreateServer(ctx context.Context, in *api.CreateServerRequest) (*api.CreateServerResponse, error) { - obj := &metalv1alpha1.Server{} + obj := &metalv1.Server{} + uuid := in.GetHardware().GetSystem().GetUuid() - if err := s.c.Get(ctx, types.NamespacedName{Name: in.GetSystemInformation().GetUuid()}, obj); err != nil { + if err := s.c.Get(ctx, types.NamespacedName{Name: uuid}, obj); err != nil { if !apierrors.IsNotFound(err) { return nil, err } - obj = &metalv1alpha1.Server{ + obj = &metalv1.Server{ TypeMeta: metav1.TypeMeta{ Kind: "Server", - APIVersion: metalv1alpha1.GroupVersion.Version, + APIVersion: metalv1.GroupVersion.Version, }, ObjectMeta: metav1.ObjectMeta{ - Name: in.GetSystemInformation().GetUuid(), + Name: uuid, }, - Spec: metalv1alpha1.ServerSpec{ + Spec: metalv1.ServerSpec{ + Hardware: MapHardwareInformation(in.GetHardware()), Hostname: in.GetHostname(), - SystemInformation: &metalv1alpha1.SystemInformation{ - Manufacturer: in.GetSystemInformation().GetManufacturer(), - ProductName: in.GetSystemInformation().GetProductName(), - Version: in.GetSystemInformation().GetVersion(), - SerialNumber: in.GetSystemInformation().GetSerialNumber(), - SKUNumber: in.GetSystemInformation().GetSkuNumber(), - Family: in.GetSystemInformation().GetFamily(), - }, - CPU: &metalv1alpha1.CPUInformation{ - Manufacturer: in.GetCpu().GetManufacturer(), - Version: in.GetCpu().GetVersion(), - }, Accepted: s.autoAccept, }, } @@ -89,7 +80,7 @@ func (s *server) CreateServer(ctx context.Context, in *api.CreateServerRequest) s.recorder.Event(ref, corev1.EventTypeNormal, "Server Registration", "Server auto-registered via API.") - log.Printf("Added %s", in.GetSystemInformation().GetUuid()) + log.Printf("Added %s", uuid) } resp := &api.CreateServerResponse{} @@ -121,7 +112,7 @@ func (s *server) CreateServer(ctx context.Context, in *api.CreateServerRequest) // MarkServerAsWiped implements api.AgentServer. func (s *server) MarkServerAsWiped(ctx context.Context, in *api.MarkServerAsWipedRequest) (*api.MarkServerAsWipedResponse, error) { - obj := &metalv1alpha1.Server{} + obj := &metalv1.Server{} if err := s.c.Get(ctx, types.NamespacedName{Name: in.GetUuid()}, obj); err != nil { return nil, err @@ -134,10 +125,10 @@ func (s *server) MarkServerAsWiped(ctx context.Context, in *api.MarkServerAsWipe obj.Status.IsClean = true - conditions.MarkTrue(obj, metalv1alpha1.ConditionPowerCycle) + conditions.MarkTrue(obj, metalv1.ConditionPowerCycle) if err := patchHelper.Patch(ctx, obj, patch.WithOwnedConditions{ - Conditions: []clusterv1.ConditionType{metalv1alpha1.ConditionPowerCycle}, + Conditions: []clusterv1.ConditionType{metalv1.ConditionPowerCycle}, }); err != nil { return nil, err } @@ -156,7 +147,7 @@ func (s *server) MarkServerAsWiped(ctx context.Context, in *api.MarkServerAsWipe // ReconcileServerAddresses implements api.AgentServer. func (s *server) ReconcileServerAddresses(ctx context.Context, in *api.ReconcileServerAddressesRequest) (*api.ReconcileServerAddressesResponse, error) { - obj := &metalv1alpha1.Server{} + obj := &metalv1.Server{} if err := s.c.Get(ctx, types.NamespacedName{Name: in.GetUuid()}, obj); err != nil { return nil, err @@ -242,7 +233,7 @@ func (s *server) ReconcileServerAddresses(ctx context.Context, in *api.Reconcile // Heartbeat implements api.AgentServer. func (s *server) Heartbeat(ctx context.Context, in *api.HeartbeatRequest) (*api.HeartbeatResponse, error) { - obj := &metalv1alpha1.Server{} + obj := &metalv1.Server{} if err := s.c.Get(ctx, types.NamespacedName{Name: in.GetUuid()}, obj); err != nil { return nil, err @@ -254,11 +245,11 @@ func (s *server) Heartbeat(ctx context.Context, in *api.HeartbeatRequest) (*api. } // remove the condition in case it was already set to make sure LastTransitionTime will be updated - conditions.Delete(obj, metalv1alpha1.ConditionPowerCycle) - conditions.MarkFalse(obj, metalv1alpha1.ConditionPowerCycle, "InProgress", clusterv1.ConditionSeverityInfo, "Server wipe in progress.") + conditions.Delete(obj, metalv1.ConditionPowerCycle) + conditions.MarkFalse(obj, metalv1.ConditionPowerCycle, "InProgress", clusterv1.ConditionSeverityInfo, "Server wipe in progress.") if err := patchHelper.Patch(ctx, obj, patch.WithOwnedConditions{ - Conditions: []clusterv1.ConditionType{metalv1alpha1.ConditionPowerCycle}, + Conditions: []clusterv1.ConditionType{metalv1.ConditionPowerCycle}, }); err != nil { return nil, err } @@ -272,7 +263,7 @@ func (s *server) UpdateBMCInfo(ctx context.Context, in *api.UpdateBMCInfoRequest bmcInfo := in.GetBmcInfo() // Fetch corresponding server - obj := &metalv1alpha1.Server{} + obj := &metalv1.Server{} if err := s.c.Get(ctx, types.NamespacedName{Name: in.GetUuid()}, obj); err != nil { return nil, err @@ -280,7 +271,7 @@ func (s *server) UpdateBMCInfo(ctx context.Context, in *api.UpdateBMCInfoRequest // Create a BMC struct if non-existent if obj.Spec.BMC == nil { - obj.Spec.BMC = &metalv1alpha1.BMC{} + obj.Spec.BMC = &metalv1.BMC{} } // Update bmc info with IP if we've got it. @@ -317,7 +308,7 @@ func (s *server) UpdateBMCInfo(ctx context.Context, in *api.UpdateBMCInfoRequest Namespace: corev1.NamespaceDefault, Name: bmcSecretName, OwnerReferences: []metav1.OwnerReference{ - *metav1.NewControllerRef(obj, metalv1alpha1.GroupVersion.WithKind("Server")), + *metav1.NewControllerRef(obj, metalv1.GroupVersion.WithKind("Server")), }, Labels: map[string]string{ clusterctl.ClusterctlMoveLabelName: "", @@ -343,16 +334,16 @@ func (s *server) UpdateBMCInfo(ctx context.Context, in *api.UpdateBMCInfoRequest } // Update server spec with pointers to endpoint and creds secret - obj.Spec.BMC.UserFrom = &metalv1alpha1.CredentialSource{ - SecretKeyRef: &metalv1alpha1.SecretKeyRef{ + obj.Spec.BMC.UserFrom = &metalv1.CredentialSource{ + SecretKeyRef: &metalv1.SecretKeyRef{ Namespace: corev1.NamespaceDefault, Name: bmcSecretName, Key: "user", }, } - obj.Spec.BMC.PassFrom = &metalv1alpha1.CredentialSource{ - SecretKeyRef: &metalv1alpha1.SecretKeyRef{ + obj.Spec.BMC.PassFrom = &metalv1.CredentialSource{ + SecretKeyRef: &metalv1.SecretKeyRef{ Namespace: corev1.NamespaceDefault, Name: bmcSecretName, Key: "pass", @@ -400,3 +391,87 @@ func CreateServer(c controllerclient.Client, recorder record.EventRecorder, sche return s } + +func MapHardwareInformation(hw *api.HardwareInformation) *metalv1.HardwareInformation { + processors := make([]*metalv1.Processor, hw.GetCompute().GetProcessorCount()) + for i, v := range hw.GetCompute().GetProcessors() { + processors[i] = &metalv1.Processor{ + Manufacturer: v.GetManufacturer(), + ProductName: v.GetProductName(), + SerialNumber: v.GetSerialNumber(), + Speed: v.GetSpeed(), + CoreCount: v.GetCoreCount(), + ThreadCount: v.GetThreadCount(), + } + } + + memoryModules := make([]*metalv1.MemoryModule, hw.GetMemory().GetModuleCount()) + for i, v := range hw.GetMemory().GetModules() { + memoryModules[i] = &metalv1.MemoryModule{ + Manufacturer: v.GetManufacturer(), + ProductName: v.GetProductName(), + SerialNumber: v.GetSerialNumber(), + Type: v.GetType(), + Size: v.GetSize(), + Speed: v.GetSpeed(), + } + } + + storageDevices := make([]*metalv1.StorageDevice, hw.GetStorage().GetDeviceCount()) + for i, v := range hw.GetStorage().GetDevices() { + storageDevices[i] = &metalv1.StorageDevice{ + Type: v.GetType().String(), + Size: v.GetSize(), + Model: v.GetModel(), + Serial: v.GetSerial(), + Name: v.GetName(), + DeviceName: v.GetDeviceName(), + UUID: v.GetUuid(), + WWID: v.GetWwid(), + } + } + + networkInterfaces := make([]*metalv1.NetworkInterface, hw.GetNetwork().GetInterfaceCount()) + for i, v := range hw.GetNetwork().GetInterfaces() { + networkInterfaces[i] = &metalv1.NetworkInterface{ + Index: v.GetIndex(), + Name: v.GetName(), + Flags: v.GetFlags(), + MTU: v.GetMtu(), + MAC: v.GetMac(), + Addresses: v.GetAddresses(), + } + } + + return &metalv1.HardwareInformation{ + System: &metalv1.SystemInformation{ + Uuid: hw.GetSystem().GetUuid(), + Manufacturer: hw.GetSystem().GetManufacturer(), + ProductName: hw.GetSystem().GetProductName(), + Version: hw.GetSystem().GetVersion(), + SerialNumber: hw.GetSystem().GetSerialNumber(), + SKUNumber: hw.GetSystem().GetSkuNumber(), + Family: hw.GetSystem().GetFamily(), + }, + Compute: &metalv1.ComputeInformation{ + TotalCoreCount: hw.GetCompute().GetTotalCoreCount(), + TotalThreadCount: hw.GetCompute().GetTotalThreadCount(), + ProcessorCount: hw.GetCompute().GetProcessorCount(), + Processors: processors, + }, + Memory: &metalv1.MemoryInformation{ + TotalSize: fmt.Sprintf("%d GB", hw.GetMemory().GetTotalSize()/1024), + ModuleCount: hw.GetMemory().GetModuleCount(), + Modules: memoryModules, + }, + Storage: &metalv1.StorageInformation{ + TotalSize: fmt.Sprintf("%d GB", hw.GetStorage().GetTotalSize()/1024/1024/1024), + DeviceCount: hw.GetStorage().GetDeviceCount(), + Devices: storageDevices, + }, + Network: &metalv1.NetworkInformation{ + InterfaceCount: hw.GetNetwork().GetInterfaceCount(), + Interfaces: networkInterfaces, + }, + } +} diff --git a/app/sidero-controller-manager/main.go b/app/sidero-controller-manager/main.go index 524d05e6e..ea9bd649a 100644 --- a/app/sidero-controller-manager/main.go +++ b/app/sidero-controller-manager/main.go @@ -29,8 +29,9 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/manager" - infrav1 "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" + infrav1alpha3 "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" metalv1alpha1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + metalv1alpha2 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" "github.com/talos-systems/sidero/app/sidero-controller-manager/controllers" "github.com/talos-systems/sidero/app/sidero-controller-manager/internal/ipxe" "github.com/talos-systems/sidero/app/sidero-controller-manager/internal/metadata" @@ -64,7 +65,8 @@ func init() { _ = capi.AddToScheme(scheme) _ = metalv1alpha1.AddToScheme(scheme) - _ = infrav1.AddToScheme(scheme) + _ = metalv1alpha2.AddToScheme(scheme) + _ = infrav1alpha3.AddToScheme(scheme) // +kubebuilder:scaffold:scheme } diff --git a/config/kustomization.yaml b/config/kustomization.yaml index 2813e7222..0c472357f 100644 --- a/config/kustomization.yaml +++ b/config/kustomization.yaml @@ -3,7 +3,7 @@ resources: bases: - ../app/caps-controller-manager/config/default - - ../app/sidero-controller-manager/config + - ../app/sidero-controller-manager/config/default commonLabels: app: sidero diff --git a/go.mod b/go.mod index e60a9b7f2..968bcc43f 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/talos-systems/go-kmsg v0.1.1 github.com/talos-systems/go-procfs v0.1.0 github.com/talos-systems/go-retry v0.3.1 - github.com/talos-systems/go-smbios v0.1.1 + github.com/talos-systems/go-smbios v0.1.2-0.20220202124743-3f1e775b7e3e github.com/talos-systems/grpc-proxy v0.2.0 github.com/talos-systems/net v0.3.1 github.com/talos-systems/siderolink v0.1.1-0.20211130121818-9902ad2774f0 diff --git a/go.sum b/go.sum index 8af46ebad..0d42e7ea6 100644 --- a/go.sum +++ b/go.sum @@ -678,8 +678,8 @@ github.com/talos-systems/go-procfs v0.1.0/go.mod h1:ATyUGFQIW8OnbnmvqefZWVPgL9g+ github.com/talos-systems/go-retry v0.1.1-0.20201113203059-8c63d290a688/go.mod h1:HiXQqyVStZ35uSY/MTLWVvQVmC3lIW2MS5VdDaMtoKM= github.com/talos-systems/go-retry v0.3.1 h1:GjjyHB8i1CJpb1O5qYPMljq74cRQ5uiDoyMaWddA5FA= github.com/talos-systems/go-retry v0.3.1/go.mod h1:HiXQqyVStZ35uSY/MTLWVvQVmC3lIW2MS5VdDaMtoKM= -github.com/talos-systems/go-smbios v0.1.1 h1:Au6obB/Pp0i0JHhvPlzONk5aoNseosO2BUsmvWWi7y8= -github.com/talos-systems/go-smbios v0.1.1/go.mod h1:vk76naUSZaWE8Z95wbDn51FgH0goECM4oK3KY2hYSMU= +github.com/talos-systems/go-smbios v0.1.2-0.20220202124743-3f1e775b7e3e h1:z2ig8zuE00kbVhyWmTQdDWbDIN5HnCKaouyjiTHCMxs= +github.com/talos-systems/go-smbios v0.1.2-0.20220202124743-3f1e775b7e3e/go.mod h1:vk76naUSZaWE8Z95wbDn51FgH0goECM4oK3KY2hYSMU= github.com/talos-systems/goipmi v0.0.0-20211214143420-35f956689e67 h1:1MyiKkPFn0OnpOnmMMVlvFtmeUB/HIRzDVL66DQBOXg= github.com/talos-systems/goipmi v0.0.0-20211214143420-35f956689e67/go.mod h1:Vr1Oadtcem03hG2RUT/dpSQS5md9d6rJ9nA0lUBC91Q= github.com/talos-systems/grpc-proxy v0.2.0 h1:DN75bLfaW4xfhq0r0mwFRnfGhSB+HPhK1LNzuMEs9Pw= diff --git a/internal/client/client.go b/internal/client/client.go index 378634310..ef4ea218b 100644 --- a/internal/client/client.go +++ b/internal/client/client.go @@ -13,8 +13,8 @@ import ( capi "sigs.k8s.io/cluster-api/api/v1beta1" "sigs.k8s.io/controller-runtime/pkg/client" - caps "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" - scm "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + infrav1 "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" ) // NewClient is responsible for creating a controller-runtime k8s client with all schemas. @@ -48,11 +48,11 @@ func NewClient(kubeconfig *string) (client.Client, error) { return nil, err } - if err = caps.AddToScheme(scheme); err != nil { + if err = infrav1.AddToScheme(scheme); err != nil { return nil, err } - if err = scm.AddToScheme(scheme); err != nil { + if err = metalv1.AddToScheme(scheme); err != nil { return nil, err } diff --git a/sfyra/go.sum b/sfyra/go.sum index 798b0f8aa..dd0d0e997 100644 --- a/sfyra/go.sum +++ b/sfyra/go.sum @@ -1124,6 +1124,7 @@ github.com/talos-systems/go-retry v0.1.1-0.20201113203059-8c63d290a688/go.mod h1 github.com/talos-systems/go-retry v0.3.1 h1:GjjyHB8i1CJpb1O5qYPMljq74cRQ5uiDoyMaWddA5FA= github.com/talos-systems/go-retry v0.3.1/go.mod h1:HiXQqyVStZ35uSY/MTLWVvQVmC3lIW2MS5VdDaMtoKM= github.com/talos-systems/go-smbios v0.1.1/go.mod h1:vk76naUSZaWE8Z95wbDn51FgH0goECM4oK3KY2hYSMU= +github.com/talos-systems/go-smbios v0.1.2-0.20220202124743-3f1e775b7e3e/go.mod h1:vk76naUSZaWE8Z95wbDn51FgH0goECM4oK3KY2hYSMU= github.com/talos-systems/grpc-proxy v0.2.0/go.mod h1:sm97Vc/z2cok3pu6ruNeszQej4KDxFrDgfWs4C1mtC4= github.com/talos-systems/net v0.3.0/go.mod h1:VreSAyRmxMtqussAHSKMKkJQa1YwBTSVfkmE4Jydam4= github.com/talos-systems/net v0.3.1-0.20211112122313-0abe5bdae8f8/go.mod h1:zhcGixNJz9dgwFiUwc7gkkAqdVqXagU1SNNoIVXYKGo= diff --git a/sfyra/pkg/capi/capi.go b/sfyra/pkg/capi/capi.go index 71074a4c4..164f0b069 100644 --- a/sfyra/pkg/capi/capi.go +++ b/sfyra/pkg/capi/capi.go @@ -123,6 +123,7 @@ func (clusterAPI *Manager) Install(ctx context.Context) error { // set template environment variables os.Setenv("SIDERO_CONTROLLER_MANAGER_HOST_NETWORK", "true") + os.Setenv("SIDERO_CONTROLLER_MANAGER_DEPLOYMENT_STRATEGY", "Recreate") os.Setenv("SIDERO_CONTROLLER_MANAGER_API_ENDPOINT", clusterAPI.cluster.SideroComponentsIP().String()) os.Setenv("SIDERO_CONTROLLER_MANAGER_SERVER_REBOOT_TIMEOUT", "30s") // wiping/reboot is fast in the test environment os.Setenv("SIDERO_CONTROLLER_MANAGER_TEST_POWER_EXPLICIT_FAILURE", fmt.Sprintf("%f", clusterAPI.options.PowerSimulatedExplicitFailureProb)) diff --git a/sfyra/pkg/capi/cluster.go b/sfyra/pkg/capi/cluster.go index dd4b68931..02df85ad1 100644 --- a/sfyra/pkg/capi/cluster.go +++ b/sfyra/pkg/capi/cluster.go @@ -27,8 +27,8 @@ import ( capiv1 "sigs.k8s.io/cluster-api/api/v1beta1" runtimeclient "sigs.k8s.io/controller-runtime/pkg/client" - sidero "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" - metal "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + infrav1 "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" ) // Cluster attaches to the provisioned CAPI cluster and provides talos.Cluster. @@ -100,7 +100,7 @@ func NewCluster(ctx context.Context, metalClient runtimeclient.Reader, clusterNa continue } - var metalMachine sidero.MetalMachine + var metalMachine infrav1.MetalMachine if err = metalClient.Get(ctx, types.NamespacedName{Namespace: machine.Spec.InfrastructureRef.Namespace, Name: machine.Spec.InfrastructureRef.Name}, @@ -116,7 +116,7 @@ func NewCluster(ctx context.Context, metalClient runtimeclient.Reader, clusterNa continue } - var server metal.Server + var server metalv1.Server if err := metalClient.Get(ctx, types.NamespacedName{Namespace: metalMachine.Spec.ServerRef.Namespace, Name: metalMachine.Spec.ServerRef.Name}, &server); err != nil { return nil, err diff --git a/sfyra/pkg/capi/metalclient.go b/sfyra/pkg/capi/metalclient.go index 7c67d65f8..e2ee8a7ab 100644 --- a/sfyra/pkg/capi/metalclient.go +++ b/sfyra/pkg/capi/metalclient.go @@ -12,8 +12,8 @@ import ( capiv1 "sigs.k8s.io/cluster-api/api/v1beta1" runtimeclient "sigs.k8s.io/controller-runtime/pkg/client" - sidero "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" - metal "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + infrav1 "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" ) // GetMetalClient builds k8s client with schemes required to access all the CAPI/Sidero/Talos components. @@ -32,11 +32,11 @@ func GetMetalClient(config *rest.Config) (runtimeclient.Client, error) { return nil, err } - if err := sidero.AddToScheme(scheme); err != nil { + if err := infrav1.AddToScheme(scheme); err != nil { return nil, err } - if err := metal.AddToScheme(scheme); err != nil { + if err := metalv1.AddToScheme(scheme); err != nil { return nil, err } diff --git a/sfyra/pkg/constants/constants.go b/sfyra/pkg/constants/constants.go index f11afb29b..2c9e2eb4d 100644 --- a/sfyra/pkg/constants/constants.go +++ b/sfyra/pkg/constants/constants.go @@ -17,4 +17,4 @@ const MTU = 1500 const BootstrapMaster = "bootstrap-master" // SideroAPIVersion is a string we need for creating Sidero resources. -const SideroAPIVersion = "metal.sidero.dev/v1alpha1" +const SideroAPIVersion = "metal.sidero.dev/v1alpha2" diff --git a/sfyra/pkg/loadbalancer/loadbalancer.go b/sfyra/pkg/loadbalancer/loadbalancer.go index b27ec3861..3c5fd8384 100644 --- a/sfyra/pkg/loadbalancer/loadbalancer.go +++ b/sfyra/pkg/loadbalancer/loadbalancer.go @@ -25,8 +25,8 @@ import ( capiv1 "sigs.k8s.io/cluster-api/api/v1beta1" "sigs.k8s.io/controller-runtime/pkg/client" - sidero "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" - metal "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + infrav1 "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" ) // ControlPlane implements dynamic loadbalancer for the control plane. @@ -153,13 +153,13 @@ func (cp *ControlPlane) reconcile() error { var upstreams []string for _, machine := range machines.Items { - var metalMachine sidero.MetalMachine + var metalMachine infrav1.MetalMachine if err := cp.client.Get(cp.ctx, types.NamespacedName{Namespace: machine.Spec.InfrastructureRef.Namespace, Name: machine.Spec.InfrastructureRef.Name}, &metalMachine); err != nil { continue } - var server metal.Server + var server metalv1.Server if metalMachine.Spec.ServerRef == nil { continue diff --git a/sfyra/pkg/tests/compatibility.go b/sfyra/pkg/tests/compatibility.go index dbb45b189..72c93432e 100644 --- a/sfyra/pkg/tests/compatibility.go +++ b/sfyra/pkg/tests/compatibility.go @@ -23,7 +23,7 @@ import ( "github.com/talos-systems/go-retry/retry" "github.com/talos-systems/talos/pkg/machinery/kernel" - "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" "github.com/talos-systems/sidero/sfyra/pkg/capi" "github.com/talos-systems/sidero/sfyra/pkg/constants" "github.com/talos-systems/sidero/sfyra/pkg/talos" @@ -42,7 +42,7 @@ func TestCompatibilityCluster(ctx context.Context, metalClient client.Client, cl t.Skip("--prev-talos-release is not set, skipped compatibility check") } - var environment v1alpha1.Environment + var environment metalv1.Environment envName := fmt.Sprintf("talos-%s", strings.ReplaceAll(talosRelease, ".", "-")) @@ -82,11 +82,13 @@ func TestCompatibilityCluster(ctx context.Context, metalClient client.Client, cl })) serverClassName := envName - classSpec := v1alpha1.ServerClassSpec{ - Qualifiers: v1alpha1.Qualifiers{ - CPU: []v1alpha1.CPUInformation{ + classSpec := metalv1.ServerClassSpec{ + Qualifiers: metalv1.Qualifiers{ + Hardware: []metalv1.HardwareInformation{ { - Manufacturer: "QEMU", + System: &metalv1.SystemInformation{ + Manufacturer: "QEMU", + }, }, }, }, diff --git a/sfyra/pkg/tests/environment.go b/sfyra/pkg/tests/environment.go index cd9dcbcf4..087ac51d1 100644 --- a/sfyra/pkg/tests/environment.go +++ b/sfyra/pkg/tests/environment.go @@ -18,18 +18,33 @@ import ( "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" "github.com/talos-systems/sidero/sfyra/pkg/constants" "github.com/talos-systems/sidero/sfyra/pkg/talos" ) const environmentName = "sfyra" +func isEnvironmentReady(env *metalv1.Environment) bool { + assetURLs := map[string]struct{}{ + env.Spec.Kernel.URL: {}, + env.Spec.Initrd.URL: {}, + } + + for _, cond := range env.Status.Conditions { + if cond.Status == "True" && cond.Type == "Ready" { + delete(assetURLs, cond.URL) + } + } + + return len(assetURLs) == 0 +} + // TestEnvironmentDefault verifies environment "default". func TestEnvironmentDefault(ctx context.Context, metalClient client.Client, cluster talos.Cluster, kernelURL, initrdURL string) TestFunc { return func(t *testing.T) { - var environment v1alpha1.Environment - err := metalClient.Get(ctx, types.NamespacedName{Name: v1alpha1.EnvironmentDefault}, &environment) + var environment metalv1.Environment + err := metalClient.Get(ctx, types.NamespacedName{Name: metalv1.EnvironmentDefault}, &environment) require.NoError(t, err) assert.True(t, environment.IsReady()) @@ -37,9 +52,9 @@ func TestEnvironmentDefault(ctx context.Context, metalClient client.Client, clus err = metalClient.Delete(ctx, &environment) require.NoError(t, err) - environment = v1alpha1.Environment{} + environment = metalv1.Environment{} err = retry.Constant(60 * time.Second).Retry(func() error { - if err := metalClient.Get(ctx, types.NamespacedName{Name: v1alpha1.EnvironmentDefault}, &environment); err != nil { + if err := metalClient.Get(ctx, types.NamespacedName{Name: metalv1.EnvironmentDefault}, &environment); err != nil { if apierrors.IsNotFound(err) { return retry.ExpectedError(err) } @@ -60,7 +75,7 @@ func TestEnvironmentDefault(ctx context.Context, metalClient client.Client, clus // TestEnvironmentCreate verifies environment creation. func TestEnvironmentCreate(ctx context.Context, metalClient client.Client, cluster talos.Cluster, kernelURL, initrdURL string) TestFunc { return func(t *testing.T) { - var environment v1alpha1.Environment + var environment metalv1.Environment if err := metalClient.Get(ctx, types.NamespacedName{Name: environmentName}, &environment); err != nil { if !apierrors.IsNotFound(err) { diff --git a/sfyra/pkg/tests/match.go b/sfyra/pkg/tests/match.go index 63fcc6d28..d9c6f57ed 100644 --- a/sfyra/pkg/tests/match.go +++ b/sfyra/pkg/tests/match.go @@ -13,7 +13,7 @@ import ( capiv1 "sigs.k8s.io/cluster-api/api/v1beta1" "sigs.k8s.io/controller-runtime/pkg/client" - metal "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" ) // TestMatchServersMetalMachines verifies that number of metal machines and servers match. @@ -23,7 +23,7 @@ func TestMatchServersMetalMachines(ctx context.Context, metalClient client.Clien require.NoError(t, metalClient.List(ctx, &machines)) - var servers metal.ServerList + var servers metalv1.ServerList require.NoError(t, metalClient.List(ctx, &servers)) diff --git a/sfyra/pkg/tests/reconcile.go b/sfyra/pkg/tests/reconcile.go index 9387e02a2..27329329a 100644 --- a/sfyra/pkg/tests/reconcile.go +++ b/sfyra/pkg/tests/reconcile.go @@ -19,8 +19,8 @@ import ( "sigs.k8s.io/cluster-api/util/patch" "sigs.k8s.io/controller-runtime/pkg/client" - sidero "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" - metal "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + infrav1 "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" ) // TestMachineDeploymentReconcile verifies that machine deployment can reconcile delete machines. @@ -95,7 +95,7 @@ func TestMachineDeploymentReconcile(ctx context.Context, metalClient client.Clie // TestServerBindingReconcile verifies that server binding controller can reconcile missing ServerBindings. func TestServerBindingReconcile(ctx context.Context, metalClient client.Client) TestFunc { return func(t *testing.T) { - var serverBindingList sidero.ServerBindingList + var serverBindingList infrav1.ServerBindingList require.NoError(t, metalClient.List(ctx, &serverBindingList)) @@ -112,7 +112,7 @@ func TestServerBindingReconcile(ctx context.Context, metalClient client.Client) start := time.Now() for time.Since(start) < time.Minute { - var server metal.Server + var server metalv1.Server require.NoError(t, metalClient.Get(ctx, types.NamespacedName{Name: serverBindingToDelete.Name}, &server)) @@ -120,7 +120,7 @@ func TestServerBindingReconcile(ctx context.Context, metalClient client.Client) } // server binding should have been re-created - var serverBinding sidero.ServerBinding + var serverBinding infrav1.ServerBinding require.NoError(t, metalClient.Get(ctx, types.NamespacedName{Name: serverBindingToDelete.Name}, &serverBinding)) @@ -141,7 +141,7 @@ func TestServerBindingReconcile(ctx context.Context, metalClient client.Client) // ref wasn't set. func TestMetalMachineServerRefReconcile(ctx context.Context, metalClient client.Client) TestFunc { return func(t *testing.T) { - var serverBindingList sidero.ServerBindingList + var serverBindingList infrav1.ServerBindingList require.NoError(t, metalClient.List(ctx, &serverBindingList)) @@ -153,7 +153,7 @@ func TestMetalMachineServerRefReconcile(ctx context.Context, metalClient client. serverBinding := serverBindingList.Items[0] // get matching metalmachine - var metalMachine sidero.MetalMachine + var metalMachine infrav1.MetalMachine require.NoError(t, metalClient.Get(ctx, types.NamespacedName{Namespace: serverBinding.Spec.MetalMachineRef.Namespace, Name: serverBinding.Spec.MetalMachineRef.Name}, &metalMachine)) diff --git a/sfyra/pkg/tests/reset.go b/sfyra/pkg/tests/reset.go index 68eeac88f..4471914ff 100644 --- a/sfyra/pkg/tests/reset.go +++ b/sfyra/pkg/tests/reset.go @@ -15,14 +15,14 @@ import ( "k8s.io/apimachinery/pkg/labels" "sigs.k8s.io/controller-runtime/pkg/client" - metal "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" - sidero "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + infrav1 "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" ) // TestServerReset verifies that all the servers got reset. func TestServerReset(ctx context.Context, metalClient client.Client) TestFunc { return func(t *testing.T) { - var machines metal.MetalMachineList + var machines infrav1.MetalMachineList labelSelector, err := labels.Parse("cluster.x-k8s.io/cluster-name=management-cluster,cluster.x-k8s.io/deployment-name=management-cluster-workers") require.NoError(t, err) @@ -44,7 +44,7 @@ func TestServerReset(ctx context.Context, metalClient client.Client) TestFunc { require.NoError(t, err) err = retry.Constant(5*time.Minute, retry.WithUnits(10*time.Second)).Retry(func() error { - var servers sidero.ServerList + var servers metalv1.ServerList err = metalClient.List(ctx, &servers) if err != nil { diff --git a/sfyra/pkg/tests/server.go b/sfyra/pkg/tests/server.go index c21467d05..d4c80d83b 100644 --- a/sfyra/pkg/tests/server.go +++ b/sfyra/pkg/tests/server.go @@ -29,8 +29,8 @@ import ( "sigs.k8s.io/cluster-api/util/patch" "sigs.k8s.io/controller-runtime/pkg/client" - metalv1 "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" - "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + infrav1 "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" "github.com/talos-systems/sidero/sfyra/pkg/capi" "github.com/talos-systems/sidero/sfyra/pkg/constants" "github.com/talos-systems/sidero/sfyra/pkg/talos" @@ -42,11 +42,11 @@ func TestServerRegistration(ctx context.Context, metalClient client.Client, vmSe return func(t *testing.T) { numNodes := len(vmSet.Nodes()) - var servers *v1alpha1.ServerList + var servers *metalv1.ServerList // wait for all the servers to be registered require.NoError(t, retry.Constant(5*time.Minute, retry.WithUnits(10*time.Second)).Retry(func() error { - servers = &v1alpha1.ServerList{} + servers = &metalv1.ServerList{} if err := metalClient.List(ctx, servers); err != nil { return err @@ -101,14 +101,14 @@ func TestServerMgmtAPI(ctx context.Context, metalClient client.Client, vmSet *vm bridgeIP := vmSet.BridgeIP() for _, vm := range vmSet.Nodes() { - server := v1alpha1.Server{} + server := metalv1.Server{} require.NoError(t, metalClient.Get(ctx, types.NamespacedName{Name: vm.UUID.String()}, &server)) patchHelper, err := patch.NewHelper(&server, metalClient) require.NoError(t, err) - server.Spec.ManagementAPI = &v1alpha1.ManagementAPI{ + server.Spec.ManagementAPI = &metalv1.ManagementAPI{ Endpoint: net.JoinHostPort(bridgeIP.String(), strconv.Itoa(vm.APIPort)), } @@ -120,7 +120,7 @@ func TestServerMgmtAPI(ctx context.Context, metalClient client.Client, vmSet *vm // TestServerPatch patches all the servers for the config. func TestServerPatch(ctx context.Context, metalClient client.Client, registryMirrors []string) TestFunc { return func(t *testing.T) { - servers := &v1alpha1.ServerList{} + servers := &metalv1.ServerList{} require.NoError(t, metalClient.List(ctx, servers)) @@ -165,14 +165,14 @@ func TestServerPatch(ctx context.Context, metalClient client.Client, registryMir patchHelper, err := patch.NewHelper(&server, metalClient) require.NoError(t, err) - server.Spec.ConfigPatches = append(server.Spec.ConfigPatches, v1alpha1.ConfigPatches{ + server.Spec.ConfigPatches = append(server.Spec.ConfigPatches, metalv1.ConfigPatches{ Op: "replace", Path: "/machine/install", Value: apiextensions.JSON{Raw: installPatch}, }) if mirrorsPatch != nil { - server.Spec.ConfigPatches = append(server.Spec.ConfigPatches, v1alpha1.ConfigPatches{ + server.Spec.ConfigPatches = append(server.Spec.ConfigPatches, metalv1.ConfigPatches{ Op: "add", Path: "/machine/registries", Value: apiextensions.JSON{Raw: mirrorsPatch}, @@ -190,9 +190,15 @@ func TestServerAcceptance(ctx context.Context, metalClient client.Client, vmSet const numDummies = 3 // create dummy servers to test with - dummySpec := v1alpha1.ServerSpec{ - CPU: &v1alpha1.CPUInformation{ - Manufacturer: "DummyCPU", + dummySpec := metalv1.ServerSpec{ + Hardware: &metalv1.HardwareInformation{ + Compute: &metalv1.ComputeInformation{ + Processors: []*metalv1.Processor{ + { + Manufacturer: "DummyCPU", + }, + }, + }, }, } @@ -202,7 +208,7 @@ func TestServerAcceptance(ctx context.Context, metalClient client.Client, vmSet require.NoError(t, err) } - dummyServers := &v1alpha1.ServerList{} + dummyServers := &metalv1.ServerList{} labelSelector, err := labels.Parse("dummy-server=") require.NoError(t, err) @@ -222,7 +228,7 @@ func TestServerAcceptance(ctx context.Context, metalClient client.Client, vmSet })) // verify servers originally registered as non-accepted - acceptedServers := []v1alpha1.Server{} + acceptedServers := []metalv1.Server{} for _, server := range dummyServers.Items { if server.Spec.Accepted { @@ -246,7 +252,7 @@ func TestServerAcceptance(ctx context.Context, metalClient client.Client, vmSet // verify all servers are now accepted require.NoError(t, metalClient.List(ctx, dummyServers, client.MatchingLabelsSelector{Selector: labelSelector})) - acceptedServers = []v1alpha1.Server{} + acceptedServers = []metalv1.Server{} for _, server := range dummyServers.Items { if server.Spec.Accepted { @@ -270,9 +276,15 @@ func TestServerCordoned(ctx context.Context, metalClient client.Client, vmSet *v const numDummies = 3 // create dummy servers to test with - dummySpec := v1alpha1.ServerSpec{ - CPU: &v1alpha1.CPUInformation{ - Manufacturer: "DummyManufacturer", + dummySpec := metalv1.ServerSpec{ + Hardware: &metalv1.HardwareInformation{ + Compute: &metalv1.ComputeInformation{ + Processors: []*metalv1.Processor{ + { + Manufacturer: "DummyManufacturer", + }, + }, + }, }, } @@ -282,7 +294,7 @@ func TestServerCordoned(ctx context.Context, metalClient client.Client, vmSet *v require.NoError(t, err) } - dummyServers := &v1alpha1.ServerList{} + dummyServers := &metalv1.ServerList{} labelSelector, err := labels.Parse("dummy-server=") require.NoError(t, err) @@ -310,8 +322,8 @@ func TestServerCordoned(ctx context.Context, metalClient client.Client, vmSet *v // verify that all servers shows up as available in `any` serverclass require.NoError(t, retry.Constant(30*time.Second, retry.WithUnits(5*time.Second)).Retry(func() error { - var serverClass v1alpha1.ServerClass - err := metalClient.Get(ctx, types.NamespacedName{Name: v1alpha1.ServerClassAny}, &serverClass) + var serverClass metalv1.ServerClass + err := metalClient.Get(ctx, types.NamespacedName{Name: metalv1.ServerClassAny}, &serverClass) if err != nil { return err } @@ -327,7 +339,7 @@ func TestServerCordoned(ctx context.Context, metalClient client.Client, vmSet *v // // cordon a single server and marked as paused serverName := dummyServers.Items[0].Name - var server v1alpha1.Server + var server metalv1.Server require.NoError(t, metalClient.Get(ctx, types.NamespacedName{Name: serverName}, &server)) patchHelper, err := patch.NewHelper(&server, metalClient) @@ -338,8 +350,8 @@ func TestServerCordoned(ctx context.Context, metalClient client.Client, vmSet *v require.NoError(t, patchHelper.Patch(ctx, &server)) require.NoError(t, retry.Constant(30*time.Second, retry.WithUnits(5*time.Second)).Retry(func() error { - var serverClass v1alpha1.ServerClass - err := metalClient.Get(ctx, types.NamespacedName{Name: v1alpha1.ServerClassAny}, &serverClass) + var serverClass metalv1.ServerClass + err := metalClient.Get(ctx, types.NamespacedName{Name: metalv1.ServerClassAny}, &serverClass) if err != nil { return err } @@ -353,7 +365,7 @@ func TestServerCordoned(ctx context.Context, metalClient client.Client, vmSet *v })) // patch the server and marked as not cordoned - var pausedServer v1alpha1.Server + var pausedServer metalv1.Server require.NoError(t, metalClient.Get(ctx, types.NamespacedName{Name: serverName}, &pausedServer)) patchHelperPausedServer, err := patch.NewHelper(&pausedServer, metalClient) @@ -364,8 +376,8 @@ func TestServerCordoned(ctx context.Context, metalClient client.Client, vmSet *v require.NoError(t, patchHelperPausedServer.Patch(ctx, &pausedServer)) require.NoError(t, retry.Constant(30*time.Second, retry.WithUnits(5*time.Second)).Retry(func() error { - var serverClass v1alpha1.ServerClass - err := metalClient.Get(ctx, types.NamespacedName{Name: v1alpha1.ServerClassAny}, &serverClass) + var serverClass metalv1.ServerClass + err := metalClient.Get(ctx, types.NamespacedName{Name: metalv1.ServerClassAny}, &serverClass) if err != nil { return err } @@ -383,12 +395,12 @@ func TestServerCordoned(ctx context.Context, metalClient client.Client, vmSet *v // TestServerResetOnAcceptance tests that servers are reset when accepted. func TestServerResetOnAcceptance(ctx context.Context, metalClient client.Client) TestFunc { return func(t *testing.T) { - serverList := &v1alpha1.ServerList{} + serverList := &metalv1.ServerList{} err := metalClient.List(ctx, serverList) require.NoError(t, err) - servers := []v1alpha1.Server{} + servers := []metalv1.Server{} for _, server := range serverList.Items { server := server @@ -412,7 +424,7 @@ func TestServerResetOnAcceptance(ctx context.Context, metalClient client.Client) require.NoError(t, retry.Constant(5*time.Minute, retry.WithUnits(10*time.Second)).Retry(func() error { for _, server := range servers { - var s v1alpha1.Server + var s metalv1.Server if err := metalClient.Get(ctx, types.NamespacedName{Name: server.Name, Namespace: server.Namespace}, &s); err != nil { return err @@ -434,7 +446,7 @@ func TestServerResetOnAcceptance(ctx context.Context, metalClient client.Client) func TestServersReady(ctx context.Context, metalClient client.Client) TestFunc { return func(t *testing.T) { require.NoError(t, retry.Constant(time.Minute, retry.WithUnits(10*time.Second)).Retry(func() error { - servers := v1alpha1.ServerList{} + servers := metalv1.ServerList{} if err := metalClient.List(ctx, &servers); err != nil { return err @@ -455,7 +467,7 @@ func TestServersReady(ctx context.Context, metalClient client.Client) TestFunc { func TestServersDiscoveredIPs(ctx context.Context, metalClient client.Client) TestFunc { return func(t *testing.T) { require.NoError(t, retry.Constant(time.Minute, retry.WithUnits(10*time.Second)).Retry(func() error { - servers := v1alpha1.ServerList{} + servers := metalv1.ServerList{} if err := metalClient.List(ctx, &servers); err != nil { return err @@ -492,18 +504,20 @@ func TestServerPXEBoot(ctx context.Context, metalClient client.Client, cluster t return func(t *testing.T) { pxeTestServerClass := "pxe-test-server" - classSpec := v1alpha1.ServerClassSpec{ - Qualifiers: v1alpha1.Qualifiers{ - CPU: []v1alpha1.CPUInformation{ + classSpec := metalv1.ServerClassSpec{ + Qualifiers: metalv1.Qualifiers{ + Hardware: []metalv1.HardwareInformation{ { - Manufacturer: "QEMU", + System: &metalv1.SystemInformation{ + Manufacturer: "QEMU", + }, }, }, }, EnvironmentRef: &v1.ObjectReference{ Name: environmentName, }, - ConfigPatches: []v1alpha1.ConfigPatches{ + ConfigPatches: []metalv1.ConfigPatches{ { Op: "add", Path: "/fake", @@ -518,7 +532,7 @@ func TestServerPXEBoot(ctx context.Context, metalClient client.Client, cluster t loadbalancer := createCluster(ctx, t, metalClient, cluster, vmSet, capiManager, pxeTestClusterName, pxeTestServerClass, pxeTestClusterLBPort, 1, 0, talosRelease, kubernetesVersion) retry.Constant(time.Minute, retry.WithUnits(10*time.Second)).Retry(func() error { - var machines metalv1.MetalMachineList + var machines infrav1.MetalMachineList labelSelector, err := labels.Parse(fmt.Sprintf("cluster.x-k8s.io/cluster-name=%s", pxeTestClusterName)) require.NoError(t, err) @@ -532,7 +546,7 @@ func TestServerPXEBoot(ctx context.Context, metalClient client.Client, cluster t return retry.ExpectedErrorf("no metal machines detected yet") } - if !conditions.IsFalse(&machines.Items[0], metalv1.TalosConfigLoadedCondition) || !conditions.IsFalse(&machines.Items[0], metalv1.TalosConfigValidatedCondition) { + if !conditions.IsFalse(&machines.Items[0], infrav1.TalosConfigLoadedCondition) || !conditions.IsFalse(&machines.Items[0], infrav1.TalosConfigValidatedCondition) { return retry.ExpectedErrorf("the machine doesn't have any config failure conditions yet") } @@ -557,8 +571,8 @@ func TestServerPXEBoot(ctx context.Context, metalClient client.Client, cluster t // createDummyServers will submit servers with dummy info that are not tied to QEMU VMs. // These can be targeted by the spec passed in or the label "dummy-server". // Dummy servers are patched after creation to ensure they're marked as clean. -func createDummyServer(ctx context.Context, metalClient client.Client, name string, spec v1alpha1.ServerSpec) (v1alpha1.Server, error) { - var server v1alpha1.Server +func createDummyServer(ctx context.Context, metalClient client.Client, name string, spec metalv1.ServerSpec) (metalv1.Server, error) { + var server metalv1.Server server.APIVersion = constants.SideroAPIVersion server.Name = name @@ -572,7 +586,7 @@ func createDummyServer(ctx context.Context, metalClient client.Client, name stri return server, retry.Constant(time.Minute, retry.WithUnits(10*time.Second)).Retry(func() error { // refetch dummy server to make sure we're synced up before patching - server = v1alpha1.Server{} + server = metalv1.Server{} err = metalClient.Get(ctx, types.NamespacedName{Name: name}, &server) if err != nil { @@ -598,7 +612,7 @@ func createDummyServer(ctx context.Context, metalClient client.Client, name stri } // getAvailableServersFromServerClass returns a list of servers that are available as part of a serverclass. -func getAvailableServersFromServerClass(serverClass v1alpha1.ServerClass, serverList *v1alpha1.ServerList) []string { +func getAvailableServersFromServerClass(serverClass metalv1.ServerClass, serverList *metalv1.ServerList) []string { var foundServers []string for _, server := range serverList.Items { diff --git a/sfyra/pkg/tests/server_class.go b/sfyra/pkg/tests/server_class.go index 404fdcdf2..7666fda8c 100644 --- a/sfyra/pkg/tests/server_class.go +++ b/sfyra/pkg/tests/server_class.go @@ -31,7 +31,7 @@ import ( capiclient "sigs.k8s.io/cluster-api/cmd/clusterctl/client" "sigs.k8s.io/controller-runtime/pkg/client" - "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha1" + metalv1 "github.com/talos-systems/sidero/app/sidero-controller-manager/api/v1alpha2" "github.com/talos-systems/sidero/sfyra/pkg/capi" "github.com/talos-systems/sidero/sfyra/pkg/constants" "github.com/talos-systems/sidero/sfyra/pkg/talos" @@ -48,8 +48,8 @@ func TestServerClassAny(ctx context.Context, metalClient client.Client, vmSet *v return func(t *testing.T) { numNodes := len(vmSet.Nodes()) - var serverClass v1alpha1.ServerClass - err := metalClient.Get(ctx, types.NamespacedName{Name: v1alpha1.ServerClassAny}, &serverClass) + var serverClass metalv1.ServerClass + err := metalClient.Get(ctx, types.NamespacedName{Name: metalv1.ServerClassAny}, &serverClass) require.NoError(t, err) assert.Empty(t, serverClass.Spec.Qualifiers) assert.Len(t, append(serverClass.Status.ServersAvailable, serverClass.Status.ServersInUse...), numNodes) @@ -58,9 +58,9 @@ func TestServerClassAny(ctx context.Context, metalClient client.Client, vmSet *v err = metalClient.Delete(ctx, &serverClass) require.NoError(t, err) - serverClass = v1alpha1.ServerClass{} + serverClass = metalv1.ServerClass{} err = retry.Constant(10 * time.Second).Retry(func() error { - if err := metalClient.Get(ctx, types.NamespacedName{Name: v1alpha1.ServerClassAny}, &serverClass); err != nil { + if err := metalClient.Get(ctx, types.NamespacedName{Name: metalv1.ServerClassAny}, &serverClass); err != nil { if apierrors.IsNotFound(err) { return retry.ExpectedError(err) } @@ -82,11 +82,13 @@ func TestServerClassAny(ctx context.Context, metalClient client.Client, vmSet *v // TestServerClassCreate verifies server class creation. func TestServerClassCreate(ctx context.Context, metalClient client.Client, vmSet *vm.Set) TestFunc { return func(t *testing.T) { - classSpec := v1alpha1.ServerClassSpec{ - Qualifiers: v1alpha1.Qualifiers{ - CPU: []v1alpha1.CPUInformation{ + classSpec := metalv1.ServerClassSpec{ + Qualifiers: metalv1.Qualifiers{ + Hardware: []metalv1.HardwareInformation{ { - Manufacturer: "QEMU", + System: &metalv1.SystemInformation{ + Manufacturer: "QEMU", + }, }, }, }, @@ -138,11 +140,17 @@ func TestServerClassCreate(ctx context.Context, metalClient client.Client, vmSet func TestServerClassPatch(ctx context.Context, metalClient client.Client, cluster talos.Cluster, capiManager *capi.Manager) TestFunc { return func(t *testing.T) { // Create dummy serverclass + a server - dummySpec := v1alpha1.ServerSpec{ - CPU: &v1alpha1.CPUInformation{ - Manufacturer: "DummyCPU", - }, + dummySpec := metalv1.ServerSpec{ Accepted: true, + Hardware: &metalv1.HardwareInformation{ + Compute: &metalv1.ComputeInformation{ + Processors: []*metalv1.Processor{ + { + Manufacturer: "DummyCPU", + }, + }, + }, + }, } dummyServer, err := createDummyServer(ctx, metalClient, "dummyserver-0", dummySpec) @@ -159,18 +167,24 @@ func TestServerClassPatch(ctx context.Context, metalClient client.Client, cluste installPatch := configPatchToJSON(t, &installConfig) - classSpec := v1alpha1.ServerClassSpec{ - ConfigPatches: []v1alpha1.ConfigPatches{ + classSpec := metalv1.ServerClassSpec{ + ConfigPatches: []metalv1.ConfigPatches{ { Op: "replace", Path: "/machine/install", Value: apiextensions.JSON{Raw: installPatch}, }, }, - Qualifiers: v1alpha1.Qualifiers{ - CPU: []v1alpha1.CPUInformation{ + Qualifiers: metalv1.Qualifiers{ + Hardware: []metalv1.HardwareInformation{ { - Manufacturer: "DummyCPU", + Compute: &metalv1.ComputeInformation{ + Processors: []*metalv1.Processor{ + { + Manufacturer: "DummyCPU", + }, + }, + }, }, }, }, @@ -279,7 +293,7 @@ func TestServerClassPatch(ctx context.Context, metalClient client.Client, cluste time.Sleep(time.Second * 10) - response := &v1alpha1.Server{} + response := &metalv1.Server{} require.NoError(t, metalClient.Get(ctx, types.NamespacedName{Name: dummyServer.Name}, response)) require.Greater(t, len(response.Finalizers), 0) @@ -303,8 +317,8 @@ func TestServerClassPatch(ctx context.Context, metalClient client.Client, cluste } } -func createServerClass(ctx context.Context, metalClient client.Client, name string, spec v1alpha1.ServerClassSpec) (v1alpha1.ServerClass, error) { - var retClass v1alpha1.ServerClass +func createServerClass(ctx context.Context, metalClient client.Client, name string, spec metalv1.ServerClassSpec) (metalv1.ServerClass, error) { + var retClass metalv1.ServerClass if err := metalClient.Get(ctx, types.NamespacedName{Name: name}, &retClass); err != nil { if !apierrors.IsNotFound(err) { diff --git a/templates/cluster-template-talos-v0.13.4.yaml b/templates/cluster-template-talos-v0.13.4.yaml index a8896a111..f6c010e67 100644 --- a/templates/cluster-template-talos-v0.13.4.yaml +++ b/templates/cluster-template-talos-v0.13.4.yaml @@ -38,7 +38,7 @@ spec: template: spec: serverClassRef: - apiVersion: metal.sidero.dev/v1alpha1 + apiVersion: metal.sidero.dev/v1alpha2 kind: ServerClass name: ${CONTROL_PLANE_SERVERCLASS} --- @@ -102,6 +102,6 @@ spec: template: spec: serverClassRef: - apiVersion: metal.sidero.dev/v1alpha1 + apiVersion: metal.sidero.dev/v1alpha2 kind: ServerClass name: ${WORKER_SERVERCLASS} diff --git a/templates/cluster-template.yaml b/templates/cluster-template.yaml index 1a478bffc..735210e9b 100644 --- a/templates/cluster-template.yaml +++ b/templates/cluster-template.yaml @@ -36,7 +36,7 @@ spec: template: spec: serverClassRef: - apiVersion: metal.sidero.dev/v1alpha1 + apiVersion: metal.sidero.dev/v1alpha2 kind: ServerClass name: ${CONTROL_PLANE_SERVERCLASS} --- @@ -97,6 +97,6 @@ spec: template: spec: serverClassRef: - apiVersion: metal.sidero.dev/v1alpha1 + apiVersion: metal.sidero.dev/v1alpha2 kind: ServerClass name: ${WORKER_SERVERCLASS} diff --git a/website/content/docs/v0.5/Getting Started/install-clusterapi.md b/website/content/docs/v0.5/Getting Started/install-clusterapi.md index 0dfca1698..8cc17e02e 100644 --- a/website/content/docs/v0.5/Getting Started/install-clusterapi.md +++ b/website/content/docs/v0.5/Getting Started/install-clusterapi.md @@ -24,6 +24,7 @@ options. ```bash export SIDERO_CONTROLLER_MANAGER_HOST_NETWORK=true +export SIDERO_CONTROLLER_MANAGER_DEPLOYMENT_STRATEGY=Recreate export SIDERO_CONTROLLER_MANAGER_API_ENDPOINT=192.168.1.150 export SIDERO_CONTROLLER_MANAGER_SIDEROLINK_ENDPOINT=192.168.1.150 diff --git a/website/content/docs/v0.5/Guides/bootstrapping.md b/website/content/docs/v0.5/Guides/bootstrapping.md index 418f10641..bbb56fb3b 100644 --- a/website/content/docs/v0.5/Guides/bootstrapping.md +++ b/website/content/docs/v0.5/Guides/bootstrapping.md @@ -147,6 +147,7 @@ To install Sidero and the other Talos providers, simply issue: ```bash SIDERO_CONTROLLER_MANAGER_HOST_NETWORK=true \ + SIDERO_CONTROLLER_MANAGER_DEPLOYMENT_STRATEGY=Recreate \ SIDERO_CONTROLLER_MANAGER_API_ENDPOINT=$PUBLIC_IP \ clusterctl init -b talos -c talos -i sidero ``` diff --git a/website/content/docs/v0.5/Guides/patching.md b/website/content/docs/v0.5/Guides/patching.md index 70609fed3..d46ada807 100644 --- a/website/content/docs/v0.5/Guides/patching.md +++ b/website/content/docs/v0.5/Guides/patching.md @@ -14,7 +14,7 @@ Any patches specified in the server resource are processed by the Sidero control A set of patches may look like this: ```yaml -apiVersion: metal.sidero.dev/v1alpha1 +apiVersion: metal.sidero.dev/v1alpha2 kind: Server metadata: name: 00000000-0000-0000-0000-d05099d33360 diff --git a/website/content/docs/v0.5/Guides/sidero-on-rpi4.md b/website/content/docs/v0.5/Guides/sidero-on-rpi4.md index da0be73b6..96c095efe 100644 --- a/website/content/docs/v0.5/Guides/sidero-on-rpi4.md +++ b/website/content/docs/v0.5/Guides/sidero-on-rpi4.md @@ -104,7 +104,7 @@ kubectl get nodes Install Sidero with host network mode, exposing the endpoints on the node's address: ```bash -SIDERO_CONTROLLER_MANAGER_HOST_NETWORK=true SIDERO_CONTROLLER_MANAGER_API_ENDPOINT=${SIDERO_IP} clusterctl init -i sidero -b talos -c talos +SIDERO_CONTROLLER_MANAGER_HOST_NETWORK=true SIDERO_CONTROLLER_MANAGER_DEPLOYMENT_STRATEGY=Recreate SIDERO_CONTROLLER_MANAGER_API_ENDPOINT=${SIDERO_IP} clusterctl init -i sidero -b talos -c talos ``` Watch the progress of installation with: diff --git a/website/content/docs/v0.5/Overview/installation.md b/website/content/docs/v0.5/Overview/installation.md index f7ffce91a..b42c9c4b3 100644 --- a/website/content/docs/v0.5/Overview/installation.md +++ b/website/content/docs/v0.5/Overview/installation.md @@ -14,6 +14,7 @@ Sidero supports several variables to configure the installation, these variables variables or as variables in the `clusterctl` configuration: - `SIDERO_CONTROLLER_MANAGER_HOST_NETWORK` (`false`): run `sidero-controller-manager` on host network +- `SIDERO_CONTROLLER_MANAGER_DEPLOYMENT_STRATEGY` (`RollingUpdate`): strategy to use when updating `sidero-controller-manager`, use `Recreate` when `SIDERO_CONTROLLER_MANAGER_HOST_NETWORK` is `true` - `SIDERO_CONTROLLER_MANAGER_API_ENDPOINT` (empty): specifies the IP address controller manager API service can be reached on, defaults to the node IP (TCP) - `SIDERO_CONTROLLER_MANAGER_API_PORT` (8081): specifies the port controller manager can be reached on - `SIDERO_CONTROLLER_MANAGER_CONTAINER_API_PORT` (8081): specifies the controller manager internal container port diff --git a/website/content/docs/v0.5/Resource Configuration/environments.md b/website/content/docs/v0.5/Resource Configuration/environments.md index 3545d9f75..226b1b7b9 100644 --- a/website/content/docs/v0.5/Resource Configuration/environments.md +++ b/website/content/docs/v0.5/Resource Configuration/environments.md @@ -20,7 +20,7 @@ The hierarchy from most to least respected is: A sample environment definition looks like this: ```yaml -apiVersion: metal.sidero.dev/v1alpha1 +apiVersion: metal.sidero.dev/v1alpha2 kind: Environment metadata: name: default @@ -52,7 +52,7 @@ spec: Example of overriding `"default"` `Environment` at the `Server` level: ```yaml -apiVersion: metal.sidero.dev/v1alpha1 +apiVersion: metal.sidero.dev/v1alpha2 kind: Server ... spec: @@ -65,7 +65,7 @@ spec: Example of overriding `"default"` `Environment` at the `ServerClass` level: ```yaml -apiVersion: metal.sidero.dev/v1alpha1 +apiVersion: metal.sidero.dev/v1alpha2 kind: ServerClass ... spec: diff --git a/website/content/docs/v0.5/Resource Configuration/metadata.md b/website/content/docs/v0.5/Resource Configuration/metadata.md index 6cdeccdc1..7e7dfab07 100644 --- a/website/content/docs/v0.5/Resource Configuration/metadata.md +++ b/website/content/docs/v0.5/Resource Configuration/metadata.md @@ -92,7 +92,7 @@ and finally in the control plane `ServerClass` custom resource we augment the ne ```yaml --- -apiVersion: metal.sidero.dev/v1alpha1 +apiVersion: metal.sidero.dev/v1alpha2 kind: ServerClass metadata: name: cp.small.x86 @@ -112,10 +112,13 @@ spec: interface: eth1 dhcp: true qualifiers: - cpu: - - version: Intel(R) Xeon(R) E-2124G CPU @ 3.40GHz - systemInformation: - - manufacturer: Supermicro + - system: + manufacturer: Supermicro + compute: + processors: + - productName: Intel(R) Xeon(R) E-2124G CPU @ 3.40GHz + memory: + totalSize: 8 GB selector: matchLabels: metal.sidero.dev/serverclass: cp.small.x86 @@ -125,7 +128,7 @@ the workload `ServerClass` defines the complete networking config ```yaml --- -apiVersion: metal.sidero.dev/v1alpha1 +apiVersion: metal.sidero.dev/v1alpha2 kind: ServerClass metadata: name: general.medium.x86 @@ -148,10 +151,13 @@ spec: - interface: eth1 dhcp: true qualifiers: - cpu: - - version: Intel(R) Xeon(R) E-2136 CPU @ 3.30GHz - systemInformation: - - manufacturer: Supermicro + - system: + manufacturer: Supermicro + compute: + processors: + - productName: Intel(R) Xeon(R) E-2136 CPU @ 3.30GHz + memory: + totalSize: 16 GB selector: matchLabels: metal.sidero.dev/serverclass: general.medium.x86 diff --git a/website/content/docs/v0.5/Resource Configuration/serverclasses.md b/website/content/docs/v0.5/Resource Configuration/serverclasses.md index 272bdb858..350589186 100644 --- a/website/content/docs/v0.5/Resource Configuration/serverclasses.md +++ b/website/content/docs/v0.5/Resource Configuration/serverclasses.md @@ -16,15 +16,14 @@ The [Kubernetes documentation][label-selector-docs] has more information on how ## `qualifiers` -There are currently two keys: `cpu`, `systemInformation`. -Each of these keys accepts a list of entries. -The top level keys are a "logical `AND`", while the lists under each key are a "logical `OR`". +A list of hardware criteria, where each entry in the list is interpreted as a logical `OR`. +All criteria inside each entry is interpreted as a logical `AND`. Qualifiers that are not specified are not evaluated. An example: ```yaml -apiVersion: metal.sidero.dev/v1alpha1 +apiVersion: metal.sidero.dev/v1alpha2 kind: ServerClass metadata: name: serverclass-sample @@ -43,20 +42,28 @@ spec: values: - prod qualifiers: - cpu: - - manufacturer: "Intel(R) Corporation" - version: "Intel(R) Atom(TM) CPU C3558 @ 2.20GHz" - - manufacturer: Advanced Micro Devices, Inc. - version: AMD Ryzen 7 2700X Eight-Core Processor - systemInformation: - - manufacturer: Dell Inc. + hardware: + - system: + manufacturer: Dell Inc. + compute: + processors: + - manufacturer: Advanced Micro Devices, Inc. + productName: AMD Ryzen 7 2700X Eight-Core Processor + - compute: + processors: + - manufacturer: "Intel(R) Corporation" + productName: "Intel(R) Atom(TM) CPU C3558 @ 2.20GHz" + memory: + totalSize: "8 GB" ``` Servers would only be added to the above class if they: -- had _EITHER_ CPU info -- _AND_ the label key/value in `matchLabels` +- have the label `common-label` with value `true` - _AND_ match the `matchExpressions` +- _AND_ match either 1 of the following criteria: + - has a system manufactured by `Dell Inc.` _AND_ has at least 1 processor that is an `AMD Ryzen 7 2700X Eight-Core Processor` + - has at least 1 processor that is an `Intel(R) Atom(TM) CPU C3558 @ 2.20GHz` _AND_ has exactly 8 GB of total memory Additionally, Sidero automatically creates and maintains a server class called `"any"` that includes all (accepted) servers. Attempts to add qualifiers to it will be reverted. @@ -71,7 +78,7 @@ See [patching](../guides/patching) for more information on how this works. An example of settings the default install disk for all servers matching a server class: ```yaml -apiVersion: metal.sidero.dev/v1alpha1 +apiVersion: metal.sidero.dev/v1alpha2 kind: ServerClass ... spec: diff --git a/website/content/docs/v0.5/Resource Configuration/servers.md b/website/content/docs/v0.5/Resource Configuration/servers.md index 969991765..14cd19e95 100644 --- a/website/content/docs/v0.5/Resource Configuration/servers.md +++ b/website/content/docs/v0.5/Resource Configuration/servers.md @@ -10,7 +10,7 @@ These are created by PXE booting the servers and allowing them to send a registr An example server may look like the following: ```yaml -apiVersion: metal.sidero.dev/v1alpha1 +apiVersion: metal.sidero.dev/v1alpha2 kind: Server metadata: name: 00000000-0000-0000-0000-d05099d333e0 @@ -27,11 +27,66 @@ spec: name: custom urls: - http://192.168.1.199/assets/cilium.yaml - cpu: - manufacturer: Intel(R) Corporation - version: Intel(R) Atom(TM) CPU C3558 @ 2.20GHz - system: - manufacturer: Dell Inc. + hardware: + system: + manufacturer: Dell Inc. + productName: PowerEdge R630 + serialNumber: 790H8D2 + compute: + totalCoreCount: 8 + totalThreadCount: 16 + processorCount: 1 + processors: + - manufacturer: Intel + productName: Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz + speed: 2400 + coreCount: 8 + threadCount: 16 + memory: + totalSize: 32 GB + moduleCount: 2 + modules: + - manufacturer: 002C00B3002C + productName: 18ASF2G72PDZ-2G3B1 + serialNumber: 12BDC045 + type: LPDDR3 + size: 16384 + speed: 2400 + - manufacturer: 002C00B3002C + productName: 18ASF2G72PDZ-2G3B1 + serialNumber: 12BDBF5D + type: LPDDR3 + size: 16384 + speed: 2400 + storage: + totalSize: 1116 GB + deviceCount: 1 + devices: + - productName: PERC H730 Mini + type: HDD + name: sda + deviceName: /dev/sda + size: 1199101181952 + wwid: naa.61866da055de070028d8e83307cc6df2 + network: + interfaceCount: 2 + interfaces: + - index: 1 + name: lo + flags: up|loopback + mtu: 65536 + mac: "" + addresses: + - 127.0.0.1/8 + - ::1/128 + - index: 2 + name: enp3s0 + flags: up|broadcast|multicast + mtu: 1500 + mac: "40:8d:5c:86:5a:14" + addresses: + - 192.168.2.8/24 + - fe80::dcb3:295c:755b:91bb/64 ``` ## Installation Disk @@ -40,7 +95,7 @@ An installation disk is required by Talos on bare metal. This can be specified in a `configPatch`: ```yaml -apiVersion: metal.sidero.dev/v1alpha1 +apiVersion: metal.sidero.dev/v1alpha2 kind: Server ... spec: @@ -54,7 +109,7 @@ spec: The install disk patch can also be set on the `ServerClass`: ```yaml -apiVersion: metal.sidero.dev/v1alpha1 +apiVersion: metal.sidero.dev/v1alpha2 kind: ServerClass ... spec: @@ -96,7 +151,7 @@ Users wishing to turn off this feature can pass the `--auto-bmc-setup=false` fla IMPI connection information can also be set manually in the `Server` spec after initial registration: ```yaml -apiVersion: metal.sidero.dev/v1alpha1 +apiVersion: metal.sidero.dev/v1alpha2 kind: Server ... spec: @@ -115,7 +170,7 @@ Without IPMI info, Sidero can still register servers, wipe them and provision cl Sidero can also fetch IPMI credentials via the `Secret` reference: ```yaml -apiVersion: metal.sidero.dev/v1alpha1 +apiVersion: metal.sidero.dev/v1alpha2 kind: Server ... spec: