// WARNING: generated by kopium - manual changes will be overwritten
// kopium command: kopium -D Default -D PartialEq -A -d openstackmachinetemplates.infrastructure.cluster.x-k8s.io
// kopium version: 0.21.1

#[allow(unused_imports)]
mod prelude {
    pub use kube::CustomResource;
    pub use schemars::JsonSchema;
    pub use serde::{Deserialize, Serialize};
}
use self::prelude::*;

/// OpenStackMachineTemplateSpec defines the desired state of OpenStackMachineTemplate.
#[derive(CustomResource, Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
#[kube(
    group = "infrastructure.cluster.x-k8s.io",
    version = "v1beta1",
    kind = "OpenStackMachineTemplate",
    plural = "openstackmachinetemplates"
)]
#[kube(namespaced)]
#[kube(derive = "Default")]
#[kube(derive = "PartialEq")]
pub struct OpenStackMachineTemplateSpec {
    /// OpenStackMachineTemplateResource describes the data needed to create a OpenStackMachine from a template.
    pub template: OpenStackMachineTemplateTemplate,
}

/// OpenStackMachineTemplateResource describes the data needed to create a OpenStackMachine from a template.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplate {
    /// Spec is the specification of the desired behavior of the machine.
    pub spec: OpenStackMachineTemplateTemplateSpec,
}

/// Spec is the specification of the desired behavior of the machine.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpec {
    /// AdditionalBlockDevices is a list of specifications for additional block devices to attach to the server instance
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "additionalBlockDevices"
    )]
    pub additional_block_devices:
        Option<Vec<OpenStackMachineTemplateTemplateSpecAdditionalBlockDevices>>,
    /// Config Drive support
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "configDrive"
    )]
    pub config_drive: Option<bool>,
    /// The flavor reference for the flavor for your server instance.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub flavor: Option<String>,
    /// FlavorID allows flavors to be specified by ID.  This field takes precedence
    /// over Flavor.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "flavorID")]
    pub flavor_id: Option<String>,
    /// floatingIPPoolRef is a reference to a IPPool that will be assigned
    /// to an IPAddressClaim. Once the IPAddressClaim is fulfilled, the FloatingIP
    /// will be assigned to the OpenStackMachine.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "floatingIPPoolRef"
    )]
    pub floating_ip_pool_ref: Option<OpenStackMachineTemplateTemplateSpecFloatingIpPoolRef>,
    /// IdentityRef is a reference to a secret holding OpenStack credentials
    /// to be used when reconciling this machine. If not specified, the
    /// credentials specified in the cluster will be used.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "identityRef"
    )]
    pub identity_ref: Option<OpenStackMachineTemplateTemplateSpecIdentityRef>,
    /// The image to use for your server instance.
    /// If the rootVolume is specified, this will be used when creating the root volume.
    pub image: OpenStackMachineTemplateTemplateSpecImage,
    /// Ports to be attached to the server instance. They are created if a port with the given name does not already exist.
    /// If not specified a default port will be added for the default cluster network.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub ports: Option<Vec<OpenStackMachineTemplateTemplateSpecPorts>>,
    /// ProviderID is the unique identifier as specified by the cloud provider.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "providerID"
    )]
    pub provider_id: Option<String>,
    /// The volume metadata to boot from
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "rootVolume"
    )]
    pub root_volume: Option<OpenStackMachineTemplateTemplateSpecRootVolume>,
    /// SchedulerHintAdditionalProperties are arbitrary key/value pairs that provide additional hints
    /// to the OpenStack scheduler. These hints can influence how instances are placed on the infrastructure,
    /// such as specifying certain host aggregates or availability zones.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "schedulerHintAdditionalProperties"
    )]
    pub scheduler_hint_additional_properties:
        Option<Vec<OpenStackMachineTemplateTemplateSpecSchedulerHintAdditionalProperties>>,
    /// The names of the security groups to assign to the instance
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "securityGroups"
    )]
    pub security_groups: Option<Vec<OpenStackMachineTemplateTemplateSpecSecurityGroups>>,
    /// The server group to assign the machine to.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "serverGroup"
    )]
    pub server_group: Option<OpenStackMachineTemplateTemplateSpecServerGroup>,
    /// Metadata mapping. Allows you to create a map of key value pairs to add to the server instance.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "serverMetadata"
    )]
    pub server_metadata: Option<Vec<OpenStackMachineTemplateTemplateSpecServerMetadata>>,
    /// The ssh key to inject in the instance
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "sshKeyName"
    )]
    pub ssh_key_name: Option<String>,
    /// Tags which will be added to the machine and all dependent resources
    /// which support them. These are in addition to Tags defined on the
    /// cluster.
    /// Requires Nova api 2.52 minimum!
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub tags: Option<Vec<String>>,
    /// Whether the server instance is created on a trunk port or not.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub trunk: Option<bool>,
}

