"""
# cdk8s

> Cloud Development Kit for Kubernetes

**cdk8s** is a software development framework for defining Kubernetes
applications using rich object-oriented APIs. It allows developers to leverage
the full power of software in order to define abstract components called
"constructs" which compose Kubernetes resources or other constructs into
higher-level abstractions.

This library is the foundation of **cdk8s**. It includes base types that are
used to define cdk8s applications.

## Chart

The `Chart` is a container that synthesizes a single Kubernetes manifest.

```python
# Example automatically generated without compilation. See https://github.com/aws/jsii/issues/826
class MyChart(Chart):
    def __init__(self, scope, ns):
        super().__init__(scope, ns)
```

During synthesis, charts collect all the `ApiObject` nodes (recursively) and
emit a single YAML manifest that includes all these objects.

## ApiObject

An `ApiObject` is a construct that represents an entry in a Kubernetes manifest.
In most cases, you won't use `ApiObject` directly but rather use classes that
are generated by the cdk8s CLI and extend this base class.

### Testing

cdk8s bundles a set of test utilities under the `Testing` class:

* `Testing.app()` returns an `App` object bound to a temporary output directory.
* `Testing.synth(chart)` returns the Kubernetes manifest synthesized from a
  chart.

## License

This project is distributed under the [Apache License, Version 2.0](./LICENSE).

This module is part of the [cdk8s project](https://github.com/awslabs/cdk8s).
"""
import abc
import builtins
import datetime
import enum
import typing

import jsii
import jsii.compat
import publication

import constructs

__jsii_assembly__ = jsii.JSIIAssembly.load("cdk8s", "0.16.0", __name__, "cdk8s@0.16.0.jsii.tgz")


class ApiObject(constructs.Construct, metaclass=jsii.JSIIMeta, jsii_type="cdk8s.ApiObject"):
    """
    stability
    :stability: experimental
    """
    def __init__(self, scope: constructs.Construct, ns: str, *, api_version: str, kind: str, data: typing.Any=None, metadata: typing.Optional["ApiObjectMetadata"]=None) -> None:
        """Defines an API object.

        :param scope: the construct scope.
        :param ns: namespace.
        :param api_version: API version.
        :param kind: Resource kind.
        :param data: Data associated with the resource.
        :param metadata: Object metadata. If ``name`` is not specified, an app-unique name will be allocated by the framework based on the path of the construct within thes construct tree.

        stability
        :stability: experimental
        """
        options = ApiObjectOptions(api_version=api_version, kind=kind, data=data, metadata=metadata)

        jsii.create(ApiObject, self, [scope, ns, options])

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.Any:
        """Renders the object to Kubernetes JSON.

        stability
        :stability: experimental
        """
        return jsii.invoke(self, "toJson", [])

    @builtins.property
    @jsii.member(jsii_name="apiVersion")
    def api_version(self) -> str:
        """The object's API version.

        stability
        :stability: experimental
        """
        return jsii.get(self, "apiVersion")

    @builtins.property
    @jsii.member(jsii_name="chart")
    def chart(self) -> "Chart":
        """The chart in which this object is defined.

        stability
        :stability: experimental
        """
        return jsii.get(self, "chart")

    @builtins.property
    @jsii.member(jsii_name="kind")
    def kind(self) -> str:
        """The object kind.

        stability
        :stability: experimental
        """
        return jsii.get(self, "kind")

    @builtins.property
    @jsii.member(jsii_name="name")
    def name(self) -> str:
        """The app-unique name of the object.

        The name is allocated based on the path of the object construct within the
        construct tree.

        stability
        :stability: experimental
        """
        return jsii.get(self, "name")


@jsii.data_type(jsii_type="cdk8s.ApiObjectMetadata", jsii_struct_bases=[], name_mapping={'name': 'name'})
class ApiObjectMetadata():
    def __init__(self, *, name: typing.Optional[str]=None):
        """Metadata associated with this object.

        :param name: The unique, namespace-global, name of this object inside the Kubernetes cluster. Normally, you shouldn't specify names for objects and let the CDK generate a name for you that is application-unique. The names CDK generates are composed from the construct path components, separated by dots and a suffix that is based on a hash of the entire path, to ensure uniqueness. You can supply custom name allocation logic by overriding the ``chart.generateObjectName`` method. If you use an explicit name here, bear in mind that this reduces the composability of your construct because it won't be possible to include more than one instance in any app. Therefore it is highly recommended to leave this unspecified. Default: - an app-unique name generated by the chart

        stability
        :stability: experimental
        """
        self._values = {
        }
        if name is not None: self._values["name"] = name

    @builtins.property
    def name(self) -> typing.Optional[str]:
        """The unique, namespace-global, name of this object inside the Kubernetes cluster.

        Normally, you shouldn't specify names for objects and let the CDK generate
        a name for you that is application-unique. The names CDK generates are
        composed from the construct path components, separated by dots and a suffix
        that is based on a hash of the entire path, to ensure uniqueness.

        You can supply custom name allocation logic by overriding the
        ``chart.generateObjectName`` method.

        If you use an explicit name here, bear in mind that this reduces the
        composability of your construct because it won't be possible to include
        more than one instance in any app. Therefore it is highly recommended to
        leave this unspecified.

        default
        :default: - an app-unique name generated by the chart

        stability
        :stability: experimental
        """
        return self._values.get('name')

    def __eq__(self, rhs) -> bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs) -> bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return 'ApiObjectMetadata(%s)' % ', '.join(k + '=' + repr(v) for k, v in self._values.items())


