
    Vh8d                        d dl mZmZmZ eZdZdZdZd dl	Z	d dl
mZ d dlmZ dZd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z d Z!	 	 d%dZ"d Z#d Z$d Z%d  Z&d! Z'd" Z(d# Z)e*d$k(  r e)        yy)&    )absolute_importdivisionprint_functiona   
module: one_service
short_description: Deploy and manage OpenNebula services
description:
  - Manage OpenNebula services.
extends_documentation_fragment:
  - community.general.attributes
attributes:
  check_mode:
    support: full
  diff_mode:
    support: none
options:
  api_url:
    description:
      - URL of the OpenNebula OneFlow API server.
      - It is recommended to use HTTPS so that the username/password are not transferred over the network unencrypted.
      - If not set then the value of the E(ONEFLOW_URL) environment variable is used.
    type: str
  api_username:
    description:
      - Name of the user to login into the OpenNebula OneFlow API server. If not set then the value of the E(ONEFLOW_USERNAME)
        environment variable is used.
    type: str
  api_password:
    description:
      - Password of the user to login into OpenNebula OneFlow API server. If not set then the value of the E(ONEFLOW_PASSWORD)
        environment variable is used.
    type: str
  template_name:
    description:
      - Name of service template to use to create a new instance of a service.
    type: str
  template_id:
    description:
      - ID of a service template to use to create a new instance of a service.
    type: int
  service_id:
    description:
      - ID of a service instance that you would like to manage.
    type: int
  service_name:
    description:
      - Name of a service instance that you would like to manage.
    type: str
  unique:
    description:
      - Setting O(unique=true) will make sure that there is only one service instance running with a name set with O(service_name)
        when instantiating a service from a template specified with O(template_id) or O(template_name). Check examples below.
    type: bool
    default: false
  state:
    description:
      - V(present) - instantiate a service from a template specified with O(template_id) or O(template_name).
      - V(absent) - terminate an instance of a service specified with O(template_id) or O(template_name).
    choices: ["present", "absent"]
    default: present
    type: str
  mode:
    description:
      - Set permission mode of a service instance in octet format, for example V(0600) to give owner C(use) and C(manage)
        and nothing to group and others.
    type: str
  owner_id:
    description:
      - ID of the user which will be set as the owner of the service.
    type: int
  group_id:
    description:
      - ID of the group which will be set as the group of the service.
    type: int
  wait:
    description:
      - Wait for the instance to reach RUNNING state after DEPLOYING or COOLDOWN state after SCALING.
    type: bool
    default: false
  wait_timeout:
    description:
      - How long before wait gives up, in seconds.
    default: 300
    type: int
  custom_attrs:
    description:
      - Dictionary of key/value custom attributes which will be used when instantiating a new service.
    default: {}
    type: dict
  role:
    description:
      - Name of the role whose cardinality should be changed.
    type: str
  cardinality:
    description:
      - Number of VMs for the specified role.
    type: int
  force:
    description:
      - Force the new cardinality even if it is outside the limits.
    type: bool
    default: false
author:
  - "Milan Ilic (@ilicmilan)"
a  
- name: Instantiate a new service
  community.general.one_service:
    template_id: 90
  register: result

- name: Print service properties
  ansible.builtin.debug:
    msg: result

- name: Instantiate a new service with specified service_name, service group and mode
  community.general.one_service:
    template_name: 'app1_template'
    service_name: 'app1'
    group_id: 1
    mode: '660'

- name: Instantiate a new service with template_id and pass custom_attrs dict
  community.general.one_service:
    template_id: 90
    custom_attrs:
      public_network_id: 21
      private_network_id: 26

- name: Instantiate a new service 'foo' if the service doesn't already exist, otherwise do nothing
  community.general.one_service:
    template_id: 53
    service_name: 'foo'
    unique: true

- name: Delete a service by ID
  community.general.one_service:
    service_id: 153
    state: absent

- name: Get service info
  community.general.one_service:
    service_id: 153
  register: service_info

- name: Change service owner, group and mode
  community.general.one_service:
    service_name: 'app2'
    owner_id: 34
    group_id: 113
    mode: '600'

- name: Instantiate service and wait for it to become RUNNING
  community.general.one_service:
    template_id: 43
    service_name: 'foo1'

- name: Wait service to become RUNNING
  community.general.one_service:
    service_id: 112
    wait: true

- name: Change role cardinality
  community.general.one_service:
    service_id: 153
    role: bar
    cardinality: 5

- name: Change role cardinality and wait for it to be applied
  community.general.one_service:
    service_id: 112
    role: foo
    cardinality: 7
    wait: true
a,  
service_id:
  description: Service ID.
  type: int
  returned: success
  sample: 153
service_name:
  description: Service name.
  type: str
  returned: success
  sample: app1
group_id:
  description: Service's group ID.
  type: int
  returned: success
  sample: 1
group_name:
  description: Service's group name.
  type: str
  returned: success
  sample: one-users
owner_id:
  description: Service's owner ID.
  type: int
  returned: success
  sample: 143
owner_name:
  description: Service's owner name.
  type: str
  returned: success
  sample: ansible-test
state:
  description: State of service instance.
  type: str
  returned: success
  sample: RUNNING
mode:
  description: Service's mode.
  type: int
  returned: success
  sample: 660
roles:
  description: List of dictionaries of roles, each role is described by name, cardinality, state and nodes IDs.
  type: list
  returned: success
  sample:
    - {"cardinality": 1, "name": "foo", "state": "RUNNING", "ids": [123, 456]}
    - {"cardinality": 2, "name": "bar", "state": "RUNNING", "ids": [452, 567, 746]}
N)AnsibleModule)open_url)PENDING	DEPLOYINGRUNNINGUNDEPLOYINGWARNINGDONEFAILED_UNDEPLOYINGFAILED_DEPLOYINGSCALINGFAILED_SCALINGCOOLDOWNc                    	 t        |j                  dz   dd|j                  |j                        }| j                  j                               S # t        $ r%}| j                  t        |             Y d }~Hd }~ww xY w)Nz/service_templateGETT)urlmethodforce_basic_authurl_usernameurl_passwordmsg	r   r   userpassword	Exception	fail_jsonstr	from_jsonread)moduleauthall_templateses       q/home/dcms/DCMS/lib/python3.12/site-packages/ansible_collections/community/general/plugins/modules/one_service.pyget_all_templatesr)      s    % dhh1D&Defjy}  zC  zC  RV  R_  R_  ` M..011  %SV$$%   1A 	B A;;B c                     t        | |      }d}d }d}d|v r)d|d   v r"|d   d   D ]  } ||      s|dz   }|}|d   } |dk  ry |dkD  r| j                  d|z          y |S )	Nr    DOCUMENT_POOLDOCUMENT   NAMEz'There is no template with unique name: r   )r)   r    )r$   r%   predall_templates_dictfoundfound_templatetemplate_nametemplates           r(   get_templater7      s    *648ENM,,?QRa?b1b*?;JG 	1HH~	!) ( 0		1 z	FVW    c                    	 t        |j                  dz   dd|j                  |j                        }| j                  j                               S # t        $ r%}| j                  t        |             Y d }~Hd }~ww xY w)Nz/servicer   Tr   r   r   r   r   r   )r$   r%   responser'   s       r(   get_all_servicesr<     s    %DHHz1%RVeienen  ~B  ~K  ~K  L HMMO,,  %SV$$%r*   c                     t        | |      }d}d }d}d|v r)d|d   v r"|d   d   D ]  } ||      s|dz   }|}|d   } |dkD  r| j                  d|z   dz   	       y |dk  ry |S )
Nr   r,   r-   r.   r/   r0   z*There are multiple services with a name: 'zE'. You have to use a unique service name or use 'service_id' instead.r   )r<   r    )r$   r%   r1   all_services_dictr3   found_serviceservice_nameservices           r(   get_servicerB     s    (6EML++
>OP_>`0`(9*E 	/GG}	 '&v		/ qyI%&(op 	q	!r8   c                 ,    rt        | |fd      S d S )Nc                 8    t        | d         t              k(  S NIDint)rA   
service_ids    r(   <lambda>z#get_service_by_id.<locals>.<lambda>4  s    c'$-6HCPZO6[ r8   rB   )r$   r%   rI   s     `r(   get_service_by_idrL   3  s    ak;vt%\]uquur8   c                 $    t        | |fd      S )Nc                     | d   k(  S Nr0    )rA   r@   s    r(   rJ   z%get_service_by_name.<locals>.<lambda>8  s    gfo6U r8   rK   )r$   r%   r@   s     `r(   get_service_by_namerQ   7  s    vt%VWWr8   c           
         t        |d         |d   t        |d         |d   t        |d         |d   t        |d   d   d	      d
}|d   d   d   }g }|D ]U  }g }d|v r|d   D ]  }|j                  |d           |j                  |d   |d   t        t        |d	            |d       W ||d<   t        t        |            |d<   |S )NrF   r0   GIDGNAMEUIDUNAMETEMPLATEBODYstate)rI   r@   group_id
group_nameowner_id
owner_namerY   rolesnodes	deploy_idnamecardinality)ra   rb   rY   idsmode)rH   STATESappendparse_service_permissions)	r$   r%   rA   resultroles_statusr^   role	nodes_idsnodes	            r(   get_service_inform   ;  s    '$-('g&'g&
+F3G<=F :&v.w7LE H	d?W 4  k!234d6l4;NY_`cdhipdq`rYs  }F  G  	HH F7O27;<F6NMr8   c                    |j                         D 	ci c]  \  }}	|t        |	       }
}}	ddd|
|didi}	 t        |j                  dz   t        |      z   dz   d| j	                  |      d	|j
                  |j                  
      }| j                  j                               d   }|S c c}	}w # t        $ r%}| j                  t        |             Y d }~Sd }~ww xY w)Nactioninstantiatemerge_template)custom_attrs_valuesra   performparamsz/service_template//actionPOSTT)r   datar   r   r   r   r.   )itemsr!   r   r   jsonifyr   r   r   r    r"   r#   )r$   r%   template_idr@   custom_attrsuniquewaitwait_timeoutkvcustom_attrs_with_strrx   r;   r'   service_results                  r(   create_servicer   V  s    3?3E3E3GH41aQAYHH 	$ +@(#

