
    Vh^                     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	)
aD  
---
module: port
short_description: Add/Update/Delete ports from an OpenStack cloud.
author: OpenStack Ansible SIG
description:
   - Add, Update or Remove ports from an OpenStack cloud.
options:
    allowed_address_pairs:
        description:
          - "Allowed address pairs list. Allowed address pairs are supported
            with dictionary structure.
            e.g.  allowed_address_pairs:
                    - ip_address: 10.1.0.12
                      mac_address: ab:cd:ef:12:34:56
                    - ip_address: ..."
          - The port will change during update if not all suboptions are
            specified, e.g. when ip_address is given but mac_address is not.
        type: list
        elements: dict
        suboptions:
            ip_address:
                description: The IP address.
                type: str
            mac_address:
                description: The MAC address.
                type: str
    binding_profile:
        description:
          - Binding profile dict that the port should be created with.
        type: dict
    binding_vnic_type:
        description:
          - The type of the port that should be created
        choices: [normal,
                  direct,
                  direct-physical,
                  macvtap,
                  baremetal,
                  virtio-forwarder]
        type: str
        aliases: ['vnic_type']
    description:
        description:
          - Description of the port.
        type: str
    device_id:
        description:
          - Device ID of device using this port.
        type: str
    device_owner:
        description:
           - The ID of the entity that uses this port.
        type: str
    dns_domain:
        description:
          - The dns domain of the port ( only with dns-integration enabled )
        type: str
    dns_name:
        description:
          - The dns name of the port ( only with dns-integration enabled )
        type: str
    extra_dhcp_opts:
        description:
          - "Extra dhcp options to be assigned to this port. Extra options are
            supported with dictionary structure. Note that options cannot be
            removed only updated.
            e.g.  extra_dhcp_opts:
                    - ip_version: 4
                      opt_name: bootfile-name
                      opt_value: pxelinux.0
                    - opt_name: ..."
          - The port will change during update if not all suboptions are
            specified, e.g. when opt_name is given but ip_version is not.
        type: list
        elements: dict
        suboptions:
            ip_version:
                description: The IP version this DHCP option is for.
                type: int
                required: true
            opt_name:
                description: The name of the DHCP option to set.
                type: str
                required: true
            opt_value:
                description: The value of the DHCP option to set.
                type: str
                required: true
    fixed_ips:
        description:
          - Desired IP and/or subnet for this port.  Subnet is referenced by
            subnet_id and IP is referenced by ip_address.
          - The port will change during update if not all suboptions are
            specified, e.g. when ip_address is given but subnet_id is not.
        type: list
        elements: dict
        suboptions:
            ip_address:
                description: The fixed IP address to attempt to allocate.
                required: true
                type: str
            subnet_id:
                description: The subnet to attach the IP address to.
                type: str
    is_admin_state_up:
        description:
          - Sets admin state.
        type: bool
        aliases: ['admin_state_up']
    mac_address:
        description:
          - MAC address of this port.
        type: str
    name:
        description:
          - Name that has to be given to the port.
          - This port attribute cannot be updated.
        type: str
        required: true
    network:
        description:
          - ID or name of the network this port belongs to.
          - Required when creating a new port.
          - Must be a name when creating a port.
          - This port attribute cannot be updated.
        type: str
    no_security_groups:
        description:
          - Do not associate a security group with this port.
          - "Deprecated. Use I(security_groups): C([]) instead
            of I(no_security_groups): C(true)."
        type: bool
        default: 'false'
    is_port_security_enabled:
        description:
          - Whether to enable or disable the port security on the network.
        type: bool
        aliases: ['port_security_enabled']
    security_groups:
        description:
          - Security group(s) ID(s) or name(s) associated with the port.
        type: list
        elements: str
    state:
        description:
          - Should the resource be present or absent.
        choices: [present, absent]
        default: present
        type: str
extends_documentation_fragment:
- openstack.cloud.openstack
a  
# Create a port
- openstack.cloud.port:
    state: present
    auth:
      auth_url: https://identity.example.com
      username: admin
      password: admin
      project_name: admin
    name: port1
    network: foo

# Create a port with a static IP
- openstack.cloud.port:
    state: present
    auth:
      auth_url: https://identity.example.com
      username: admin
      password: admin
      project_name: admin
    name: port1
    network: foo
    fixed_ips:
      - ip_address: 10.1.0.21