@jsii.data_type(jsii_type="cdk8s.ApiObjectOptions", jsii_struct_bases=[], name_mapping={'api_version': 'apiVersion', 'kind': 'kind', 'data': 'data', 'metadata': 'metadata'})
class ApiObjectOptions():
    def __init__(self, *, api_version: str, kind: str, data: typing.Any=None, metadata: typing.Optional["ApiObjectMetadata"]=None):
        """Options for defining API objects.

        :param api_version: API version.
        :param kind: Resource kind.
        :param data: Data associated with the resource.
        :param metadata: Object metadata. If ``name`` is not specified, an app-unique name will be allocated by the framework based on the path of the construct within thes construct tree.

        stability
        :stability: experimental
        """
        if isinstance(metadata, dict): metadata = ApiObjectMetadata(**metadata)
        self._values = {
            'api_version': api_version,
            'kind': kind,
        }
        if data is not None: self._values["data"] = data
        if metadata is not None: self._values["metadata"] = metadata

    @builtins.property
    def api_version(self) -> str:
        """API version.

        stability
        :stability: experimental
        """
        return self._values.get('api_version')

    @builtins.property
    def kind(self) -> str:
        """Resource kind.

        stability
        :stability: experimental
        """
        return self._values.get('kind')

    @builtins.property
    def data(self) -> typing.Any:
        """Data associated with the resource.

        stability
        :stability: experimental
        """
        return self._values.get('data')

    @builtins.property
    def metadata(self) -> typing.Optional["ApiObjectMetadata"]:
        """Object metadata.

        If ``name`` is not specified, an app-unique name will be allocated by the
        framework based on the path of the construct within thes construct tree.

        stability
        :stability: experimental
        """
        return self._values.get('metadata')

    def __eq__(self, rhs) -> bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs) -> bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return 'ApiObjectOptions(%s)' % ', '.join(k + '=' + repr(v) for k, v in self._values.items())


class App(constructs.Construct, metaclass=jsii.JSIIMeta, jsii_type="cdk8s.App"):
    """Represents a cdk8s application.

    stability
    :stability: experimental
    """
    def __init__(self, *, outdir: typing.Optional[str]=None) -> None:
        """Defines an app.

        :param outdir: The directory to output Kubernetes manifests. Default: - CDK8S_OUTDIR if defined, otherwise "dist"

        stability
        :stability: experimental
        """
        options = AppOptions(outdir=outdir)

        jsii.create(App, self, [options])

    @jsii.member(jsii_name="synth")
    def synth(self) -> None:
        """Synthesizes all manifests to the output directory.

        stability
        :stability: experimental
        """
        return jsii.invoke(self, "synth", [])

    @builtins.property
    @jsii.member(jsii_name="outdir")
    def outdir(self) -> str:
        """The output directory into which manifests will be synthesized.

        stability
        :stability: experimental
        """
        return jsii.get(self, "outdir")


@jsii.data_type(jsii_type="cdk8s.AppOptions", jsii_struct_bases=[], name_mapping={'outdir': 'outdir'})
class AppOptions():
    def __init__(self, *, outdir: typing.Optional[str]=None):
        """
        :param outdir: The directory to output Kubernetes manifests. Default: - CDK8S_OUTDIR if defined, otherwise "dist"

        stability
        :stability: experimental
        """
        self._values = {
        }
        if outdir is not None: self._values["outdir"] = outdir

    @builtins.property
    def outdir(self) -> typing.Optional[str]:
        """The directory to output Kubernetes manifests.

        default
        :default: - CDK8S_OUTDIR if defined, otherwise "dist"

        stability
        :stability: experimental
        """
        return self._values.get('outdir')

    def __eq__(self, rhs) -> bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs) -> bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return 'AppOptions(%s)' % ', '.join(k + '=' + repr(v) for k, v in self._values.items())


