
    Vh:I                         d dl mZmZmZ eZdZdZdZd dl	m
Z
 d dlmZmZ 	 d dlmZmZ dZ G d de      Z G d de      Z G d de      Zd Zd Zedk(  r e        y	y	# e$ r d	Zd
ZY @w xY w)    )absolute_importdivisionprint_functiona  
module: dimensiondata_vlan
short_description: Manage a VLAN in a Cloud Control network domain
extends_documentation_fragment:
  - community.general.dimensiondata
  - community.general.dimensiondata_wait
  - community.general.attributes

description:
  - Manage VLANs in Cloud Control network domains.
author: 'Adam Friedman (@tintoy)'
attributes:
  check_mode:
    support: none
  diff_mode:
    support: none
options:
  name:
    description:
      - The name of the target VLAN.
    type: str
    required: true
  description:
    description:
      - A description of the VLAN.
    type: str
    default: ''
  network_domain:
    description:
      - The ID or name of the target network domain.
    required: true
    type: str
  private_ipv4_base_address:
    description:
      - The base address for the VLAN's IPv4 network (for example V(192.168.1.0)).
    type: str
    default: ''
  private_ipv4_prefix_size:
    description:
      - The size of the IPv4 address space, for example V(24).
      - Required, if O(private_ipv4_base_address) is specified.
    type: int
    default: 0
  state:
    description:
      - The desired state for the target VLAN.
      - V(readonly) ensures that the state is only ever read, not modified (the module will fail if the resource does not
        exist).
    choices: [present, absent, readonly]
    default: present
    type: str
  allow_expand:
    description:
      - Permit expansion of the target VLAN's network if the module parameters specify a larger network than the VLAN currently
        possesses.
      - If V(false), the module will fail under these conditions.
      - This is intended to prevent accidental expansion of a VLAN's network (since this operation is not reversible).
    type: bool
    default: false
a  
- name: Add or update VLAN
  community.general.dimensiondata_vlan:
    region: na
    location: NA5
    network_domain: test_network
    name: my_vlan1
    description: A test VLAN
    private_ipv4_base_address: 192.168.23.0
    private_ipv4_prefix_size: 24
    state: present
    wait: true

- name: Read / get VLAN details
  community.general.dimensiondata_vlan:
    region: na
    location: NA5
    network_domain: test_network
    name: my_vlan1
    state: readonly
    wait: true

- name: Delete a VLAN
  community.general.dimensiondata_vlan:
    region: na
    location: NA5
    network_domain: test_network
    name: my_vlan_1
    state: absent
    wait: true