/// AdditionalBlockDevice is a block device to attach to the server.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecAdditionalBlockDevices {
    /// Name of the block device in the context of a machine.
    /// If the block device is a volume, the Cinder volume will be named
    /// as a combination of the machine name and this name.
    /// Also, this name will be used for tagging the block device.
    /// Information about the block device tag can be obtained from the OpenStack
    /// metadata API or the config drive.
    /// Name cannot be 'root', which is reserved for the root volume.
    pub name: String,
    /// SizeGiB is the size of the block device in gibibytes (GiB).
    #[serde(rename = "sizeGiB")]
    pub size_gi_b: i64,
    /// Storage specifies the storage type of the block device and
    /// additional storage options.
    pub storage: OpenStackMachineTemplateTemplateSpecAdditionalBlockDevicesStorage,
}

/// Storage specifies the storage type of the block device and
/// additional storage options.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecAdditionalBlockDevicesStorage {
    /// Type is the type of block device to create.
    /// This can be either "Volume" or "Local".
    #[serde(rename = "type")]
    pub r#type: String,
    /// Volume contains additional storage options for a volume block device.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub volume: Option<OpenStackMachineTemplateTemplateSpecAdditionalBlockDevicesStorageVolume>,
}

/// Volume contains additional storage options for a volume block device.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecAdditionalBlockDevicesStorageVolume {
    /// AvailabilityZone is the volume availability zone to create the volume
    /// in. If not specified, the volume will be created without an explicit
    /// availability zone.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "availabilityZone"
    )]
    pub availability_zone: Option<
        OpenStackMachineTemplateTemplateSpecAdditionalBlockDevicesStorageVolumeAvailabilityZone,
    >,
    /// Type is the Cinder volume type of the volume.
    /// If omitted, the default Cinder volume type that is configured in the OpenStack cloud
    /// will be used.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "type")]
    pub r#type: Option<String>,
}

/// AvailabilityZone is the volume availability zone to create the volume
/// in. If not specified, the volume will be created without an explicit
/// availability zone.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecAdditionalBlockDevicesStorageVolumeAvailabilityZone {
    /// From specifies where we will obtain the availability zone for the
    /// volume. The options are "Name" and "Machine". If "Name" is specified
    /// then the Name field must also be specified. If "Machine" is specified
    /// the volume will use the value of FailureDomain, if any, from the
    /// associated Machine.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub from: Option<
        OpenStackMachineTemplateTemplateSpecAdditionalBlockDevicesStorageVolumeAvailabilityZoneFrom,
    >,
    /// Name is the name of a volume availability zone to use. It is required
    /// if From is "Name". The volume availability zone name may not contain
    /// spaces.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
}

/// AvailabilityZone is the volume availability zone to create the volume
/// in. If not specified, the volume will be created without an explicit
/// availability zone.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub enum OpenStackMachineTemplateTemplateSpecAdditionalBlockDevicesStorageVolumeAvailabilityZoneFrom
{
    Name,
    Machine,
}