D%DHH';;c+>NNQZZci!'!5[_[d[dsw  tA  tAB
 %%hmmo6zBN- I"  %SV$$%s   B.AB4 4	C"=CC"c                    dd l }|j                         }|j                         |z
  |k  rN	 t        |j                  dz   t        |      z   dd|j                  |j
                        }| j                  j                               }|d   d	   d
   d   }|t        j                  d      t        j                  d      fv r|d   S |t        j                  d      t        j                  d      t        j                  d      fvrId}	|d   d	   d
   d   D ]  }
|
d   dk(  s|	|
d   z   }	 n | j                  dt        |   z   dz   |	z          |j                  d       |j                         |z
  |k  rN| j                  d       y # t        $ r)}| j                  dt        |      z          Y d }~Pd }~ww xY w)Nr   	/service/r   Tr:   z6Request for service status has failed. Error message: r   r.   rW   rX   rY   r
   r   r   r	   r   r,   logseverityEmessagez*Deploying is unsuccessful. Service state: z. Error message: r/   zWait timeout has expired)timer   r   r!   r   r   r   r    r"   r#   re   indexsleep)r$   r%   rI   r   r   
start_timestatus_resultr'   service_statelog_messagelog_infos              r(    wait_for_service_to_become_readyr   q  s   J99;#|
3	d$TXX%;c*o%MV[6:aeananpM
 ((););)=>%j1*=fEgNV\\)4fll:6NOO ,,6<<	#:FLL<UW]WcWcdmWn"ooK)*5jA&I%P J'3."-0C"CK
 !MPVWdPe!eh{!{  J  "J  K

1+ 99;#|
3. 34'  	d!Y\_`a\b!bcc	ds   =F 	F?F::F?c           
         ddd|idi}	 t        |j                  dz   t        |      z   dz   dd|j                  |j                  | j                  |      	      }y # t        $ r%}| j                  t        |      
       Y d }~y d }~ww xY w)Nro   chmodoctetrs   r   rv   rw   Tr   r   r   r   rx   r   r   r   r!   r   r   rz   r   r    )r$   r%   rI   permissionsrx   r   r'   s          r(   change_service_permissionsr     s     	,
