
    VhA                     R    d Z dZdZddlmZ  G d de      Zd Zedk(  r e        y	y	)
aK  
---
module: subnet
short_description: Add/Remove subnet to an OpenStack network
author: OpenStack Ansible SIG
description:
   - Add or Remove a subnet to an OpenStack network
options:
    state:
        description:
            - Indicate desired state of the resource
        choices: ['present', 'absent']
        default: present
        type: str
    allocation_pool_start:
        description:
            - From the subnet pool the starting address from which the IP
              should be allocated.
        type: str
    allocation_pool_end:
        description:
            - From the subnet pool the last IP that should be assigned to the
              virtual machines.
        type: str
    allocation_pools:
        description:
            - List of allocation pools to assign to the subnet. Each element
              consists of a 'start' and 'end' value.
        type: list
        elements: dict
    cidr:
        description:
            - The CIDR representation of the subnet that should be assigned to
              the subnet. Required when I(state) is 'present' and a subnetpool
              is not specified.
        type: str
    description:
        description:
            - Description of the subnet
        type: str
    disable_gateway_ip:
        description:
            - The gateway IP would not be assigned for this subnet
        type: bool
        aliases: ['no_gateway_ip']
        default: 'false'
    dns_nameservers:
        description:
            - List of DNS nameservers for this subnet.
        type: list
        elements: str
    extra_attrs:
        description:
            - Dictionary with extra key/value pairs passed to the API
        required: false
        aliases: ['extra_specs']
        default: {}
        type: dict
    host_routes:
        description:
            - A list of host route dictionaries for the subnet.
        type: list
        elements: dict
        suboptions:
            destination:
                description: The destination network (CIDR).
                type: str
                required: true
            nexthop:
                description: The next hop (aka gateway) for the I(destination).
                type: str
                required: true
    gateway_ip:
        description:
            - The ip that would be assigned to the gateway for this subnet
        type: str
    ip_version:
        description:
            - The IP version of the subnet 4 or 6
        default: 4
        type: int
        choices: [4, 6]
    is_dhcp_enabled:
        description:
            - Whether DHCP should be enabled for this subnet.
        type: bool
        aliases: ['enable_dhcp']
        default: 'true'
    ipv6_ra_mode:
        description:
            - IPv6 router advertisement mode
        choices: ['dhcpv6-stateful', 'dhcpv6-stateless', 'slaac']
        type: str
    ipv6_address_mode:
        description:
            - IPv6 address mode
        choices: ['dhcpv6-stateful', 'dhcpv6-stateless', 'slaac']
        type: str
    name:
        description:
            - The name of the subnet that should be created. Although Neutron
              allows for non-unique subnet names, this module enforces subnet
              name uniqueness.
        required: true
        type: str
    network:
        description:
            - Name or id of the network to which the subnet should be attached
            - Required when I(state) is 'present'
        aliases: ['network_name']
        type: str
    project:
        description:
            - Project name or ID containing the subnet (name admin-only)
        type: str
    prefix_length:
        description:
            - The prefix length to use for subnet allocation from a subnet pool
        type: str
    use_default_subnet_pool:
        description:
            - Use the default subnetpool for I(ip_version) to obtain a CIDR.
        type: bool
        aliases: ['use_default_subnetpool']
    subnet_pool:
        description:
            - The subnet pool name or ID from which to obtain a CIDR
        type: str
        required: false
extends_documentation_fragment:
- openstack.cloud.openstack
a  
# Create a new (or update an existing) subnet on the specified network
- openstack.cloud.subnet:
    state: present
    network_name: network1
    name: net1subnet
    cidr: 192.168.0.0/24
    dns_nameservers:
       - 8.8.8.7
       - 8.8.8.8
    host_routes:
       - destination: 0.0.0.0/0
         nexthop: 12.34.56.78
       - destination: 192.168.0.0/24
         nexthop: 192.168.0.1

# Delete a subnet
- openstack.cloud.subnet:
    state: absent
    name: net1subnet

# Create an ipv6 stateless subnet
- openstack.cloud.subnet:
    state: present
    name: intv6
    network_name: internal
    ip_version: 6
    cidr: 2db8:1::/64
    dns_nameservers:
        - 2001:4860:4860::8888
        - 2001:4860:4860::8844
    ipv6_ra_mode: dhcpv6-stateless
    ipv6_address_mode: dhcpv6-stateless
a  
id:
    description: Id of subnet
    returned: On success when subnet exists.
    type: str