/// floatingIPPoolRef is a reference to a IPPool that will be assigned
/// to an IPAddressClaim. Once the IPAddressClaim is fulfilled, the FloatingIP
/// will be assigned to the OpenStackMachine.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecFloatingIpPoolRef {
    /// APIGroup is the group for the resource being referenced.
    /// If APIGroup is not specified, the specified Kind must be in the core API group.
    /// For any other third-party types, APIGroup is required.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "apiGroup")]
    pub api_group: Option<String>,
    /// Kind is the type of resource being referenced
    pub kind: String,
    /// Name is the name of resource being referenced
    pub name: String,
}

/// IdentityRef is a reference to a secret holding OpenStack credentials
/// to be used when reconciling this machine. If not specified, the
/// credentials specified in the cluster will be used.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecIdentityRef {
    /// CloudName specifies the name of the entry in the clouds.yaml file to use.
    #[serde(rename = "cloudName")]
    pub cloud_name: String,
    /// Name is the name of a secret in the same namespace as the resource being provisioned.
    /// The secret must contain a key named `clouds.yaml` which contains an OpenStack clouds.yaml file.
    /// The secret may optionally contain a key named `cacert` containing a PEM-encoded CA certificate.
    pub name: String,
    /// Region specifies an OpenStack region to use. If specified, it overrides
    /// any value in clouds.yaml. If specified for an OpenStackMachine, its
    /// value will be included in providerID.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub region: Option<String>,
}

/// The image to use for your server instance.
/// If the rootVolume is specified, this will be used when creating the root volume.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecImage {
    /// Filter describes a query for an image. If specified, the combination
    /// of name and tags must return a single matching image or an error will
    /// be raised.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub filter: Option<OpenStackMachineTemplateTemplateSpecImageFilter>,
    /// ID is the uuid of the image. ID will not be validated before use.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
    /// ImageRef is a reference to an ORC Image in the same namespace as the
    /// referring object.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "imageRef")]
    pub image_ref: Option<OpenStackMachineTemplateTemplateSpecImageImageRef>,
}

/// Filter describes a query for an image. If specified, the combination
/// of name and tags must return a single matching image or an error will
/// be raised.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecImageFilter {
    /// The name of the desired image. If specified, the combination of name and tags must return a single matching image or an error will be raised.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
    /// The tags associated with the desired image. If specified, the combination of name and tags must return a single matching image or an error will be raised.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub tags: Option<Vec<String>>,
}

/// ImageRef is a reference to an ORC Image in the same namespace as the
/// referring object.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecImageImageRef {
    /// Name is the name of the referenced resource
    pub name: String,
}