class Chart(constructs.Construct, metaclass=jsii.JSIIMeta, jsii_type="cdk8s.Chart"):
    """
    stability
    :stability: experimental
    """
    def __init__(self, scope: constructs.Construct, ns: str, *, namespace: typing.Optional[str]=None) -> None:
        """
        :param scope: -
        :param ns: -
        :param namespace: The default namespace for all objects defined in this chart (directly or indirectly). This namespace will only apply to objects that don't have a ``namespace`` explicitly defined for them. Default: - no namespace is synthesized (usually this implies "default")

        stability
        :stability: experimental
        """
        options = ChartOptions(namespace=namespace)

        jsii.create(Chart, self, [scope, ns, options])

    @jsii.member(jsii_name="of")
    @builtins.classmethod
    def of(cls, c: constructs.Construct) -> "Chart":
        """Finds the chart in which a node is defined.

        :param c: a construct node.

        stability
        :stability: experimental
        """
        return jsii.sinvoke(cls, "of", [c])

    @jsii.member(jsii_name="generateObjectName")
    def generate_object_name(self, api_object: "ApiObject") -> str:
        """Generates a app-unique name for an object given it's construct node path.

        Different resource types may have different constraints on names
        (``metadata.name``). The previous version of the name generator was
        compatible with DNS_SUBDOMAIN but not with DNS_LABEL.

        For example, ``Deployment`` names must comply with DNS_SUBDOMAIN while
        ``Service`` names must comply with DNS_LABEL.

        Since there is no formal specification for this, the default name
        generation scheme for kubernetes objects in cdk8s was changed to DNS_LABEL,
        since it’s the common denominator for all kubernetes resources
        (supposedly).

        You can override this method if you wish to customize object names at the
        chart level.

        :param api_object: The API object to generate a name for.

        stability
        :stability: experimental
        """
        return jsii.invoke(self, "generateObjectName", [api_object])

    @jsii.member(jsii_name="onSynthesize")
    def _on_synthesize(self, session: constructs.ISynthesisSession) -> None:
        """Called by the app to synthesize the chart as a YAML file in the output directory/.

        :param session: -

        stability
        :stability: experimental
        """
        return jsii.invoke(self, "onSynthesize", [session])

    @jsii.member(jsii_name="toJson")
    def to_json(self) -> typing.List[typing.Any]:
        """Renders this chart to a set of Kubernetes JSON resources.

        return
        :return: array of resource manifests

        stability
        :stability: experimental
        """
        return jsii.invoke(self, "toJson", [])

    @builtins.property
    @jsii.member(jsii_name="manifestFile")
    def manifest_file(self) -> str:
        """The name of the stack's YAML file as emitted into the cloud assembly directory during synthesis.

        stability
        :stability: experimental
        """
        return jsii.get(self, "manifestFile")

    @builtins.property
    @jsii.member(jsii_name="namespace")
    def namespace(self) -> typing.Optional[str]:
        """The default namespace for all objects in this chart.

        stability
        :stability: experimental
        """
        return jsii.get(self, "namespace")


@jsii.data_type(jsii_type="cdk8s.ChartOptions", jsii_struct_bases=[], name_mapping={'namespace': 'namespace'})
class ChartOptions():
    def __init__(self, *, namespace: typing.Optional[str]=None):
        """
        :param namespace: The default namespace for all objects defined in this chart (directly or indirectly). This namespace will only apply to objects that don't have a ``namespace`` explicitly defined for them. Default: - no namespace is synthesized (usually this implies "default")

        stability
        :stability: experimental
        """
        self._values = {
        }
        if namespace is not None: self._values["namespace"] = namespace

    @builtins.property
    def namespace(self) -> typing.Optional[str]:
        """The default namespace for all objects defined in this chart (directly or indirectly).

        This namespace will only apply to objects that don't have a
        ``namespace`` explicitly defined for them.

        default
        :default: - no namespace is synthesized (usually this implies "default")

        stability
        :stability: experimental
        """
        return self._values.get('namespace')

    def __eq__(self, rhs) -> bool:
        return isinstance(rhs, self.__class__) and rhs._values == self._values

    def __ne__(self, rhs) -> bool:
        return not (rhs == self)

    def __repr__(self) -> str:
        return 'ChartOptions(%s)' % ', '.join(k + '=' + repr(v) for k, v in self._values.items())


class Testing(metaclass=jsii.JSIIMeta, jsii_type="cdk8s.Testing"):
    """Testing utilities for cdk8s applications.

    stability
    :stability: experimental
    """
    @jsii.member(jsii_name="app")
    @builtins.classmethod
    def app(cls) -> "App":
        """Returns an app for testing with the following properties: - Output directory is a temp dir.

        stability
        :stability: experimental
        """
        return jsii.sinvoke(cls, "app", [])

    @jsii.member(jsii_name="synth")
    @builtins.classmethod
    def synth(cls, chart: "Chart") -> typing.List[typing.Any]:
        """Returns the Kubernetes manifest synthesized from this chart.

        :param chart: -

        stability
        :stability: experimental
        """
        return jsii.sinvoke(cls, "synth", [chart])


__all__ = ["ApiObject", "ApiObjectMetadata", "ApiObjectOptions", "App", "AppOptions", "Chart", "ChartOptions", "Testing", "__jsii_assembly__"]

publication.publish()