D% K!7#j/!II!U^dw{.2iidmmZ`ZhZhimZnp %SV$$%   AA 	B
%BB
c           
         ddd|idi}	 t        |j                  dz   t        |      z   dz   dd|j                  |j                  | j                  |      	      }y # t        $ r%}| j                  t        |      
       Y d }~y d }~ww xY w)Nro   chownr\   rs   r   rv   rw   Tr   r   r   )r$   r%   rI   r\   rx   r   r'   s          r(   change_service_ownerr     s    !8,
D% K!7#j/!II!U^dw{.2iidmmZ`ZhZhimZnp %SV$$%r   c           
         ddd|idi}	 t        |j                  dz   t        |      z   dz   dd|j                  |j                  | j                  |      	      }y # t        $ r%}| j                  t        |      
       Y d }~y d }~ww xY w)Nro   chgrprZ   rs   r   rv   rw   Tr   r   r   )r$   r%   rI   rZ   rx   r   r'   s          r(   change_service_groupr     s     	!8,
D% K!7#j/!II!U^dw{.2iidmmZ`ZhZhimZnp %SV$$%r   c           
         ||d}	 t        |j                  dz   t        |      z   dz   |z   dd|j                  |j                  | j                  |            }j                         dk7  r3| j                  d	|z   d
