Skip to content

Commit

Permalink
Add transformation support
Browse files Browse the repository at this point in the history
  • Loading branch information
lblackstone committed Mar 27, 2019
1 parent fd2385f commit d73e209
Show file tree
Hide file tree
Showing 4 changed files with 603 additions and 386 deletions.
51 changes: 34 additions & 17 deletions pkg/gen/python-templates/yaml.py.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import json
from copy import deepcopy
from typing import Optional
from typing import (Dict, List, Optional)

import pulumi.runtime
import requests
Expand All @@ -25,9 +25,12 @@ class ConfigFile(pulumi.ComponentResource):
:param str name: A name for a resource.
:param str file_id: Path or a URL that uniquely identifies a file.
:param ResourceOptions opts: A bag of optional settings that control a resource's behavior.
:param transformations: A set of transformations to apply to Kubernetes resource definitions before registering
with engine.
"""

def __init__(self, name: str, file_id: str, opts: Optional[pulumi.ResourceOptions] = None):
def __init__(self, name: str, file_id: str, opts: Optional[pulumi.ResourceOptions] = None,
transformations=None):
if not name:
raise TypeError('Missing resource name argument (for URN creation)')
if not isinstance(name, str):
Expand All @@ -48,14 +51,14 @@ class ConfigFile(pulumi.ComponentResource):
else:
text = read_file(file_id)

# TODO: transformation support
if opts is not None:
_opts = deepcopy(opts)
_opts.parent = self
else:
_opts = pulumi.ResourceOptions(parent=self)

self.register_outputs(parse_yaml_document(yaml.safe_load_all(text), _opts))
output = parse_yaml_document(yaml.safe_load_all(text), _opts, transformations)
self.register_outputs({"output": output})

def translate_output_property(self, prop: str) -> str:
return tables._CASING_FORWARD_TABLE.get(prop) or prop
Expand All @@ -78,22 +81,34 @@ def read_file(path: str) -> str:
return data


def parse_yaml_document(objects, opts: Optional[pulumi.ResourceOptions] = None):
def _build_resources_dict(objs: List[pulumi.Output]) -> Dict[pulumi.Output, pulumi.Output]:
resources = {}
for obj in objects:
# TODO: transformation support
file_objects = parse_yaml_object(obj, opts)
for key, value in file_objects:
resources[key] = value
for key, value in objs:
resources[key] = value

return resources


def parse_yaml_object(obj, opts: Optional[pulumi.ResourceOptions] = None):
def parse_yaml_document(objects, opts: Optional[pulumi.ResourceOptions] = None,
transformations=None) -> pulumi.Output:
objs = []
for obj in objects:
file_objects = parse_yaml_object(obj, opts, transformations)
for file_object in file_objects:
objs.append(file_object)

return pulumi.Output.all(*objs).apply(_build_resources_dict)


def parse_yaml_object(obj, opts: Optional[pulumi.ResourceOptions] = None,
transformations=None) -> [pulumi.Output]:
if not obj:
return []

# TODO: transformation support
# Allow users to change API objects before any validation.
if transformations is not None:
for t in transformations:
obj = t(obj)

if "kind" not in obj or "apiVersion" not in obj:
raise Exception("Kubernetes resources require a kind and apiVersion: {}".format(json.dumps(obj)))
Expand All @@ -105,7 +120,7 @@ def parse_yaml_object(obj, opts: Optional[pulumi.ResourceOptions] = None):
objs = []
if "items" in obj:
for item in obj["items"]:
objs = objs + parse_yaml_object(item, opts)
objs += parse_yaml_object(item, opts, transformations)
return objs

if "metadata" not in obj or "name" not in obj["metadata"]:
Expand All @@ -114,17 +129,19 @@ def parse_yaml_object(obj, opts: Optional[pulumi.ResourceOptions] = None):

metadata = obj["metadata"]
spec = obj.get("spec")
identifier = metadata["name"]
identifier: pulumi.Output = pulumi.Output.from_input(metadata["name"])
if "namespace" in metadata:
identifier = "{}/{}".format(metadata["namespace"], metadata["name"])
identifier = pulumi.Output.from_input(metadata).apply(
lambda metadata: f"{metadata['namespace']}/{metadata['name']}")

gvk = f"{api_version}/{kind}"
{{#Groups}}
{{#Versions}}
{{#Kinds}}
if gvk == "{{RawAPIVersion}}/{{Kind}}":
return [(f"{{RawAPIVersion}}/{{Kind}}:{identifier}",
{{Kind}}(identifier, opts, metadata, spec))]
return [identifier.apply(
lambda x: (f"{{RawAPIVersion}}/{{Kind}}:{x}",
{{Kind}}(x, opts, metadata, spec)))]
{{/Kinds}}
{{/Versions}}
{{/Groups}}
Expand Down
Loading

0 comments on commit d73e209

Please sign in to comment.