airshipctl/pkg/phase/executors/baremetal_manager.go
Kostiantyn Kalynovskyi f0e80cfdc5 Add BaremetalManager executor
This will allow to peform remote BMH operations as a phase

Change-Id: I8e99285e0407d1922312a08ad4f766363f8855d2
2021-02-02 16:42:09 +00:00

143 lines
4.5 KiB
Go

/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package executors
import (
"fmt"
"io"
"time"
"opendev.org/airship/airshipctl/pkg/api/v1alpha1"
airshipv1 "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
"opendev.org/airship/airshipctl/pkg/events"
"opendev.org/airship/airshipctl/pkg/inventory"
inventoryifc "opendev.org/airship/airshipctl/pkg/inventory/ifc"
"opendev.org/airship/airshipctl/pkg/phase/ifc"
)
// BaremetalManagerExectuor is abstraction built on top of baremetal commands of airshipctl
type BaremetalManagerExectuor struct {
inventory inventoryifc.Inventory
options *airshipv1.BaremetalManager
}
// NewBaremetalExecutor constructor for baremetal executor
func NewBaremetalExecutor(cfg ifc.ExecutorConfig) (ifc.Executor, error) {
inv, err := cfg.Helper.Inventory()
if err != nil {
return nil, err
}
options := airshipv1.DefaultBaremetalManager()
if err := cfg.ExecutorDocument.ToAPIObject(options, airshipv1.Scheme); err != nil {
return nil, err
}
return &BaremetalManagerExectuor{
inventory: inv,
options: options,
}, nil
}
// Run runs baremetal operations as exectuor
func (e *BaremetalManagerExectuor) Run(evtCh chan events.Event, opts ifc.RunOptions) {
defer close(evtCh)
commandOptions := toCommandOptions(e.inventory, e.options.Spec, opts)
evtCh <- events.NewEvent().WithBaremetalManagerEvent(events.BaremetalManagerEvent{
Step: events.BaremetalManagerStart,
HostOperation: string(e.options.Spec.Operation),
Message: fmt.Sprintf("Starting remote operation, selector to be to filter hosts %v",
e.options.Spec.HostSelector),
})
op, err := e.validate()
if err != nil {
handleError(evtCh, err)
return
}
if !opts.DryRun {
switch e.options.Spec.Operation {
case airshipv1.BaremetalOperationPowerOn, airshipv1.BaremetalOperationPowerOff,
airshipv1.BaremetalOperationReboot, airshipv1.BaremetalOperationEjectVirtualMedia:
err = commandOptions.BMHAction(op)
case airshipv1.BaremetalOperationRemoteDirect:
err = commandOptions.RemoteDirect()
}
}
if err != nil {
handleError(evtCh, err)
return
}
evtCh <- events.NewEvent().WithBaremetalManagerEvent(events.BaremetalManagerEvent{
Step: events.BaremetalManagerComplete,
HostOperation: string(e.options.Spec.Operation),
Message: fmt.Sprintf("Successfully completed operation against host selected by selector %v",
e.options.Spec.HostSelector),
})
}
// Validate executor configuration and documents
func (e *BaremetalManagerExectuor) Validate() error {
_, err := e.validate()
return err
}
func (e *BaremetalManagerExectuor) validate() (inventoryifc.BaremetalOperation, error) {
var result inventoryifc.BaremetalOperation
var err error
switch e.options.Spec.Operation {
case airshipv1.BaremetalOperationPowerOn:
result = inventoryifc.BaremetalOperationPowerOn
case airshipv1.BaremetalOperationPowerOff:
result = inventoryifc.BaremetalOperationPowerOff
case airshipv1.BaremetalOperationEjectVirtualMedia:
result = inventoryifc.BaremetalOperationEjectVirtualMedia
case airshipv1.BaremetalOperationReboot:
result = inventoryifc.BaremetalOperationReboot
case airshipv1.BaremetalOperationRemoteDirect:
// TODO add remote direct validation, make sure that ISO-URL is specified
result = ""
default:
err = ErrUnknownExecutorAction{Action: string(e.options.Spec.Operation), ExecutorName: BMHManager}
}
return result, err
}
// Render baremetal hosts
func (e *BaremetalManagerExectuor) Render(w io.Writer, _ ifc.RenderOptions) error {
// add printing of baremetal hosts here
_, err := w.Write([]byte{})
return err
}
func toCommandOptions(i inventoryifc.Inventory,
spec v1alpha1.BaremetalManagerSpec,
opts ifc.RunOptions) *inventory.CommandOptions {
timeout := time.Duration(spec.Timeout) * time.Second
if opts.Timeout != 0 {
timeout = opts.Timeout
}
return &inventory.CommandOptions{
Invetnory: i,
IsoURL: spec.OperationOptions.RemoteDirect.ISOURL,
Labels: spec.HostSelector.LabelSelector,
Name: spec.HostSelector.Name,
Namespace: spec.HostSelector.Namespace,
Timeout: timeout,
}
}