z   t        |j                               z          y y # t        $ r%}| j                  t        |             Y d }~pd }~ww xY w)N)rb   forcer   z/role/PUTTr   r      z'Failed to change cardinality for role: z. Return code: )	r   r   r!   r   r   rz   r   r    getcode)	r$   r%   rI   rj   rb   r   rx   r   r'   s	            r(   change_role_cardinalityr     s     #D
% K!7#j/!IH!TW[![di26TYY]a]j]jqwqq  AE  rFG
 #%FMPaadghuh}h}h  eA  A  	B &  %SV$$%s   AB! !	C*C

Cc                 (    t        |d         }||k7  S )NrU   rG   )r$   rA   r\   old_owner_ids       r(   check_change_service_ownerr         wu~&L8##r8   c                 (    t        |d         }||k7  S )NrS   rG   )r$   rA   rZ   old_group_ids       r(   check_change_service_groupr     r   r8   c                    | d   }	 t        |d         dz  t        |d         dz  z   t        |d         z   }t        |d         dz  t        |d         dz  z   t        |d	         z   }t        |d
         dz  t        |d         dz  z   t        |d         z   }t        |      t        |      z   t        |      z   }|S )NPERMISSIONSOWNER_U   OWNER_M   OWNER_AGROUP_UGROUP_MGROUP_AOTHER_UOTHER_MOTHER_A)rH   r!   )rA   	perm_dictowner_octalgroup_octalother_octalr   s         r(   rg   rg     s    &I  i	*+a/#i	6J2Ka2OORUV_`iVjRkkKi	*+a/#i	6J2Ka2OORUV_`iVjRkkKi	*+a/#i	6J2Ka2OORUV_`iVjRkkKk"S%55K8HHKr8   c                 "    t        |      }||k7  S )N)rg   )r$   rA   r   old_permissionss       r(    check_change_service_permissionsr     s    /8Ok))r8   c                     |d   d   d   }|D ]  }|d   |k(  st        |d         |k7  c S  | j                  d|z          y )NrW   rX   r^   ra   rb   zThere is no role with name: r   )rH   r    )r$   rA   	role_namerb   
roles_listrj   s         r(   check_change_role_cardinalityr     s_    $V,W5J ;<9$tM*+{::; 7)CDr8   c           
          |sd}d}d }|rt        | ||      }|r|d   d   d   dk(  r | j                  st        | ||||||	|
      }d}| j                  r|rddiS t        | ||||	|
