# generated by datamodel-codegen:
#   filename:  ecs-files-input.json
#   timestamp: 2023-02-28T08:48:36+00:00

from __future__ import annotations

from enum import Enum
from typing import Any, Dict, List, Optional, Union

from pydantic import AnyUrl, BaseModel, EmailStr, Extra, Field, constr


class S3Uri(BaseModel):
    __root__: str = Field(
        ...,
        description="s3://bucket-name/path/to/file simple syntax. Does not support IamOverride",
        regex="^s3://([a-zA-Z\\d\\-.]+)/([\\S]+)$",
    )


class ComposeXUri(BaseModel):
    __root__: str = Field(
        ...,
        description="bucket_name::path/to/file format used in other compose-x projects",
        regex="([a-zA-Z\\-\\d.]+)::([\\S]+)$",
    )


class Encoding(Enum):
    base64 = "base64"
    plain = "plain"


class Context(Enum):
    plain = "plain"
    jinja2 = "jinja2"


class IgnoreFailureItem(BaseModel):
    class Config:
        extra = Extra.forbid

    commands: Optional[bool] = Field(
        False, description="Ignore if any of the commands failed"
    )
    mode: Optional[bool] = Field(
        False, description="Ignore if `mode` (using chmod) failed."
    )
    owner: Optional[bool] = Field(
        False, description="Ignore if `owner` (using chown) failed"
    )
    source_download: Optional[bool] = Field(
        False,
        description="Ignore if a Source download failed. Any subsequent action is cancelled.",
    )


class UrlDef(BaseModel):
    url: Optional[AnyUrl] = Field(None, alias="Url")
    username: Optional[str] = Field(None, alias="Username")
    password: Optional[str] = Field(None, alias="Password")


class IamOverrideDef(BaseModel):
    role_arn: Optional[str] = Field(None, alias="RoleArn")
    session_name: Optional[str] = Field(
        "S3File@EcsConfigComposer",
        alias="SessionName",
        description="Name of the IAM session",
    )
    external_id: Optional[str] = Field(
        None,
        alias="ExternalId",
        description="The External ID to use when using sts:AssumeRole",
    )
    region_name: Optional[str] = Field(None, alias="RegionName")
    access_key_id: Optional[str] = Field(
        None, alias="AccessKeyId", description="AWS Access Key Id to use for session"
    )
    secret_access_key: Optional[str] = Field(
        None, alias="SecretAccessKey", description="AWS Secret Key to use for session"
    )
    session_token: Optional[str] = Field(None, alias="SessionToken")


class CommandsDef(BaseModel):
    __root__: List[str] = Field(..., description="List of commands to run")


class JksConfig(BaseModel):
    class Config:
        extra = Extra.forbid

    file_name: str = Field(
        ..., alias="fileName", description="Name of the JKS file to create"
    )
    passphrase: str = Field(
        ..., description="The passphrase to use to secure the jks and certificate"
    )


class CertbotAwsStoreCertificate(BaseModel):
    storage_path: str = Field(
        ...,
        description="path to folder to store the certbot certificates into.",
        regex="^/[\\x00-\\x7F]+$",
    )
    certificates_registry_table_name: Optional[str] = Field(
        None, description="Override the top level certificates_registry_table_name"
    )
    certificates_registry_table_region: Optional[str] = Field(
        None, description="Override the top level certificates_registry_table_region"
    )


class CertbotStore(BaseModel):
    certificates_registry_table_name: Optional[str] = Field(
        "certbot-registry", description="default table name to query for certificates."
    )
    certificates_registry_table_region: Optional[str] = Field(
        None,
        description="region to use for the certificates_registry_table_name. Defaults to current region found in profiles chain.",
    )
    certificates: Optional[Dict[str, CertbotAwsStoreCertificate]] = None


class Commands(BaseModel):
    class Config:
        extra = Extra.forbid

    post: Optional[CommandsDef] = Field(
        None, description="Commands to run after the file was retrieved"
    )
    pre: Optional[CommandsDef] = Field(
        None,
        description="Commands executed prior to the file being fetched, after `depends_on` completed",
    )


class SsmDef(BaseModel):
    parameter_name: Optional[str] = Field(None, alias="ParameterName")
    iam_override: Optional[IamOverrideDef] = Field(None, alias="IamOverride")


