Skip to content
This repository has been archived by the owner on Jul 25, 2023. It is now read-only.

Commit

Permalink
feat: add support for interpolating strings
Browse files Browse the repository at this point in the history
Supports the following syntax as described in composable-operator#49

```yaml
interpolateValuesFrom:
  format: 'http://%s:%s'
  inputs:
    - getValueFrom:
      ....
    - getValueFrom:
      ....
```
  • Loading branch information
TMaYaD committed Oct 22, 2021
1 parent e96a96d commit 75935f6
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 15 deletions.
5 changes: 5 additions & 0 deletions sdk/composable-types.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ type ComposableGetValueFrom struct {
FormatTransformers []string `json:"format-transformers,omitempty"`
}

type ComposableInterpolateValuesFrom struct {
Format string `json:"format"`
Inputs []ComposableGetValueFrom `json:"inputs"`
}

// ObjectRef is the type that can be used for cross-resource references
// +kubebuilder:object:generate=true
type ObjectRef struct {
Expand Down
86 changes: 71 additions & 15 deletions sdk/composable.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,24 @@ var logf = log.Log.WithName("composable-sdk")

// String constants
const (
Metadata = "metadata"
Namespace = "namespace"
GetValueFrom = "getValueFrom"
kind = "kind"
apiVersion = "apiVersion"
path = "path"
Name = "name"
Labels = "labels"
Transformers = "format-transformers"
defaultValue = "defaultValue"
objectPrefix = ".Object"
kindNotFound = "Error resolving the kind for an object reference"
objectNotFound = "Error finding an object reference"
valueNotFound = "Error finding a value in an object reference"
illFormedRef = "Object reference is ill-formed"
Metadata = "metadata"
Namespace = "namespace"
GetValueFrom = "getValueFrom"
InterpolateValuesFrom = "interpolateValuesFrom"
kind = "kind"
apiVersion = "apiVersion"
path = "path"
Name = "name"
Labels = "labels"
Transformers = "format-transformers"
format = "format"
inputs = "inputs"
defaultValue = "defaultValue"
objectPrefix = ".Object"
kindNotFound = "Error resolving the kind for an object reference"
objectNotFound = "Error finding an object reference"
valueNotFound = "Error finding a value in an object reference"
illFormedRef = "Object reference is ill-formed"
)

// KubernetesResourceResolver implements the ResolveObject interface
Expand Down Expand Up @@ -109,6 +112,13 @@ func resolveFields(ctx context.Context, r client.Client, fields interface{}, com
return nil, err
}
fields = newFields
} else if k == InterpolateValuesFrom {
newFields, err = interpolateValues(ctx, r, v, composableNamespace, cache, discoveryClient)
if err != nil {
logf.Info("resolveFields interpolateValues 1", "err", err)
return nil, err
}
fields = newFields
} else if values, ok := v.(map[string]interface{}); ok {
if value, ok := values[GetValueFrom]; ok {
if len(values) > 1 {
Expand All @@ -117,6 +127,13 @@ func resolveFields(ctx context.Context, r client.Client, fields interface{}, com
return nil, err
}
newFields, err = resolveValue(ctx, r, value, composableNamespace, cache, discoveryClient)
} else if value, ok := values[InterpolateValuesFrom]; ok {
if len(values) > 1 {
err := fmt.Errorf("%s, %s", "InterpolateValuesFrom must be the only field in a value", illFormedRef)
logf.Error(err, "resolveFields", "values", values)
return nil, err
}
newFields, err = interpolateValues(ctx, r, value, composableNamespace, cache, discoveryClient)
} else {
newFields, err = resolveFields(ctx, r, values, composableNamespace, cache, discoveryClient)
}
Expand Down Expand Up @@ -288,6 +305,45 @@ func resolveValue(ctx context.Context, r client.Client, value interface{}, compo
return nil, err
}

func interpolateValues(ctx context.Context, r client.Client, value interface{}, composableNamespace string, cache *ComposableCache, discoveryClient discovery.ServerResourcesInterface) (interface{}, error) {
var err error

val, ok := value.(map[string]interface{})
if !ok {
err = fmt.Errorf("%s %T, %s ", "InterpolateValuesFrom is not well-formed, value type is not ", value, illFormedRef)

This comment has been minimized.

Copy link
@pralim

pralim Oct 28, 2021

missing "defined" at end of the message

This comment has been minimized.

Copy link
@TMaYaD

TMaYaD Oct 29, 2021

Author

This is modelled after L303. I'm guessing value contains the object that's supposed to go there.

logf.Error(err, "resolveValue", "value", value)
return nil, err
}

objFormat, ok := val[format].(string)
if !ok {
err = fmt.Errorf("%s, %s ", "InterpolateValuesFrom is not well-formed, 'format' is not defined ", illFormedRef)
logf.Error(err, "resolveValue", "val", val)
return nil, err
}

objInputs, ok := val[inputs].([]interface{})
if !ok || len(objInputs) == 0 {
err = fmt.Errorf("%s, %s ", "InterpolateValuesFrom is not well-formed, 'inputs' is not defined ", illFormedRef)
logf.Error(err, "resolveValue", "val", val)
return nil, err
}

values := make([]interface{}, 0, len(objInputs))

for _, input := range objInputs {
value, err = resolveValue(ctx, r, input, composableNamespace, cache, discoveryClient)
if err != nil {
logf.Info("interpolateValues resolveValue", "err", err)
return nil, err
}
values = append.values(value)
}

return fmt.Sprintf(objFormat, values...), err

}

func getInputObject(ctx context.Context, r client.Client, val map[string]interface{}, objKind, apiversion, composableNamespace string, cache *ComposableCache, discoveryClient discovery.ServerResourcesInterface) (*unstructured.Unstructured, error) {
res, err := lookupAPIResource(discoveryClient, objKind, apiversion)
if err != nil {
Expand Down

0 comments on commit 75935f6

Please sign in to comment.