#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecPorts {
    /// AdminStateUp specifies whether the port should be created in the up (true) or down (false) state. The default is up.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "adminStateUp"
    )]
    pub admin_state_up: Option<bool>,
    /// AllowedAddressPairs is a list of address pairs which Neutron will
    /// allow the port to send traffic from in addition to the port's
    /// addresses. If not specified, the MAC Address will be the MAC Address
    /// of the port. Depending on the configuration of Neutron, it may be
    /// supported to specify a CIDR instead of a specific IP address.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "allowedAddressPairs"
    )]
    pub allowed_address_pairs:
        Option<Vec<OpenStackMachineTemplateTemplateSpecPortsAllowedAddressPairs>>,
    /// Description is a human-readable description for the port.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub description: Option<String>,
    /// DisablePortSecurity enables or disables the port security when set.
    /// When not set, it takes the value of the corresponding field at the network level.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "disablePortSecurity"
    )]
    pub disable_port_security: Option<bool>,
    /// FixedIPs is a list of pairs of subnet and/or IP address to assign to the port. If specified, these must be subnets of the port's network.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "fixedIPs")]
    pub fixed_i_ps: Option<Vec<OpenStackMachineTemplateTemplateSpecPortsFixedIPs>>,
    /// HostID specifies the ID of the host where the port resides.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "hostID")]
    pub host_id: Option<String>,
    /// MACAddress specifies the MAC address of the port. If not specified, the MAC address will be generated.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "macAddress"
    )]
    pub mac_address: Option<String>,
    /// NameSuffix will be appended to the name of the port if specified. If unspecified, instead the 0-based index of the port in the list is used.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "nameSuffix"
    )]
    pub name_suffix: Option<String>,
    /// Network is a query for an openstack network that the port will be created or discovered on.
    /// This will fail if the query returns more than one network.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub network: Option<OpenStackMachineTemplateTemplateSpecPortsNetwork>,
    /// Profile is a set of key-value pairs that are used for binding
    /// details. We intentionally don't expose this as a map[string]string
    /// because we only want to enable the users to set the values of the
    /// keys that are known to work in OpenStack Networking API.  See
    /// https://docs.openstack.org/api-ref/network/v2/index.html?expanded=create-port-detail#create-port
    /// To set profiles, your tenant needs permissions rule:create_port, and
    /// rule:create_port:binding:profile
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub profile: Option<OpenStackMachineTemplateTemplateSpecPortsProfile>,
    /// PropageteUplinkStatus enables or disables the propagate uplink status on the port.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "propagateUplinkStatus"
    )]
    pub propagate_uplink_status: Option<bool>,
    /// SecurityGroups is a list of the names, uuids, filters or any combination these of the security groups to assign to the instance.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "securityGroups"
    )]
    pub security_groups: Option<Vec<OpenStackMachineTemplateTemplateSpecPortsSecurityGroups>>,
    /// Tags applied to the port (and corresponding trunk, if a trunk is configured.)
    /// These tags are applied in addition to the instance's tags, which will also be applied to the port.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub tags: Option<Vec<String>>,
    /// Trunk specifies whether trunking is enabled at the port level. If not
    /// provided the value is inherited from the machine, or false for a
    /// bastion host.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub trunk: Option<bool>,
    /// Value specs are extra parameters to include in the API request with OpenStack.
    /// This is an extension point for the API, so what they do and if they are supported,
    /// depends on the specific OpenStack implementation.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "valueSpecs"
    )]
    pub value_specs: Option<Vec<OpenStackMachineTemplateTemplateSpecPortsValueSpecs>>,
    /// VNICType specifies the type of vNIC which this port should be
    /// attached to. This is used to determine which mechanism driver(s) to
    /// be used to bind the port. The valid values are normal, macvtap,
    /// direct, baremetal, direct-physical, virtio-forwarder, smart-nic and
    /// remote-managed, although these values will not be validated in this
    /// API to ensure compatibility with future neutron changes or custom
    /// implementations. What type of vNIC is actually available depends on
    /// deployments. If not specified, the Neutron default value is used.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "vnicType")]
    pub vnic_type: Option<String>,
}

#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecPortsAllowedAddressPairs {
    /// IPAddress is the IP address of the allowed address pair. Depending on
    /// the configuration of Neutron, it may be supported to specify a CIDR
    /// instead of a specific IP address.
    #[serde(rename = "ipAddress")]
    pub ip_address: String,
    /// MACAddress is the MAC address of the allowed address pair. If not
    /// specified, the MAC address will be the MAC address of the port.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "macAddress"
    )]
    pub mac_address: Option<String>,
}

#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecPortsFixedIPs {
    /// IPAddress is a specific IP address to assign to the port. If Subnet
    /// is also specified, IPAddress must be a valid IP address in the
    /// subnet. If Subnet is not specified, IPAddress must be a valid IP
    /// address in any subnet of the port's network.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "ipAddress")]
    pub ip_address: Option<String>,
    /// Subnet is an openstack subnet query that will return the id of a subnet to create
    /// the fixed IP of a port in. This query must not return more than one subnet.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub subnet: Option<OpenStackMachineTemplateTemplateSpecPortsFixedIPsSubnet>,
}