class SecretDef(BaseModel):
    secret_id: str = Field(..., alias="SecretId")
    version_id: Optional[str] = Field(None, alias="VersionId")
    version_stage: Optional[str] = Field(None, alias="VersionStage")
    json_key: Optional[str] = Field(
        None,
        alias="JsonKey",
        description="If the SecretString is a valid JSON, use the Key to map to the value stored in secret",
    )
    iam_override: Optional[IamOverrideDef] = Field(None, alias="IamOverride")


class S3Def1(BaseModel):
    s3_uri: Optional[S3Uri] = Field(None, alias="S3Uri")
    compose_x_uri: Optional[ComposeXUri] = Field(None, alias="ComposeXUri")
    bucket_name: Optional[str] = Field(
        None, alias="BucketName", description="Name of the S3 Bucket"
    )
    bucket_region: Optional[str] = Field(
        None,
        alias="BucketRegion",
        description="S3 Region to use. Default will ignore or retrieve via s3:GetBucketLocation",
    )
    key: Optional[str] = Field(
        None, alias="Key", description="Full path to the file to retrieve"
    )
    iam_override: Optional[IamOverrideDef] = Field(None, alias="IamOverride")


class S3Def(BaseModel):
    __root__: Union[S3Def1, Any, Any, Any]


class X509CertDef(BaseModel):
    class Config:
        extra = Extra.allow

    dir_path: Optional[str] = None
    email_address: Optional[EmailStr] = Field(
        "files-composer@compose-x.tld", alias="emailAddress"
    )
    common_name: Optional[
        constr(
            regex=r"^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]{0,61}[A-Za-z0-9])\Z"
        )
    ] = Field(None, alias="commonName")
    country_name: Optional[str] = Field("ZZ", alias="countryName", regex="^[A-Z]+$")
    locality_name: Optional[str] = Field("Anywhere", alias="localityName")
    state_or_province_name: Optional[str] = Field("Shire", alias="stateOrProvinceName")
    organization_name: Optional[str] = Field("NoOne", alias="organizationName")
    organization_unit_name: Optional[str] = Field(
        "Automation", alias="organizationUnitName"
    )
    validity_end_in_seconds: Optional[float] = Field(
        8035200,
        alias="validityEndInSeconds",
        description="Validity before cert expires, in seconds. Default 3*31*24*60*60=3Months",
    )
    key_file_name: str = Field(..., alias="keyFileName")
    cert_file_name: str = Field(..., alias="certFileName")
    group: Optional[str] = Field(
        "root",
        description="UNIX group name or GID owner of the file. Default to root(0)",
    )
    owner: Optional[str] = Field(
        "root", description="UNIX user or UID owner of the file. Default to root(0)"
    )
    jks_config: Optional[JksConfig] = Field(None, alias="jksConfig")


class Certificates(BaseModel):
    class Config:
        extra = Extra.forbid

    x509: Optional[Dict[str, X509CertDef]] = None


class SourceDef(BaseModel):
    url: Optional[UrlDef] = Field(None, alias="Url")
    ssm: Optional[SsmDef] = Field(None, alias="Ssm")
    s3: Optional[S3Def] = Field(None, alias="S3")
    secret: Optional[SecretDef] = Field(None, alias="Secret")


class FileDef(BaseModel):
    class Config:
        extra = Extra.allow

    path: Optional[str] = None
    content: Optional[str] = Field(
        None, description="The raw content of the file to use"
    )
    source: Optional[SourceDef] = None
    encoding: Optional[Encoding] = "plain"
    group: Optional[str] = Field(
        "root",
        description="UNIX group name or GID owner of the file. Default to root(0)",
    )
    owner: Optional[str] = Field(
        "root", description="UNIX user or UID owner of the file. Default to root(0)"
    )
    mode: Optional[str] = Field("0644", description="UNIX file mode")
    context: Optional[Context] = "plain"
    ignore_failure: Optional[Union[IgnoreFailureItem, bool]] = None
    commands: Optional[Commands] = None


class Model(BaseModel):
    files: Optional[Dict[str, FileDef]] = None
    certificates: Optional[Certificates] = None
    certbot_store: Optional[CertbotStore] = None
    iam_override: Optional[IamOverrideDef] = Field(None, alias="IamOverride")