# Create a port with No security groups
- openstack.cloud.port:
    state: present
    auth:
      auth_url: https://identity.example.com
      username: admin
      password: admin
      project_name: admin
    name: port1
    network: foo
    no_security_groups: True

# Update the existing 'port1' port with multiple security groups (version 1)
- openstack.cloud.port:
    state: present
    auth:
      auth_url: https://identity.example.com
      username: admin
      password: admin
      project_name: admin
    name: port1
    security_groups: 1496e8c7-4918-482a-9172-f4f00fc4a3a5,057d4bdf-6d4d-472...

# Update the existing 'port1' port with multiple security groups (version 2)
- openstack.cloud.port:
    state: present
    auth:
      auth_url: https://identity.example.com
      username: admin
      password: admin
      project_name: admin
    name: port1
    security_groups:
      - 1496e8c7-4918-482a-9172-f4f00fc4a3a5
      - 057d4bdf-6d4d-472...

# Create port of type 'direct'
- openstack.cloud.port:
    state: present
    auth:
      auth_url: https://identity.example.com
      username: admin
      password: admin
      project_name: admin
    name: port1
    network: foo
    binding_vnic_type: direct

# Create a port with binding profile
- openstack.cloud.port:
    state: present
    auth:
      auth_url: https://identity.example.com
      username: admin
      password: admin
      project_name: admin
    name: port1
    network: foo
    binding_profile:
      pci_slot: "0000:03:11.1"
      physical_network: "provider"
ao  
port:
    description: Dictionary describing the port.
    type: dict
    returned: On success when I(state) is C(present).
    contains:
        allowed_address_pairs:
            description: Allowed address pairs.
            returned: success
            type: list
            sample: []
        binding_host_id:
            description: |
                The ID of the host where the port is allocated. In some cases,
                different implementations can run on different hosts.
            returned: success
            type: str
            sample: "b4bd682d-234a-4091-aa5b-4b025a6a7759"
        binding_profile:
            description: |
                A dictionary the enables the application running on the
                specified host to pass and receive vif port-specific
                information to the plug-in.
            returned: success
            type: dict
            sample: {}
        binding_vif_details:
            description: |
                A dictionary that enables the application to pass
                information about functions that the Networking API provides.
            returned: success
            type: dict
        binding_vif_type:
            description: The VIF type for the port.
            returned: success
            type: dict
        binding_vnic_type:
            description: |
                The virtual network interface card (vNIC) type that is
                bound to the neutron port.
            returned: success
            type: str
            sample: "normal"
        created_at:
            description: Timestamp when the port was created.
            returned: success
            type: str
            sample: "2022-02-03T13:28:25Z"
        data_plane_status:
            description: Status of the underlying data plane of a port.
            returned: success
            type: str
        description:
            description: The port description.
            returned: success
            type: str
        device_id:
            description: Device ID of this port.
            returned: success
            type: str
            sample: "b4bd682d-234a-4091-aa5b-4b025a6a7759"
        device_owner:
            description: Device owner of this port, e.g. C(network:dhcp).
            returned: success
            type: str
            sample: "network:router_interface"
        device_profile:
            description: |
                Device profile of this port, refers to Cyborg device-profiles:
                https://docs.openstack.org/api-ref/accelerator/v2/index.html#
                device-profiles.
            returned: success
            type: str
        dns_assignment:
            description: DNS assignment for the port.
            returned: success
            type: list
        dns_domain:
            description: DNS domain assigned to the port.
            returned: success
            type: str
        dns_name:
            description: DNS name for the port.
            returned: success
            type: str
        extra_dhcp_opts:
            description: |
                A set of zero or more extra DHCP option pairs.
                An option pair consists of an option value and name.
            returned: success
            type: list
            sample: []
        fixed_ips:
            description: |
                IP addresses for the port. Includes the IP address and subnet
                ID.
            returned: success
            type: list
        id:
            description: The port ID.
            returned: success
            type: str
            sample: "3ec25c97-7052-4ab8-a8ba-92faf84148de"
        ip_allocation:
            description: |
                The ip_allocation indicates when ports use deferred,
                immediate or no IP allocation.
            returned: success
            type: str
        is_admin_state_up:
            description: |
                The administrative state of the port, which is up C(True) or
                down C(False).
            returned: success
            type: bool
            sample: true
        is_port_security_enabled:
            description: |
                The port security status, which is enabled C(True) or disabled
                C(False).
            returned: success
            type: bool
            sample: false
        mac_address:
            description: The MAC address of an allowed address pair.
            returned: success
            type: str
            sample: "00:00:5E:00:53:42"
        name:
            description: The port name.
            returned: success
            type: str
            sample: "port_name"
        network_id:
            description: The ID of the attached network.
            returned: success
            type: str
            sample: "dd1ede4f-3952-4131-aab6-3b8902268c7d"
        numa_affinity_policy:
            description: |
                The NUMA affinity policy defined for this port.
            returned: success
            type: str
            sample: "required"
        project_id:
            description: The ID of the project who owns the network.
            returned: success
            type: str
            sample: "aa1ede4f-3952-4131-aab6-3b8902268c7d"
        propagate_uplink_status:
            description: Whether to propagate uplink status of the port.
            returned: success
            type: bool
            sample: false
        qos_network_policy_id:
            description: |
                The ID of the QoS policy attached to the network where the
                port is bound.
            returned: success
            type: str
            sample: "1e4f3958-c0c9-4dec-82fa-ed2dc1c5cb34"
        qos_policy_id:
            description: The ID of the QoS policy attached to the port.
            returned: success
            type: str
            sample: "b20bb47f-5d6d-45a6-8fe7-2c1b44f0db73"
        resource_request:
            description: |
                The port-resource-request exposes Placement resources
                (i.e.: minimum-bandwidth) and traits (i.e.: vnic-type, physnet)
                requested by a port to Nova and Placement.
            returned: success
            type: str
        revision_number:
            description: The revision number of the resource.
            returned: success
            type: int
            sample: 0
        security_group_ids:
            description: The IDs of any attached security groups.
            returned: success
            type: list
        status:
            description: The port status. Value is C(ACTIVE) or C(DOWN).
            returned: success
            type: str
            sample: "ACTIVE"
        tags:
            description: The list of tags on the resource.
            returned: success
            type: list
            sample: []
        tenant_id:
            description: Same as I(project_id). Deprecated.
            returned: success
            type: str
            sample: "51fce036d7984ba6af4f6c849f65ef00"
        trunk_details:
            description: |
                The trunk referring to this parent port and its subports.
                Present for trunk parent ports if C(trunk-details) extension
                is loaded.
            returned: success
            type: dict
        updated_at:
            description: Timestamp when the port was last updated.
            returned: success
            type: str
            sample: "2022-02-03T13:28:25Z"
    )OpenStackModulec            
          e Zd Z ed/i d edd      d ed      d eg dd	g
      d e       d e       d e       d e       d e       d edd      d edd      d eddg      d e       d ed      d e       d edd      d eddg      d  edd!      d" ed#d$d#g%      Z edd ggd&gd'      Zd( Zd) Zd* Zd+ Z	d, Z