subnet:
    description: Dictionary describing the subnet.
    returned: On success when subnet exists.
    type: dict
    contains:
        allocation_pools:
            description: Allocation pools associated with this subnet.
            returned: success
            type: list
            elements: dict
        cidr:
            description: Subnet's CIDR.
            returned: success
            type: str
        created_at:
            description: Created at timestamp
            type: str
        description:
            description: Description
            type: str
        dns_nameservers:
            description: DNS name servers for this subnet.
            returned: success
            type: list
            elements: str
        dns_publish_fixed_ip:
            description: Whether to publish DNS records for fixed IPs.
            returned: success
            type: bool
        gateway_ip:
            description: Subnet's gateway ip.
            returned: success
            type: str
        host_routes:
            description: A list of host routes.
            returned: success
            type: str
        id:
            description: Unique UUID.
            returned: success
            type: str
        ip_version:
            description: IP version for this subnet.
            returned: success
            type: int
        ipv6_address_mode:
            description: |
                The IPv6 address modes which are 'dhcpv6-stateful',
                'dhcpv6-stateless' or 'slaac'.
            returned: success
            type: str
        ipv6_ra_mode:
            description: |
                The IPv6 router advertisements modes which can be 'slaac',
                'dhcpv6-stateful', 'dhcpv6-stateless'.
            returned: success
            type: str
        is_dhcp_enabled:
            description: DHCP enable flag for this subnet.
            returned: success
            type: bool
        name:
            description: Name given to the subnet.
            returned: success
            type: str
        network_id:
            description: Network ID this subnet belongs in.
            returned: success
            type: str
        prefix_length:
            description: |
                The prefix length to use for subnet allocation from a subnet
                pool.
            returned: success
            type: str
        project_id:
            description: Project id associated with this subnet.
            returned: success
            type: str
        revision_number:
            description: Revision number of the resource
            returned: success
            type: int
        segment_id:
            description: The ID of the segment this subnet is associated with.
            returned: success
            type: str
        service_types:
            description: Service types for this subnet
            returned: success
            type: list
        subnet_pool_id:
            description: The subnet pool ID from which to obtain a CIDR.
            returned: success
            type: str
        tags:
            description: Tags
            type: str
        updated_at:
            description: Timestamp when the subnet was last updated.
            returned: success
            type: str
        use_default_subnet_pool:
            description: |
                Whether to use the default subnet pool to obtain a CIDR.
            returned: success
            type: bool
    )OpenStackModulec                   .   e Zd Zg dZ ed<i d ed      d edg      d e       d	 e       d
 eddddg      d edddg      d e       d edddg      d edd      d e       d e       d edd      d edd      d  ee!      d" ee!      d# e       d$ e       d% edd&g'      d( ed e       d)g      d* ed+d,d+g-      d. e       Z edddggd/d0gg d12      Zd3Zd4 Zd5 Z	d6 Z
d7 Zd8 Zd9 Zd: Zy;)=SubnetModule)zdhcpv6-statefulzdhcpv6-statelessslaacnameT)requirednetworknetwork_name)aliasescidrdescription
ip_versionint      )typedefaultchoicesis_dhcp_enabledboolenable_dhcp)r   r   r   
gateway_ipdisable_gateway_ipFno_gateway_ipdns_nameserversliststr)r   elementsallocation_pool_startallocation_pool_endallocation_poolsdicthost_routesipv6_ra_mode)r   ipv6_address_modesubnet_poolprefix_lengthuse_default_subnet_pooluse_default_subnetpool)r   r   extra_attrsextra_specsstatepresentabsent)r   r   project)r,   r-   )r	   )r,   r-   )r   r(   r&   T))r(   r&   )r   r!   )r    r!   )supports_check_moderequired_togetherrequired_ifmutually_exclusive)r   r   r   r   r#   r   r%   r$   r   r   r'   r(   c                 v    dD ]4  }||v s||   ||   k7  s| j                  dj                  |             6 y)z/ Check for differences in non-updatable values )r   r   r$   r%   r'   r(   z$Cannot update {0} in existing subnetmsgN)	fail_jsonformat)selfsubnetupdateattrs       j/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/openstack/cloud/plugins/modules/subnet.py_validate_updatezSubnetModule._validate_updateX  sL    A 	MDv~&,&,">>EEdK  M	M    c                     | j                   d   }|dk(  r|d uS |sy| j                  |||      }| j                  ||      }| j                  ||       t	        |      S )Nr,   r.   T)params_build_params_build_updatesr>   r   )r9   r:   r	   r/   r&   r,   rA   updatess           r=   _system_state_changez!SubnetModule._system_state_changea  si    G$H%%##GWkB%%ff5fg.G}r?   c                 `    | j                   d   }| j                   d   }|rt        ||      gS y )Nr   r    )startend)rA   r"   )r9   
pool_startpool_ends      r=   _build_poolzSubnetModule._build_poolm  s6    [[!89
;;45zx899r?   c                    | j                   D ci c]  }|| j                  |    }}|j                  |d<   |r|j                  |d<   |r|j                  |d<   | j                  d   r| j                         |d<   n| j                  d   |d<   | j	                  |      }|j                         D ci c]  \  }}|	|| }}}|S c c}w c c}}w )N
network_id
project_idsubnet_pool_idr   r!   )attr_paramsrA   idrK   _add_extra_attrsitems)r9   r	   r/   r&   r<   rA   kvs           r=   rB   zSubnetModule._build_paramst  s    6:6F6FGd$D))GG&zz|#*::F< '2~~F#$;;./)-)9)9);F%&)-5G)HF%&&&v.#)<<>C41aQ]!Q$CC H Ds   C2
C=Cc                    d|v r&|d   j                          |d   j                          d|v r,|d   j                  d        |d   j                  d        d|v r,|d   j                  d        |d   j                  d        |D ci c]  }||   ||   k7  s|||    }}| j                  d	   r|j                  rd |d
<   |S c c}w )Nr   r#   c                 4    t        | j                               S NsortedrS   rs    r=   <lambda>z-SubnetModule._build_updates.<locals>.<lambda>      VAGGI5F r?   )keyc                 4    t        | j                               S rX   rY   r[   s    r=   r]   z-SubnetModule._build_updates.<locals>.<lambda>  r^   r?   r!   c                 4    t        | j                               S rX   rY   r[   s    r=   r]   z-SubnetModule._build_updates.<locals>.<lambda>      &:K r?   c                 4    t        | j                               S rX   rY   r[   s    r=   r]   z-SubnetModule._build_updates.<locals>.<lambda>  rb   r?   r   r   )sortrA   r   )r9   r:   rA   rT   rD   s        r=   rC   zSubnetModule._build_updates  s    &$%**,$%**,F"=!&&+F&G=!&&+F&G'%&++0K+L%&++0K+L)/JA6!9q	3I1fQi<JJ;;+,1B1B$(GL! Ks   C Cc                     t        | j                  d         t        |      z  }|r*| j                  dj                  t	        |                   |j                  | j                  d          |S )Nr*   z#Duplicate key(s) {0} in extra_specsr5   )setrA   r7   r8   r   r;   )r9   rA   
duplicatess      r=   rR   zSubnetModule._add_extra_attrs  s^    ]34s6{B
NND"F4
#34  6dkk-01r?   c                 4   | j                   d   }| j                   d   }| j                   d   }| j                   d   }| j                   d   }| j                   d   }| j                   d   }|r|r| j                  d	       i }i }	d }
|rE| j                  j                  j	                  |d
      }