||	      }|d   rd}||d<   |S )
Nr,   FrW   rX   rY   r   Tchanged)r\   rZ   r~   r   r   rA   )rQ   
check_moder   service_operation)r$   r%   r{   r@   r\   rZ   r   r|   r}   r~   r   r   rA   rh   s                 r(   create_service_and_operationr     s    GG%fdLAgj)&1':fD  $VT;l\bdhjvwG W4  vthX\,8k[bdF iF9Mr8   c                 L   d}|st        | ||      }n|d   }|s| j                  dt        |      z          |r)t        | ||      r| j                  st        | |||       d}|r)t        | ||      r| j                  st        | |||       d}|r)t        | ||      r| j                  st        | |||       d}|r,t        | |||      r| j                  st        | |||||       d}|	r| j                  st        | |||
      }|rt        | ||      }t        | ||      }||d<   |S )NFrF   zThere is no service with id: r   Tr   )rL   r    r!   r   r   r   r   r   r   r   r   r   r   rm   )r$   r%   rI   r\   rZ   r   rj   rb   r   r~   r   rA   r   service_infos                 r(   r   r   #  s@    G#FD*=T]
<s:NO%fgx@$$$VT:xHG%fgx@$$$VT:xHG+FG[I$$*64[QG($L$$'j$UZ[GF%%264\Z #FD*=#FD':L%Lr8   c                 R   t        | ||      }|sddiS t        | ||      }d|d<   | j                  r|S 	 t        |j                  dz   t        |      z   dd|j                  |j                        }|S # t        $ r)}| j                  dt        |      z          Y d }~|S d }~ww xY w)	Nr   FTr   DELETEr:   z,Service deletion has failed. Error message: r   )
rL   rm   r   r   r   r!   r   r   r   r    )r$   r%   rI   rA   r   rh   r'   s          r(   delete_servicer   S  s    j9G5!!#FD':L"LV$(([03z?B8fjy}  zC  zC  RV  R_  R_  `   VKcRSfTUUVs   =A4 4	B&=B!!B&c                 $    t        | |fd      S )Nc                     | d   k(  S rO   rP   )r6   r5   s    r(   rJ   z&get_template_by_name.<locals>.<lambda>h  s    8HM8Y r8   r7   )r$   r%   r5   s     `r(   get_template_by_namer   g  s    &Z[[r8   c                 ,    rt        | |fd      S d S )Nc                 8    t        | d         t              k(  S rE   rG   )r6   r{   s    r(   rJ   z$get_template_by_id.<locals>.<lambda>l  s    HTN8KsS^O_8_ r8   r   )r$   r%   r{   s     `r(   get_template_by_idr   k  s    ep<&`azvzzr8   c                 J    |rt        | ||      nt        | ||      }|r|d   S y rE   )r   r   )r$   r%   requested_idrequested_namer6   s        r(   get_template_idr   o  s:    AM!&$=Sghnpt  wE  TFH~r8   c                 ,    t        | ||      }|r|d   S y rE   )rQ   )r$   r%   r@   rA   s       r(   get_service_id_by_namer   x  s     !&$=Gt}r8   c                    | j                   j                  d      }| j                   j                  d      }| j                   j                  d      }|st        j                  j                  d      }|st        j                  j                  d      }|st        j                  j                  d      }|r|r|s| j	                  d       d	d
lm}  |dd      } ||||      S )Napi_urlapi_usernameapi_passwordONEFLOW_URLONEFLOW_USERNAMEONEFLOW_PASSWORDzZOne or more connection parameters (api_url, api_username, api_password) were not specifiedr   r   )
namedtupler%   )r   r   r   )ru   getosenvironr    collectionsr   )r$   r   usernamer   r   auth_paramss         r(   get_connection_infor     s    
--

I
&C}}  0H}}  0Hjjnn]+::>>"45::>>"45Hyz&V%@AK3XAAr8   c                     i dddddddddddddd	dddd
dddddddddddddddgdddddddddddddddddddddddddddi ddddddddddddddi} t        | g d d
d	gg d!g d"d
dggddggd#      }t        |      }|j                  }|j                  d	      }|j                  d
      }|j                  d      }|j                  d      }|j                  d      }|j                  d      }	|j                  d      }
