Validate the result returned by providers

Providers may return only 3 possible statuses:

  * InstanceRunning
  * InstanceError
  * InstanceStopped

Every other status is reserved for the controller to set. Provider
responses will be split from the instance response in a future commit.

Signed-off-by: Gabriel Adrian Samfira <gsamfira@cloudbasesolutions.com>
This commit is contained in:
Gabriel Adrian Samfira 2023-06-10 16:46:02 +03:00
parent e6a4137e3b
commit 06745eb88a
No known key found for this signature in database
GPG key ID: 7D073DCC2C074CB5
2 changed files with 33 additions and 7 deletions

View file

@ -35,6 +35,7 @@ const (
RunnerActive RunnerStatus = "active"
)
// IsValidStatus checks if the given status is valid.
func IsValidStatus(status InstanceStatus) bool {
switch status {
case InstanceRunning, InstanceError, InstancePendingCreate,
@ -46,3 +47,17 @@ func IsValidStatus(status InstanceStatus) bool {
return false
}
}
// IsProviderValidStatus checks if the given status is valid for the provider.
// A provider should only return a status indicating that the instance is in a
// lifecycle state that it can influence. The sole purpose of a provider is to
// manage the lifecycle of an instance. Statuses that indicate an instance should
// be created or removed, will be set by the controller.
func IsValidProviderStatus(status InstanceStatus) bool {
switch status {
case InstanceRunning, InstanceError, InstanceStopped:
return true
default:
return false
}
}

View file

@ -44,21 +44,21 @@ type external struct {
execPath string
}
func (e *external) validateCreateResult(inst params.Instance) error {
func (e *external) validateResult(inst params.Instance) error {
if inst.ProviderID == "" {
return garmErrors.NewProviderError("missing provider ID after create call")
return garmErrors.NewProviderError("missing provider ID")
}
if inst.Name == "" {
return garmErrors.NewProviderError("missing instance name after create call")
return garmErrors.NewProviderError("missing instance name")
}
if inst.OSName == "" || inst.OSArch == "" || inst.OSType == "" {
// we can still function without this info (I think)
log.Printf("WARNING: missing OS information after create call")
log.Printf("WARNING: missing OS information")
}
if !providerCommon.IsValidStatus(inst.Status) {
return garmErrors.NewProviderError("invalid status returned (%s) after create call", inst.Status)
if !providerCommon.IsValidProviderStatus(inst.Status) {
return garmErrors.NewProviderError("invalid status returned (%s)", inst.Status)
}
return nil
@ -88,7 +88,7 @@ func (e *external) CreateInstance(ctx context.Context, bootstrapParams params.Bo
return params.Instance{}, garmErrors.NewProviderError("failed to decode response from binary: %s", err)
}
if err := e.validateCreateResult(param); err != nil {
if err := e.validateResult(param); err != nil {
return params.Instance{}, garmErrors.NewProviderError("failed to validate result: %s", err)
}
@ -137,6 +137,11 @@ func (e *external) GetInstance(ctx context.Context, instance string) (params.Ins
if err := json.Unmarshal(out, &param); err != nil {
return params.Instance{}, garmErrors.NewProviderError("failed to decode response from binary: %s", err)
}
if err := e.validateResult(param); err != nil {
return params.Instance{}, garmErrors.NewProviderError("failed to validate result: %s", err)
}
return param, nil
}
@ -158,6 +163,12 @@ func (e *external) ListInstances(ctx context.Context, poolID string) ([]params.I
if err := json.Unmarshal(out, &param); err != nil {
return []params.Instance{}, garmErrors.NewProviderError("failed to decode response from binary: %s", err)
}
for _, inst := range param {
if err := e.validateResult(inst); err != nil {
return []params.Instance{}, garmErrors.NewProviderError("failed to validate result: %s", err)
}
}
return param, nil
}