a  
vlan:
  description: Dictionary describing the VLAN.
  returned: On success when O(state=present)
  type: complex
  contains:
    id:
      description: VLAN ID.
      type: str
      sample: "aaaaa000-a000-4050-a215-2808934ccccc"
    name:
      description: VLAN name.
      type: str
      sample: "My VLAN"
    description:
      description: VLAN description.
      type: str
      sample: "My VLAN description"
    location:
      description: Datacenter location.
      type: str
      sample: NA3
    private_ipv4_base_address:
      description: The base address for the VLAN's private IPV4 network.
      type: str
      sample: 192.168.23.0
    private_ipv4_prefix_size:
      description: The prefix size for the VLAN's private IPV4 network.
      type: int
      sample: 24
    private_ipv4_gateway_address:
      description: The gateway address for the VLAN's private IPV4 network.
      type: str
      sample: 192.168.23.1
    private_ipv6_base_address:
      description: The base address for the VLAN's IPV6 network.
      type: str
      sample: 2402:9900:111:1195:0:0:0:0
    private_ipv6_prefix_size:
      description: The prefix size for the VLAN's IPV6 network.
      type: int
      sample: 64
    private_ipv6_gateway_address:
      description: The gateway address for the VLAN's IPV6 network.
      type: str
      sample: 2402:9900:111:1195:0:0:0:1
    status:
      description: VLAN status.
      type: str
      sample: NORMAL
)AnsibleModule)DimensionDataModuleUnknownNetworkError)DimensionDataVlanDimensionDataAPIExceptionTNFc                   R     e Zd ZdZ fdZd Zd Zd Zd Zd Z	d Z
d	 Zd
 Z xZS )DimensionDataVlanModulez4
    The dimensiondata_vlan module for Ansible.
    c                 R   t         t        |   t        t	        j
                  t        dd      t        dd      t        dd      t        dd      t        dd      t        ddd	
      t        dg d            t	        j                                      | j                  j                  d   | _
        | j                  j                  d   | _        | j                  j                  d   | _        | j                  j                  d   | _        | j                  j                  d   | _        | j                  j                  d   | _        | j                  j                  d   | _        | j"                  r-| j                  dk7  r| j                  j%                  d       yyy)z:
        Create a new Dimension Data VLAN module.
        Tstr)requiredtype )defaultr   r   intFbool)r   r   r   present)r   absentreadonly)r   choices)namedescriptionnetwork_domainprivate_ipv4_base_addressprivate_ipv4_prefix_sizeallow_expandstate)argument_specrequired_togethermoduler   r   r   r   r   r   r   z=The wait parameter is only supported when state is "present".msgN)superr   __init__r   r   argument_spec_with_waitdictr!   r#   paramsr   r   network_domain_selectorr   r   r   r   wait	fail_json)self	__class__s    x/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/general/plugins/modules/dimensiondata_vlan.pyr'   z DimensionDataVlanModule.__init__   s^   
 	%t5 1IIt%8 $Re <#'E#B.22E.J-1!%-H!%ue&!Qy:[\ #6"G"G"I 	6 	
 KK&&v.	;;--m<'+{{'9'9:J'K$)-););<W)X&(,(:(:;U(V%[[''0
 KK..~>99y0KK!!S "  19    c                    | j                         }| j                  |      }|s| j                  j                  rA| j                  j	                  dj                  | j                  | j                        d       | j                  |      }| j                  j	                  dj                  | j                  | j                        t        |      d       yt        || j                  j                        }|j                         sL| j                  j	                  dj                  | j                  | j                        t        |      d       y	 |j                          |j!                         r`| j"                  sT| j                  j                  dj                  | j$                        dj                  |j&                        z   dz   
       | j                  j                  rK| j                  j	                  dj                  | j                  | j                        t        |      d       |j)                         r=| j                  |_        | j*                  |_        | j,                  j/                  |       |j!                         r,| j$                  |_        | j,                  j1                  |       | j                  j	                  dj                  | j                  | j                        t        |      d       y# t        $ rL}| j                  j                  d	j                  | j                  | j                  |      
       Y d}~d}~ww xY w)z9
        Ensure that the target VLAN is present.
        zCVLAN "{0}" is absent from network domain "{1}" (should be present).Tr%   changedz+Created VLAN "{0}" in network domain "{1}".r%   vlanr4   zDVLAN "{0}" is present in network domain "{1}" (no changes detected).FNz8Unable to update VLAN "{0}" in network domain "{1}": {2}r$   z>The configured private IPv4 network size ({0}-bit prefix) for z@the VLAN differs from its current network size ({0}-bit prefix) zIand needs to be expanded. Use allow_expand=true if this is what you want.zAVLAN "{0}" is present in network domain "{1}" (changes detected).z+Updated VLAN "{0}" in network domain "{1}".)_get_network_domain	_get_vlanr#   
check_mode	exit_jsonformatr   r+   _create_vlanvlan_to_dictVlanDiffr*   has_changesensure_legal_changeInvalidVlanChangeErrorr-   needs_expandr   r   private_ipv4_range_size
needs_editr   driverex_update_vlanex_expand_vlan)r.   r   r6   diffinvalid_vlan_changes        r0   state_presentz%DimensionDataVlanModule.state_present   s   
 113~~n-{{%%%%]dd		4#?#? !	 &  $$^4DKK!!AHHIIt;; "$' "  D$++"4"45D##%%%^ee		4#?#? &d+! &  ((*   "4+<+<%%X__55Zaa44 d	d &  {{%%%%[bb		4#?#? &d+  &    II	#'#3#3 **40  "/3/L/L,**40KK!!AHHIIt;; "$' " G * %%RYY		4#?#?AT &  s   L 	M AMM c                    | j                         }| j                  |      }|r'| j                  j                  t	        |      d       y| j                  j                  dj                  | j                  | j                               y)z/
        Read the target VLAN's state.
        F)r6   r4   z2VLAN "{0}" does not exist in network domain "{1}".r$   N)	r7   r8   r#   r:   r=   r-   r;   r   r+   r.   r   r6   s      r0   state_readonlyz&DimensionDataVlanModule.state_readonly%  s{    
 113~~n-KK!!!$' " 
 KK!!HOOIIt;; " r1   c                 4   | j                         }| j                  |      }|sB| j                  j                  dj	                  | j
                  | j                        d       y| j                  j                  rK| j                  j                  dj	                  | j
                  | j                        t        |      d       | j                  |       | j                  j                  dj	                  | j
                  | j                        d       y)	z=
        Ensure that the target VLAN is not present.
        z/VLAN "{0}" is absent from network domain "{1}".Fr3   NzAVLAN "{0}" is present in network domain "{1}" (should be absent).Tr5   z-Deleted VLAN "{0}" from network domain "{1}".)