|j                  d      }|j                  d      }|j                  d      }|j                  d      }|j                  d      }|j                  d      }|j                  d      }|j                  d      }d }|s|rHt	        ||||      }|s8|r|j                  d$t        |      z   %       n|r|j                  d&|z   %       |r|s|j                  d'%       |r|dk(  r|j                  d(%       |r|dk(  rt        |||||
||	||||      }n}|s|s|j                  d)%       |r|j                  d*%       |st        |||      }|s|dk(  r|j                  d+|z   %       |dk(  rt        |||      }nt        ||||
||	|||||      } |j                  d,i | y )-Nr   Fr!   )requiredtyper   r   T)r   r   no_logr@   rI   rH   r5   r{   rY   presentabsent)defaultchoicesr   rd   r\   rZ   r}   bool)r   r   r~   r   i,  r|   dictrj   rb   r   )r{   r5   rI   )r{   r5   rj   )r{   r5   rb   )argument_specmutually_exclusiverequired_togethersupports_check_modez'There is no template with template_id: r   z There is no template with name: z3You cannot use unique without passing service_name!z&State absent is not valid for templatezRTo manage the service at least the service id or service name should be specified!z7You can only set custom_attrs when instantiate service!zThere is no service with name: rP   )r   r   ru   r   r   r    r!   r   r   r   r   	exit_json)fieldsr$   r%   ru   r@   rI   requested_template_idrequested_template_namerY   r   r\   rZ   r}   r~   r   r|   rj   rb   r   r{   rh   s                        r(   mainr     s   u5UE: 	UETJ 	UE:	
 	5%8 	eU; 	E59 	 !8,
 	UE2 	6 	6  	eV4!" 	E62#$ 	C7%& 	B7'( 	UE2)* 	E59+, 	UF3-F2 M ,n=GN ,n=/ 06}.E-F/3	5F v&D]]F::n-LL)J"JJ}5$jj9JJwE**V$Kzz*%Hzz*%HZZ!F::fD::n-L::n-L::fD**]+KJJwEK 7%fd4IKbc$  %NQTUjQk%k l(  %GJa%a blRSu(EFu	)-fdKW_.6\SY[_amo l!uv!Z[/lKJey0!B\!QRH#FD*=F&vtZ8U`bfhsuz  }A  CO  PFFvr8   __main__)
NNNNNNNFNN)+
__future__r   r   r   r   __metaclass__DOCUMENTATIONEXAMPLESRETURNr   ansible.module_utils.basicr   ansible.module_utils.urlsr   re   r)   r7   r<   rB   rL   rQ   rm   r   r   r   r   r   r   r   r   rg   r   r   r   r   r   r   r   r   r   r   r   __name__rP   r8   r(   <module>r	     s    C BeNEN0
d 
 4 .
]2,-0vX665<% %% B"$$6*E: `dfj-`(\{B.\~ zF r8   