d- Zy.)0
PortModuleallowed_address_pairslistdict)typeelementsbinding_profile)r	   binding_vnic_type)normaldirectzdirect-physicalmacvtap	baremetalzvirtio-forwarder	vnic_type)choicesaliasesdescription	device_iddevice_owner
dns_domaindns_nameextra_dhcp_opts	fixed_ipsis_admin_state_upbooladmin_state_up)r	   r   mac_addressnameT)requirednetworkno_security_groupsF)defaultr	   is_port_security_enabledport_security_enabledsecurity_groupsstrstatepresentabsent)r#   r   )r(   r)   )r!   )mutually_exclusiverequired_ifsupports_check_modec                 h   | j                   d   }| j                   d   }| j                   d   }d }|r'| j                  j                  j                  |d      } | j                  j                  j                  |fi |rt        |j                        n	t               }| j                  j                  r"| j                  | j                  ||             |dk(  r7|s5| j                  |      }| j                  d	|j                  d
             y |dk(  rT|rR| j                  |      }|r| j                  ||      }| j                  t        |      |j                  d
             y |dk(  r&|r$| j!                  |       | j                  d	       y |dk(  r|s| j                  d       y y y )Nr!   r   r(   Fignore_missing)
network_id)changedr)   T)computed)r2   portr*   )paramsconnr!   find_network	find_portr   idansible
check_mode	exit_json_will_change_createto_dict_build_update_updater   _delete)selfnetwork_name_or_idport_name_or_idr(   r!   r4   updates          h/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/openstack/cloud/plugins/modules/port.pyrunzPortModule.run  s   ![[3++f-G$ii''44"5 5 :G +tyy  **D /6twzz*46D
 <<""NN4#4#4T5#ANBId<<(DNN4 $e <  >iD''-F||D&1NN4< $e <  >h4LLNN4N(htNN5N) (,    c                     i }t         fddD              }dD ]O  } j                  |    j                  |   s|   s( j                  |   |   k7  s> j                  |   ||<   Q dD ]O  } j                  |    j                  |   s|   s( j                  |   |   k7  s> j                  |   ||<   Q  j                  d   rg }n] j                  d   L j                  d   D cg c]3  } j                  j                  j	                  |d      j
                  5 }}nd }|t        |      t        d	         k7  r||d	<    j                  j                  d
      rI j                  j                  j                  d      r$|j                  t         fddD                     |r||d<   |S c c}w )Nc              3      K   | ]G  }|j                   v r7j                   |   (j                   |   |   k7  r|j                   |   f I y wNr5   .0kr4   rC   s     rG   	<genexpr>z+PortModule._build_update.<locals>.<genexpr>?  sU      +
 DKKDKKN$>A$q') A+s   AA)
binding_host_idr   data_plane_statusr   r   r   r   r$   r   numa_affinity_policy)r   )r   r   r   r"   r&   Fr/   security_group_idsdnsdns-integrationc              3      K   | ]9  }j                   |   (j                   |   |   k7  r|j                   |   f ; y wrL   rM   rN   s     rG   rQ   z+PortModule._build_update.<locals>.<genexpr>q  sG      (;;q>-$++a.DG2K DKKN#(s   ?A)r   r   port_attributes)
r   r5   r6   r!   find_security_groupr9   sethas_servicefind_extensionrF   )rC   r4   rF   rY   rP   rU   security_group_name_or_ids   ``     rG   r@   zPortModule._build_update  s   J  +.+ + % 	4A{{1~%A$q';;q>T!W,%)[[^"	4 K 	4A{{1~%A$q';;q>T!W,%)[[^"	4 ;;+,!#[[*+7 26=N1O" . 		!!55-e 6 EEGRH" " "&)%&#d3G.H*II4FO01 99  '99++,=>""4 (3( $  (7F$%/"s   48F?c                    i }|j                   |d<   | j                  d   rg |d<   n^| j                  d   O| j                  d   D cg c]3  }| j                  j                  j	                  |d      j                   5 c}|d<   dD ]$  }| j                  |   | j                  |   ||<   & | j                  j                  d      rN| j                  j                  j                  d	      r)d
D ]$  }| j                  |   | j                  |   ||<   &  | j                  j                  j                  di |S c c}w )Nr1   r"   rU   r&   Fr/   )r   r   r   r   r   r   r   r   r   r$   r   r   rV   rW   )r   r    )r9   r5   r6   r!   rZ   r\   r]   create_port)rC   r!   argsr^   rP   s        rG   r>   zPortModule._create{  sJ   $ZZ\ ;;+,)+D%&[[*+7 26=N1O* . 		!!55-e 6 EEGRH*D%& 	)A {{1~)++a.Q	) 99  'yy  //0AB/ -;;q>-"kk!nDG- -tyy  ,,4t447*s   8D=c                 b    | j                   j                  j                  |j                         y rL   )r6   r!   delete_portr9   )rC   r4   s     rG   rB   zPortModule._delete  s    		%%dgg.rI   c                 z    |j                  d      }|r' | j                  j                  j                  |fi |}|S )NrY   )getr6   r!   update_port)rC   r4   rF   rY   s       rG   rA   zPortModule._update  s:     **%670499$$00IIDrI   c                 f    |dk(  r|sy|dk(  r|rt        | j                  |            S |dk(  r|ryy)Nr)   Tr*   F)r   r@   )rC   r4   r(   s      rG   r=   zPortModule._will_change  sA    IdiD**4011h4 rI   Nr`   )__name__
__module____qualname__r   argument_specmodule_kwargsrH   r@   r>   rB   rA   r=   r`   rI   rG   r   r     su    "@&)  (< )4}6 F & V 6  &6: FV4 F5E4FG F  4 !" #$  F;%& "&6<S;T!U'( &59)* 9x.CD+M0 !#45
 /
 !M%*N`D$5L/	rI   r   c                  &    t               }  |         y rL   )r   )modules    rG   mainrp     s    \F
HrI   __main__N)DOCUMENTATIONEXAMPLESRETURNBansible_collections.openstack.cloud.plugins.module_utils.openstackr   r   rp   ri   r`   rI   rG   <module>rv      sN   XtVpQ
f _d dN
 zF rI   