r7   r8   r#   r:   r;   r   r+   r9   r=   _delete_vlanrL   s      r0   state_absentz$DimensionDataVlanModule.state_absent9  s    
 113~~n-KK!!ELLIIt;; 	 "  ;;!!KK!!W^^IIt;; "$' "  	$?FF		477 	 	 	
r1   c                     | j                   j                  | j                  |      }|D cg c]  }|j                  | j                  k(  s|  }}|r|d   S yc c}w )z
        Retrieve the target VLAN details from CloudControl.

        :param network_domain: The target network domain.
        :return: The VLAN, or None if the target VLAN was not found.
        :rtype: DimensionDataVlan
        )locationr   r   N)rE   ex_list_vlansrR   r   )r.   r   vlansr6   matching_vlanss        r0   r8   z!DimensionDataVlanModule._get_vlan]  sb     ))]]) * 
 ,1K4DII4J$KK!!$$	 Ls   AAc                     | j                   j                  || j                  | j                  | j                  | j
                        }| j                  r| j                  |j                  d      }|S )NNORMAL)	rE   ex_create_vlanr   r   r   r   r,   _wait_for_vlan_stateidrL   s      r0   r<   z$DimensionDataVlanModule._create_vlanp  s_    {{))II**))
 99,,TWWh?Dr1   c                 &   	 | j                   j                  |       | j                  r| j                  |d       y y # t        $ rJ}| j
                  j                  dj                  |j                  |j                               Y d }~y d }~ww xY w)N	NOT_FOUNDzRFailed to delete VLAN "{0}" due to unexpected error from the CloudControl API: {1}r$   )
rE   ex_delete_vlanr,   rY   r
   r#   r-   r;   rZ   r%   )r.   r6   api_exceptions      r0   rO   z$DimensionDataVlanModule._delete_vlan~  s    	KK&&t, yy))$<  ) 	KK!!hooGG].. "  	s   9= 	BA BBc                    | j                         }| j                  j                  d   }| j                  j                  d   }	 | j                  j                  j                  || j                  j                  |||      S # t        $ rE}|j                  dk7  r t        |j                  ddddddddd| j                  |      cY d }~S d }~ww xY w)Nwait_poll_interval	wait_timeRESOURCE_NOT_FOUNDr\   r   r   )rZ   statusr   r   private_ipv4_range_addressrC   ipv4_gatewayipv6_range_addressipv6_range_sizeipv6_gatewayrR   r   )r7   r#   r*   rE   