/// Subnet is an openstack subnet query that will return the id of a subnet to create
/// the fixed IP of a port in. This query must not return more than one subnet.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecPortsFixedIPsSubnet {
    /// Filter specifies a filter to select the subnet. It must match exactly one subnet.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub filter: Option<OpenStackMachineTemplateTemplateSpecPortsFixedIPsSubnetFilter>,
    /// ID is the uuid of the subnet. It will not be validated.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
}

/// Filter specifies a filter to select the subnet. It must match exactly one subnet.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecPortsFixedIPsSubnetFilter {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub cidr: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub description: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "gatewayIP")]
    pub gateway_ip: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "ipVersion")]
    pub ip_version: Option<i64>,
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "ipv6AddressMode"
    )]
    pub ipv6_address_mode: Option<String>,
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "ipv6RAMode"
    )]
    pub ipv6_ra_mode: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
    /// NotTags is a list of tags to filter by. If specified, resources which
    /// contain all of the given tags will be excluded from the result.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "notTags")]
    pub not_tags: Option<Vec<String>>,
    /// NotTagsAny is a list of tags to filter by. If specified, resources
    /// which contain any of the given tags will be excluded from the result.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "notTagsAny"
    )]
    pub not_tags_any: Option<Vec<String>>,
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "projectID")]
    pub project_id: Option<String>,
    /// Tags is a list of tags to filter by. If specified, the resource must
    /// have all of the tags specified to be included in the result.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub tags: Option<Vec<String>>,
    /// TagsAny is a list of tags to filter by. If specified, the resource
    /// must have at least one of the tags specified to be included in the
    /// result.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "tagsAny")]
    pub tags_any: Option<Vec<String>>,
}

/// Network is a query for an openstack network that the port will be created or discovered on.
/// This will fail if the query returns more than one network.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecPortsNetwork {
    /// Filter specifies a filter to select an OpenStack network. If provided, cannot be empty.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub filter: Option<OpenStackMachineTemplateTemplateSpecPortsNetworkFilter>,
    /// ID is the ID of the network to use. If ID is provided, the other filters cannot be provided. Must be in UUID format.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
}

/// Filter specifies a filter to select an OpenStack network. If provided, cannot be empty.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecPortsNetworkFilter {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub description: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
    /// NotTags is a list of tags to filter by. If specified, resources which
    /// contain all of the given tags will be excluded from the result.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "notTags")]
    pub not_tags: Option<Vec<String>>,
    /// NotTagsAny is a list of tags to filter by. If specified, resources
    /// which contain any of the given tags will be excluded from the result.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "notTagsAny"
    )]
    pub not_tags_any: Option<Vec<String>>,
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "projectID")]
    pub project_id: Option<String>,
    /// Tags is a list of tags to filter by. If specified, the resource must
    /// have all of the tags specified to be included in the result.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub tags: Option<Vec<String>>,
    /// TagsAny is a list of tags to filter by. If specified, the resource
    /// must have at least one of the tags specified to be included in the
    /// result.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "tagsAny")]
    pub tags_any: Option<Vec<String>>,
}

/// Profile is a set of key-value pairs that are used for binding
/// details. We intentionally don't expose this as a map[string]string
/// because we only want to enable the users to set the values of the
/// keys that are known to work in OpenStack Networking API.  See
/// https://docs.openstack.org/api-ref/network/v2/index.html?expanded=create-port-detail#create-port
/// To set profiles, your tenant needs permissions rule:create_port, and
/// rule:create_port:binding:profile
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecPortsProfile {
    /// OVSHWOffload enables or disables the OVS hardware offload feature.
    /// This flag is not required on OpenStack clouds since Yoga as Nova will set it automatically when the port is attached.
    /// See: https://bugs.launchpad.net/nova/+bug/2020813
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "ovsHWOffload"
    )]
    pub ovs_hw_offload: Option<bool>,
    /// TrustedVF enables or disables the “trusted mode” for the VF.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "trustedVF")]
    pub trusted_vf: Option<bool>,
}