|
j
                  |d<   |
j
                  |	d<   d }|r8 | j                  j                  j                  |fdd
i|	}|j
                  |	d<   d }|r8 | j                  j                  j                  |fdd
i|}|j
                  |	d<    | j                  j                  j                  |fi |	}| j                  j                  r$| j                  | j                  |||
|             d
}|dk(  r| j                  ||
|      }|) | j                  j                  j                  di |}d}nO| j!                  ||      }|r;| j#                  ||        | j                  j                  j$                  |fi |}d}| j                  |||j
                         n.|dk(  r)|'| j                  j                  j'                  |       d}| j                  |       y )Nr,   r	   r/   r&   r   r   r   z,no_gateway_ip is not allowed with gateway_ipr5   F)ignore_missingrN   ri   rM   rO   )changedr-   T)rj   r:   rQ   r.    )rA   r7   connidentityfind_projectrQ   r	   find_networkfind_subnet_poolfind_subnetansible
check_mode	exit_jsonrE   rB   create_subnetrC   r>   update_subnetdelete_subnet)r9   r,   network_name_or_idproject_name_or_idsubnet_pool_name_or_idsubnet_namer   r   subnet_pool_filtersfiltersr/   r	   r&   r:   rj   rA   rD   s                    r=   runzSubnetModule.run  s   G$![[3![[3!%]!;kk&)[[.
![[)=> *NNMNN ii((556HEJ 6 LG07

-$+JJGL!4dii''445G @DI@7>@G %,JJGL!!<$))++<<&'$' &'K )4G$%.""..{FgF<<""NN4#<#<+$7N 8 I''+FF~8**88B6B--ff=))&':<TYY..<<VOwOF"GNN76fiiNHh6#5II++F3Gw'r?   Nrk   )__name__
__module____qualname__ipv6_mode_choicesr"   argument_specmodule_kwargsrP   r>   rE   rK   rB   rC   rR   r~   rk   r?   r=   r   r   $  s   H 4 n-. V F	
 UA1v> &$&3_6 6  0AC &59 #f !F 6F; fv6  "34!" '89#$ F%& f'( !%":!;!=), fdf}oN-. 9$i02/2 3M8  13JKL.G


M /KM
&=(r?   r   c                  &    t               }  |         y rX   )r   )modules    r=   mainr     s    ^F
Hr?   __main__N)DOCUMENTATIONEXAMPLESRETURNBansible_collections.openstack.cloud.plugins.module_utils.openstackr   r   r   r   rk   r?   r=   <module>r      sM   CJ!Fp
d _w(? w(t
 zF r?   