connectionwait_for_stateex_get_vlanr
   coder	   rZ   rR   )r.   r6   state_to_wait_forr   r`   ra   r^   s          r0   rY   z,DimensionDataVlanModule._wait_for_vlan_state  s    113![[//0DEKK&&{3		;;))88!''"  ) 	!!%99$77"+-()#% !- 		s   <B 	C
:C
C
Cc                     	 | j                  | j                  | j                        S # t        $ rC | j                  j                  dj                  | j                  | j                               Y yw xY w)zv
        Retrieve the target network domain from the Cloud Control API.

        :return: The network domain.
        z5Cannot find network domain "{0}" in datacenter "{1}".r$   N)get_network_domainr+   rR   r   r#   r-   r;   r.   s    r0   r7   z+DimensionDataVlanModule._get_network_domain  ss    	**,,dmm  # 	KK!!KRR00$-- "  	s   %( A	A43A4)__name__
__module____qualname____doc__r'   rJ   rM   rP   r8   r<   rO   rY   r7   __classcell__)r/   s   @r0   r   r      s:    BQf("
H&"Hr1   r   c                       e Zd ZdZy)rA   zI
    Error raised when an illegal change to VLAN state is attempted.
    N)rq   rr   rs   rt    r1   r0   rA   rA     s     	r1   rA   c                   .    e Zd ZdZd Zd Zd Zd Zd Zy)r>   zd
    Represents differences between VLAN information (from CloudControl) and module parameters.
    c                 $   || _         || _        |d   |j                  k7  | _        |d   |j                  k7  | _        |d   |j                  k7  | _        |d   |j                  k7  | _	        |d   |j                  z
  }|dkD  | _
        |dk  | _        y)z

        :param vlan: The VLAN information from CloudControl.
        :type vlan: DimensionDataVlan
        :param module_params: The module parameters.
        :type module_params: dict
        r   r   r   r   r   N)r6   module_paramsr   name_changedr   description_changedrd   !private_ipv4_base_address_changedrC    private_ipv4_prefix_size_changed"private_ipv4_prefix_size_increased"private_ipv4_prefix_size_decreased)r.   r6   rz   #private_ipv4_prefix_size_differences       r0   r'   zVlanDiff.__init__  s     	*)&1TYY>#0#?4CSCS#S 1>?Z1[_c_~_~1~.0=>X0Y]a]y]y0y- /<<V.WZ^ZvZv.v+2UXY2Y/2UXY2Y/r1   c                 F    | j                         xs | j                         S )z
        Does the VlanDiff represent any changes between the VLAN and module configuration?

        :return: True, if there are change changes; otherwise, False.
        )rD   rB   rp   s    r0   r?   zVlanDiff.has_changes  s      7D$5$5$77r1   c                 `    | j                   rt        d      | j                  rt        d      y)a~  
        Ensure the change (if any) represented by the VlanDiff represents a legal change to VLAN state.

        - private_ipv4_base_address cannot be changed
        - private_ipv4_prefix_size must be greater than or equal to the VLAN's existing private_ipv4_range_size

        :raise InvalidVlanChangeError: The VlanDiff does not represent a legal change to VLAN state.
        zACannot change the private IPV4 base address for an existing VLAN.zWCannot shrink the private IPV4 network for an existing VLAN (only expand is supported).N)r}   rA   r   rp   s    r0   r@   zVlanDiff.ensure_legal_change  s>     11()lmm 22(  *C  D  D 3r1   c                 6    | j                   xs | j                  S )z
        Is an Edit operation required to resolve the differences between the VLAN information and the module parameters?

        :return: True, if an Edit operation is required; otherwise, False.
        )r{   r|   rp   s    r0   rD   zVlanDiff.needs_edit  s       <D$<$<<r1   c                     | j                   S )a&  
        Is an Expand operation required to resolve the differences between the VLAN information and the module parameters?

        The VLAN's network is expanded by reducing the size of its network prefix.

        :return: True, if an Expand operation is required; otherwise, False.
        )r   rp   s    r0   rB   zVlanDiff.needs_expand  s     666r1   N)	rq   rr   rs   rt   r'   r?   r@   rD   rB   rw   r1   r0   r>   r>     s"    Z,8D$=	7r1   r>   c                    | j                   | j                  | j                  | j                  j                   | j                  | j
                  | j                  | j                  | j                  | j                  | j                  dS )N)rZ   r   r   rR   r   r   private_ipv4_gateway_addressipv6_base_addressipv6_prefix_sizeipv6_gateway_addressrc   )rZ   r   r   rR   rd   rC   re   rf   rg   rh   rc   )r6   s    r0   r=   r=     sm    gg		''MM$$%)%D%D$($@$@(,(9(9!44 00 $ 1 1++ r1   c                      t               } | j                  dk(  r| j                          y | j                  dk(  r| j                          y | j                  dk(  r| j	                          y y )Nr   r   r   )r   r   rJ   rM   rP   r"   s    r0   mainr   )  sW    $&F||y 		#		! 
"r1   __main__)
__future__r   r   r   r   __metaclass__DOCUMENTATIONEXAMPLESRETURNansible.module_utils.basicr   Hansible_collections.community.general.plugins.module_utils.dimensiondatar   r   libcloud.common.dimensiondatar	   r
   HAS_LIBCLOUDImportErrorr   	ExceptionrA   objectr>   r=   r   rq   rw   r1   r0   <module>r      s    C B;z@2
h 5 }ZLW1 Wt	Y 	H7v H7V  zF ]  Ls   
A! !	A-,A-