/// SecurityGroupParam specifies an OpenStack security group. It may be specified by ID or filter, but not both.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecPortsSecurityGroups {
    /// Filter specifies a query to select an OpenStack security group. If provided, cannot be empty.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub filter: Option<OpenStackMachineTemplateTemplateSpecPortsSecurityGroupsFilter>,
    /// ID is the ID of the security group to use. If ID is provided, the other filters cannot be provided. Must be in UUID format.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
}

/// Filter specifies a query to select an OpenStack security group. If provided, cannot be empty.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecPortsSecurityGroupsFilter {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub description: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
    /// NotTags is a list of tags to filter by. If specified, resources which
    /// contain all of the given tags will be excluded from the result.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "notTags")]
    pub not_tags: Option<Vec<String>>,
    /// NotTagsAny is a list of tags to filter by. If specified, resources
    /// which contain any of the given tags will be excluded from the result.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "notTagsAny"
    )]
    pub not_tags_any: Option<Vec<String>>,
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "projectID")]
    pub project_id: Option<String>,
    /// Tags is a list of tags to filter by. If specified, the resource must
    /// have all of the tags specified to be included in the result.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub tags: Option<Vec<String>>,
    /// TagsAny is a list of tags to filter by. If specified, the resource
    /// must have at least one of the tags specified to be included in the
    /// result.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "tagsAny")]
    pub tags_any: Option<Vec<String>>,
}

/// ValueSpec represents a single value_spec key-value pair.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecPortsValueSpecs {
    /// Key is the key in the key-value pair.
    pub key: String,
    /// Name is the name of the key-value pair.
    /// This is just for identifying the pair and will not be sent to the OpenStack API.
    pub name: String,
    /// Value is the value in the key-value pair.
    pub value: String,
}

/// The volume metadata to boot from
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecRootVolume {
    /// AvailabilityZone is the volume availability zone to create the volume
    /// in. If not specified, the volume will be created without an explicit
    /// availability zone.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "availabilityZone"
    )]
    pub availability_zone: Option<OpenStackMachineTemplateTemplateSpecRootVolumeAvailabilityZone>,
    /// SizeGiB is the size of the block device in gibibytes (GiB).
    #[serde(rename = "sizeGiB")]
    pub size_gi_b: i64,
    /// Type is the Cinder volume type of the volume.
    /// If omitted, the default Cinder volume type that is configured in the OpenStack cloud
    /// will be used.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "type")]
    pub r#type: Option<String>,
}

/// AvailabilityZone is the volume availability zone to create the volume
/// in. If not specified, the volume will be created without an explicit
/// availability zone.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecRootVolumeAvailabilityZone {
    /// From specifies where we will obtain the availability zone for the
    /// volume. The options are "Name" and "Machine". If "Name" is specified
    /// then the Name field must also be specified. If "Machine" is specified
    /// the volume will use the value of FailureDomain, if any, from the
    /// associated Machine.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub from: Option<OpenStackMachineTemplateTemplateSpecRootVolumeAvailabilityZoneFrom>,
    /// Name is the name of a volume availability zone to use. It is required
    /// if From is "Name". The volume availability zone name may not contain
    /// spaces.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
}

/// AvailabilityZone is the volume availability zone to create the volume
/// in. If not specified, the volume will be created without an explicit
/// availability zone.
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, JsonSchema)]
pub enum OpenStackMachineTemplateTemplateSpecRootVolumeAvailabilityZoneFrom {
    Name,
    Machine,
}

