95 lines
2.4 KiB
Go
95 lines
2.4 KiB
Go
package customresource
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
|
|
"opendev.org/airship/kubernetes-entrypoint/entrypoint"
|
|
"opendev.org/airship/kubernetes-entrypoint/logger"
|
|
"opendev.org/airship/kubernetes-entrypoint/util/env"
|
|
)
|
|
|
|
// A Resolver represents the state of a CustomResource
|
|
type Resolver struct {
|
|
APIVersion string `json:"apiVersion"`
|
|
Kind string `json:"kind"`
|
|
Name string `json:"name"`
|
|
Namespace string `json:"namespace"`
|
|
Fields []Field `json:"fields"`
|
|
}
|
|
|
|
var _ entrypoint.Resolver = Resolver{}
|
|
|
|
// A Field represents a key-value pair
|
|
type Field struct {
|
|
Key string `json:"key"`
|
|
Value string `json:"value"`
|
|
}
|
|
|
|
func init() {
|
|
crEnv := fmt.Sprintf("%sCUSTOM_RESOURCE", entrypoint.DependencyPrefix)
|
|
resolvers, err := fromEnv(crEnv)
|
|
if err != nil {
|
|
logger.Error.Printf(err.Error())
|
|
}
|
|
for _, resolver := range resolvers {
|
|
entrypoint.Register(resolver)
|
|
}
|
|
}
|
|
|
|
// IsResolved will return true when the values for each key in r.Fields is the same as the resource in the cluster
|
|
func (r Resolver) IsResolved(ep entrypoint.EntrypointInterface) (bool, error) {
|
|
customResource, err := ep.Client().CustomResource(r.APIVersion, r.Kind, r.Namespace, r.Name)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
for _, field := range r.Fields {
|
|
key := field.Key
|
|
expected := field.Value
|
|
|
|
// Extract the specified value from the resource
|
|
actual, found, err := unstructured.NestedFieldNoCopy(customResource.Object, strings.Split(key, ".")...)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
if !found {
|
|
return false, fmt.Errorf("Could not find key [%s]", key)
|
|
}
|
|
if actual != expected {
|
|
return false, fmt.Errorf("Expected value of [%s] to be [%s], but got [%s]", key, expected, actual)
|
|
}
|
|
}
|
|
|
|
return true, nil
|
|
}
|
|
|
|
// fromEnv reads the value of the jsonEnv variable and returns the array of
|
|
// Resolvers it contains, if any
|
|
func fromEnv(jsonEnv string) ([]Resolver, error) {
|
|
resolvers := []Resolver{}
|
|
jsonEnvVal, isSet := os.LookupEnv(jsonEnv)
|
|
if !isSet {
|
|
return resolvers, nil
|
|
}
|
|
|
|
err := json.Unmarshal([]byte(jsonEnvVal), &resolvers)
|
|
if err != nil {
|
|
return resolvers, fmt.Errorf("Unable to unmarshal variable %s with value %s: %s",
|
|
jsonEnv, jsonEnvVal, err.Error())
|
|
}
|
|
|
|
namespace := env.GetBaseNamespace()
|
|
for i := range resolvers {
|
|
if resolvers[i].Namespace == "" {
|
|
resolvers[i].Namespace = namespace
|
|
}
|
|
}
|
|
|
|
return resolvers, nil
|
|
}
|