pulumi / pulumi-kubernetes

A Pulumi resource provider for Kubernetes to manage API resources and workloads in running clusters
https://www.pulumi.com/docs/reference/clouds/kubernetes/
Apache License 2.0
410 stars 117 forks source link

Python SDK: Inform user about invalid properties in resource #966

Closed Panaetius closed 1 year ago

Panaetius commented 4 years ago

Problem description

I wanted to render a helm chart that includes the resource: https://github.com/SwissDataScienceCenter/renku-graph/blob/master/helm-chart/renku-graph/charts/jena/templates/fuseki-server.yaml

This resource definition is wrong, as type is not a valid property on a ConfigMap (type is only available on Secret). I'd expect this to produce a human readable error about there being an invalid property present, instead pulumi produces a python stack trace about an expected keyword argument (see below).

Errors & Logs

error: Program failed with an unhandled exception:
    error: Traceback (most recent call last):
      File "/usr/local/bin/pulumi-language-python-exec", line 85, in <module>
        loop.run_until_complete(coro)
      File "/Users/<user>/.pyenv/versions/3.7.6/lib/python3.7/asyncio/base_events.py", line 583, in run_until_complete
        return future.result()
      File "/Users/<user>/renga/renku-gcp/venv/lib/python3.7/site-packages/pulumi/runtime/stack.py", line 72, in run_in_stack
        raise RPC_MANAGER.unhandled_exception.with_traceback(RPC_MANAGER.exception_traceback)
      File "/Users/<user>/renga/renku-gcp/venv/lib/python3.7/site-packages/pulumi/runtime/rpc_manager.py", line 67, in rpc_wrapper
        result = await rpc_function(*args, **kwargs)
      File "/Users/<user>/renga/renku-gcp/venv/lib/python3.7/site-packages/pulumi/runtime/resource.py", line 415, in do_register_resource_outputs
        serialized_props = await rpc.serialize_properties(outputs, {})
      File "/Users/<user>/renga/renku-gcp/venv/lib/python3.7/site-packages/pulumi/runtime/rpc.py", line 67, in serialize_properties
        result = await serialize_property(v, deps, input_transformer)
      File "/Users/<user>/renga/renku-gcp/venv/lib/python3.7/site-packages/pulumi/runtime/rpc.py", line 163, in serialize_property
        value = await serialize_property(value.future(), deps, input_transformer)
      File "/Users/<user>/renga/renku-gcp/venv/lib/python3.7/site-packages/pulumi/runtime/rpc.py", line 150, in serialize_property
        future_return = await asyncio.ensure_future(value)
      File "/Users/<user>/renga/renku-gcp/venv/lib/python3.7/site-packages/pulumi/output.py", line 114, in get_value
        val = await self._future
      File "/Users/<user>/renga/renku-gcp/venv/lib/python3.7/site-packages/pulumi/output.py", line 114, in get_value
        val = await self._future
      File "/Users/<user>/renga/renku-gcp/venv/lib/python3.7/site-packages/pulumi/output.py", line 186, in run
        return await transformed.future(with_unknowns=True)
      File "/Users/<user>/renga/renku-gcp/venv/lib/python3.7/site-packages/pulumi/output.py", line 155, in run
        value = await self._future
      File "/Users/<user>/renga/renku-gcp/venv/lib/python3.7/site-packages/pulumi/output.py", line 114, in get_value
        val = await self._future
      File "/Users/<user>/renga/renku-gcp/venv/lib/python3.7/site-packages/pulumi/output.py", line 186, in run
        return await transformed.future(with_unknowns=True)
      File "/Users/<user>/renga/renku-gcp/venv/lib/python3.7/site-packages/pulumi/output.py", line 114, in get_value
        val = await self._future
      File "/Users/<user>/renga/renku-gcp/venv/lib/python3.7/site-packages/pulumi/output.py", line 155, in run
        value = await self._future
      File "/Users/<user>/renga/renku-gcp/venv/lib/python3.7/site-packages/pulumi/output.py", line 335, in gather_futures
        return await asyncio.gather(*value_futures)
      File "/Users/<user>/renga/renku-gcp/venv/lib/python3.7/site-packages/pulumi/output.py", line 114, in get_value
        val = await self._future
      File "/Users/<user>/renga/renku-gcp/venv/lib/python3.7/site-packages/pulumi/output.py", line 155, in run
        value = await self._future
      File "/Users/<user>/renga/renku-gcp/venv/lib/python3.7/site-packages/pulumi/output.py", line 176, in run
        transformed: Input[U] = func(value)
      File "/Users/<user>/renga/renku-gcp/venv/lib/python3.7/site-packages/pulumi_kubernetes/yaml.py", line 651, in <lambda>
        ConfigMap(f"{x}", opts, **obj)))]
    TypeError: __init__() got an unexpected keyword argument 'type'
    error: an unhandled error occurred: Program exited with non-zero exit code: 1

Suggestions for a fix

Ideally, pulumi-kubernetes would catch these errors and produce a more human readable error message, as it takes quite a while to debug otherwise. E.g. Invalid property 'type' present in resource 'fuseki-server-sh' in this case.

I'm not sure to what extent this affects all resources on this and the following lines in https://github.com/pulumi/pulumi-kubernetes/blob/master/sdk/python/pulumi_kubernetes/yaml.py#L187 (are resource properties verified before being passed to _parse_yaml_object(..)?) and if it's enough to wrap all of them in a try...catch.. around_parse_yaml_object(..).

pgavlin commented 4 years ago

Thanks for the report! Would throwing an error from the resource constructor would be more in line with what you'd expect?

Panaetius commented 4 years ago

An explicit check in the constructor to check for invalid properties would be even nicer, yes. As long as it mentions the name of the property and the name of the affected resource, i think that's the key information needed.

Thanks a lot for the quick reply and the awesome work you're doing, i really love pulumi and what it's doing!

lblackstone commented 1 year ago

The Python SDK includes much better type support now, so closing as fixed.