/// SchedulerHintAdditionalProperty represents a single additional property for a scheduler hint.
/// It includes a Name to identify the property and a Value that can be of various types.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecSchedulerHintAdditionalProperties {
    /// Name is the name of the scheduler hint property.
    /// It is a unique identifier for the property.
    pub name: String,
    /// Value is the value of the scheduler hint property, which can be of various types
    /// (e.g., bool, string, int). The type is indicated by the Value.Type field.
    pub value: OpenStackMachineTemplateTemplateSpecSchedulerHintAdditionalPropertiesValue,
}

/// Value is the value of the scheduler hint property, which can be of various types
/// (e.g., bool, string, int). The type is indicated by the Value.Type field.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecSchedulerHintAdditionalPropertiesValue {
    /// Bool is the boolean value of the scheduler hint, used when Type is "Bool".
    /// This field is required if type is 'Bool', and must not be set otherwise.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub bool: Option<bool>,
    /// Number is the integer value of the scheduler hint, used when Type is "Number".
    /// This field is required if type is 'Number', and must not be set otherwise.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub number: Option<i64>,
    /// String is the string value of the scheduler hint, used when Type is "String".
    /// This field is required if type is 'String', and must not be set otherwise.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub string: Option<String>,
    /// Type represents the type of the value.
    /// Valid values are Bool, String, and Number.
    #[serde(rename = "type")]
    pub r#type: OpenStackMachineTemplateTemplateSpecSchedulerHintAdditionalPropertiesValueType,
}

/// Value is the value of the scheduler hint property, which can be of various types
/// (e.g., bool, string, int). The type is indicated by the Value.Type field.
#[derive(Serialize, Deserialize, Clone, Default, Debug, PartialEq, JsonSchema)]
pub enum OpenStackMachineTemplateTemplateSpecSchedulerHintAdditionalPropertiesValueType {
    Bool,
    #[default]
    String,
    Number,
}

/// SecurityGroupParam specifies an OpenStack security group. It may be specified by ID or filter, but not both.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecSecurityGroups {
    /// Filter specifies a query to select an OpenStack security group. If provided, cannot be empty.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub filter: Option<OpenStackMachineTemplateTemplateSpecSecurityGroupsFilter>,
    /// ID is the ID of the security group to use. If ID is provided, the other filters cannot be provided. Must be in UUID format.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
}

/// Filter specifies a query to select an OpenStack security group. If provided, cannot be empty.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecSecurityGroupsFilter {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub description: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
    /// NotTags is a list of tags to filter by. If specified, resources which
    /// contain all of the given tags will be excluded from the result.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "notTags")]
    pub not_tags: Option<Vec<String>>,
    /// NotTagsAny is a list of tags to filter by. If specified, resources
    /// which contain any of the given tags will be excluded from the result.
    #[serde(
        default,
        skip_serializing_if = "Option::is_none",
        rename = "notTagsAny"
    )]
    pub not_tags_any: Option<Vec<String>>,
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "projectID")]
    pub project_id: Option<String>,
    /// Tags is a list of tags to filter by. If specified, the resource must
    /// have all of the tags specified to be included in the result.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub tags: Option<Vec<String>>,
    /// TagsAny is a list of tags to filter by. If specified, the resource
    /// must have at least one of the tags specified to be included in the
    /// result.
    #[serde(default, skip_serializing_if = "Option::is_none", rename = "tagsAny")]
    pub tags_any: Option<Vec<String>>,
}

/// The server group to assign the machine to.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecServerGroup {
    /// Filter specifies a query to select an OpenStack server group. If provided, it cannot be empty.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub filter: Option<OpenStackMachineTemplateTemplateSpecServerGroupFilter>,
    /// ID is the ID of the server group to use.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub id: Option<String>,
}

/// Filter specifies a query to select an OpenStack server group. If provided, it cannot be empty.
#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecServerGroupFilter {
    /// Name is the name of a server group to look for.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub name: Option<String>,
}

#[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, JsonSchema)]
pub struct OpenStackMachineTemplateTemplateSpecServerMetadata {
    /// Key is the server metadata key
    pub key: String,
    /// Value is the server metadata value
    pub value: String,
}
