Commit 7c761994 authored by Romain Courteaud's avatar Romain Courteaud

slapos_cloud:

* drop support request template preference
* drop my_preferred_support_request_template
* stop using getPreferredSupportRequestTemplate
* drop Subscription Condition usage
* break Base_getSupportRequestInProgress
  Use causality category instead of aggregate, to link the Ticket to the context document (instance, node, ...).
  Aggregate must be used to define the item of the movement resource.
  Break the parameters and use the context to define the causality value.
* use causality to link the  Ticket to the context document
* XXX disable person.notify & person.requestSupport
  I don't get why there are 2 transitions for now.
* drop ComputerNetwork_viewComputeNodeList
* drop notify and requestSupport transitions
  They have been replaced by python script and alarms
* test: person.notify has been dropped
* drop slapos_crm_regularisation_request_template
* Do not allow user to change the release/type/shared status
* no need to use a tag if context is not reindexed
* allow to force software change
* speed up Base_reindexAndSenseAlarm execution
* drop my_preferred_default_pre_payment_template
* drop default_pre_payment_subscription_invoice_template
* drop getPreferredAggregatedSubscriptionSaleTradeCondition
* test: drop unused functions
* drop preferred_aggregated_sale_trade_condition
* drop preferred_aggregated_sale_trade_condition
* test: drop reference to slapos_aggregated_trade_condition_v3
* test: drop test from dropped interaction
* test: role is not required on a Person
* test: do not invalidate instance to not unlink
* test: create Trade Condition when Project is accountable
* drop slapos_crm_web_message_template
* drop my_preferred_web_message_template
* drop template_pre_payment_subscription_sale_invoice_transaction
* drop preferred_default_pre_payment_subscription_invoice_template
* drop slapos_accounting_instance_delivery_line_template
* drop slapos_aggregated_consumption_trade_condition
* drop preferred_aggregated_consumption_sale_trade_condition
* drop unused template
* drop template_computer_model
* drop template_hosting_subscription
* drop template_software_installation
* drop template_compute_node
* drop template_instance_tree
* drop template_software_instance
* drop template_member
* drop drop template_software_instance
* drop template_software_instance
* drop template_software_instance
* add afterClone scripts
* test: check remote node parameters propagation
* try to create an upgrade decision for a remote instance
* test: add checkRemoteInstanceUnallocation method
* XXX stop invalidating Slave Instance
  TODO: Instance on Remote Node must propagate their destruction, before being invalidated
* instance must be invalidated before unallocating it
* drop not needed script
* invalidate Slave Instance allocation on a Compute Node
* trigger invalidation as soon as an Instance is destroyed
* alarm must visit allocated Slave Instance to invalidate them
* report software url of the linked instance, even if it is in destroyed_state / invalidated
* test: slave are not directly invalidated as soon as it is destroyed
* propagate remote node destruction
* do not crash if no instance is found
* ExactMatch
* drop comments
* keep compatibility with project_guid sla
* allow to propagate a single instance
* add subordination category on Remote Node
* try to wait for previous alarms to finish before triggering a new one
* priority 3
* do not call activeSense concurrently
* prevent activeSense to be called concurrently
* reduce number of activities
* do not loop
* drop preferred_cloud_contract_enabled
* stop using hateoas web site
* change the skin selection to register
* test: create needed bank account
parent b8ae0c1c
<module> <module>
<category_list>
<category>business_application/slapos</category>
</category_list>
<id>allocation_supply_module</id> <id>allocation_supply_module</id>
<permission_list> <permission_list>
<permission type='tuple'> <permission type='tuple'>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Compute Node" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>template_compute_node</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Compute Node</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Computer Model" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>capacity_quantity</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>template_computer_model</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Computer Model</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>template_computer_model</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Hosting Subscription" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Delete_objects_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>template_hosting_subscription</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>periodicity_hour</string> </key>
<value>
<tuple>
<int>0</int>
</tuple>
</value>
</item>
<item>
<key> <string>periodicity_minute</string> </key>
<value>
<tuple>
<int>0</int>
</tuple>
</value>
</item>
<item>
<key> <string>periodicity_month_day</string> </key>
<value>
<tuple>
<int>17</int>
</tuple>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Hosting Subscription</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Instance Tree" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Delete_objects_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value> <string>RootSoftwareInstance</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>template_instance_tree</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>periodicity_hour</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_minute</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_month</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_month_day</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>periodicity_week</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Instance Tree</string> </value>
</item>
<item>
<key> <string>root_slave</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>sla_xml</string> </key>
<value> <string encoding="cdata"><![CDATA[
<?xml version=\'1.0\' encoding=\'utf-8\'?>\n
<instance>\n
<parameter id="computer_guid">SOMECOMP</parameter>\n
</instance>\n
]]></string> </value>
</item>
<item>
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
<?xml version="1.0" encoding="utf-8"?>\n
<instance>\n
<parameter id="parameter1">valueof1</parameter>\n
<parameter id="parameter2">valueof2</parameter>\n
</instance>
]]></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Template Instance Tree</string> </value>
</item>
<item>
<key> <string>url_string</string> </key>
<value> <string>http://example.com/root/software/release</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Person" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Author</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>__translation_dict</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>_count</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>_mt_index</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>_tree</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>first_name</string> </key>
<value> <string>Member</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>template_member</string> </value>
</item>
<item>
<key> <string>last_name</string> </key>
<value> <string>Template</string> </value>
</item>
<item>
<key> <string>password</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Person</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Length" module="BTrees.Length"/>
</pickle>
<pickle> <int>0</int> </pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="OOBTree" module="BTrees.OOBTree"/>
</pickle>
<pickle>
<none/>
</pickle>
</record>
<record id="5" aka="AAAAAAAAAAU=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value> <string>{SSHA}f1gAG3A53rfwjkLB/+Ex89MtocZz/4V9K4TZ</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Address" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>city</string> </key>
<value> <string>azezae</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>default_address</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Address</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>street_address</string> </key>
<value> <string>address</string> </value>
</item>
<item>
<key> <string>zip_code</string> </key>
<value> <string>123456</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Career" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>role/client</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>default_career</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Career</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Email" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>default_email</string> </value>
</item>
<item>
<key> <string>int_index</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Email</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>url_string</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Telephone" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>coordinate_text</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>default_telephone</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Telephone</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>telephone_number</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Software Installation" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Delete_objects_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>template_software_installation</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Software Installation</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Slave Instance" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Delete_objects_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>connection_xml</string> </key>
<value> <string encoding="cdata"><![CDATA[
<?xml version=\'1.0\' encoding=\'utf-8\'?>\n
<instance>\n
<parameter id="parameter1">valueof1</parameter>\n
<parameter id="parameter2">https://niut:pass@example.com:4567/arfarf/oink?m=1#4.5</parameter>\n
</instance>\n
]]></string> </value>
</item>
<item>
<key> <string>default_destination_reference</string> </key>
<value> <string>02</string> </value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>SItestVifibSlaposRestAPIV1.TestVifibSlaposRestAPIV1.test_instance_destruction_started0.325656030454</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value> <string>RootSoftwareInstance</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>template_slave_instance</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Slave Instance</string> </value>
</item>
<item>
<key> <string>sla_xml</string> </key>
<value> <string encoding="cdata"><![CDATA[
<?xml version=\'1.0\' encoding=\'utf-8\'?>\n
<instance>\n
<parameter id="computer_guid">SOMECOMP</parameter>\n
</instance>\n
]]></string> </value>
</item>
<item>
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
<?xml version="1.0" encoding="utf-8"?>\n
<instance>\n
<parameter id="parameter1">valueof1</parameter>\n
<parameter id="parameter2">valueof2</parameter>\n
</instance>
]]></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Template Slave Instance</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Software Instance" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Delete_objects_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>connection_xml</string> </key>
<value> <string encoding="cdata"><![CDATA[
<?xml version=\'1.0\' encoding=\'utf-8\'?>\n
<instance>\n
<parameter id="parameter1">valueof1</parameter>\n
<parameter id="parameter2">https://niut:pass@example.com:4567/arfarf/oink?m=1#4.5</parameter>\n
</instance>\n
]]></string> </value>
</item>
<item>
<key> <string>default_destination_reference</string> </key>
<value> <string>02</string> </value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>SItestVifibSlaposRestAPIV1.TestVifibSlaposRestAPIV1.test_instance_destruction_started0.325656030454</string> </value>
</item>
<item>
<key> <string>default_source_reference</string> </key>
<value> <string>RootSoftwareInstance</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>template_software_instance</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Software Instance</string> </value>
</item>
<item>
<key> <string>sla_xml</string> </key>
<value> <string encoding="cdata"><![CDATA[
<?xml version=\'1.0\' encoding=\'utf-8\'?>\n
<instance>\n
<parameter id="computer_guid">SOMECOMP</parameter>\n
</instance>\n
]]></string> </value>
</item>
<item>
<key> <string>ssl_certificate</string> </key>
<value> <string>Certificate:\n
Data:\n
Version: 3 (0x2)\n
Serial Number: 2 (0x2)\n
Signature Algorithm: sha1WithRSAEncryption\n
Issuer: C=PL, ST=Silesia, L=Bytom, O=Luke Ltd, CN=Certificate Authority bdbe24bc-889b-11e1-973b-00215dc2e59c/emailAddress=luke@nexedi.com\n
Validity\n
Not Before: Apr 19 14:28:02 2012 GMT\n
Not After : Apr 17 14:28:02 2022 GMT\n
Subject: C=PL, ST=Silesia, O=Luke Ltd, CN=SOFTINST-0/emailAddress=luke@nexedi.com\n
Subject Public Key Info:\n
Public Key Algorithm: rsaEncryption\n
Public-Key: (2048 bit)\n
Modulus:\n
00:b8:98:81:1c:ba:85:f3:d0:a6:bd:83:06:5a:06:\n
4a:b6:1e:ed:32:44:81:9e:97:b9:33:0a:e1:cd:7c:\n
02:f8:1e:c5:56:8e:e6:75:c5:a2:44:a8:60:3d:f1:\n
be:b4:c5:91:00:21:a4:89:a7:00:c3:9f:3d:49:1e:\n
ed:be:37:3b:06:95:56:2f:2f:0a:7f:80:e8:69:13:\n
57:51:54:6e:c6:16:bf:3d:74:3a:84:68:10:ec:be:\n
bc:60:5a:d9:07:dd:00:0a:55:78:d9:6d:42:12:c3:\n
ba:93:f4:8f:16:29:00:21:4c:86:cc:40:0f:61:ad:\n
27:aa:42:8a:ff:59:94:21:c0:d1:25:dc:99:c6:20:\n
3b:43:e0:60:0c:e7:86:e1:18:bc:44:eb:12:77:5f:\n
f8:a7:57:61:e4:63:63:f8:20:48:6e:3b:64:c9:97:\n
ab:4b:ea:3a:e8:96:e9:ff:98:36:aa:d8:c6:77:c5:\n
eb:48:24:05:a9:b0:45:34:ea:81:57:df:64:29:a0:\n
fa:0e:5c:d2:ff:47:5a:90:63:a6:3d:27:19:31:88:\n
07:0e:d0:17:ae:17:1a:c8:fc:e8:75:ca:17:24:33:\n
99:4d:51:c2:6b:26:69:35:94:88:97:3c:68:d1:b5:\n
6b:84:75:55:fa:0c:15:d1:8a:80:d1:7e:aa:0a:4e:\n
4e:e7\n
Exponent: 65537 (0x10001)\n
X509v3 extensions:\n
X509v3 Basic Constraints: \n
CA:FALSE\n
Netscape Comment: \n
OpenSSL Generated Certificate\n
X509v3 Subject Key Identifier: \n
DE:9F:89:65:E1:7C:A3:88:A1:EE:79:A4:81:A8:97:C5:F5:E5:6B:DA\n
X509v3 Authority Key Identifier: \n
keyid:98:C1:BA:FC:AE:0A:0E:B1:0D:80:79:95:1A:7B:BE:6E:F4:DE:31:9E\n
\n
Signature Algorithm: sha1WithRSAEncryption\n
73:b2:c7:a9:e2:75:b7:69:a7:11:1b:8b:8a:eb:1f:bd:37:a8:\n
73:d0:67:00:d9:54:ca:c3:82:f5:f4:e1:6f:0d:ad:2c:50:b2:\n
ec:74:ae:c1:87:bc:33:4e:8e:e7:56:be:1c:77:7f:7c:2d:90:\n
19:54:ed:ac:a7:99:cb:01:4c:df:ca:c7:9f:56:32:3e:7a:98:\n
fe:bf:73:fc:12:d3:33:dc:f4:10:16:0a:1f:c4:10:33:e0:14:\n
0a:2f:dd:7a:5d:34:ec:1a:b0:68:d1:ec:91:cb:9a:c6:b7:8a:\n
04:b8:69:50:b0:ef:34:2a:62:af:95:43:86:5b:6c:92:65:25:\n
e5:6d:0c:95:f3:f7:19:0f:33:71:12:80:fe:21:da:f1:8a:24:\n
bb:ae:75:3d:af:b6:22:f4:01:26:31:23:1f:a9:8d:6a:7c:a8:\n
1a:81:7b:38:12:e1:95:62:3c:22:f1:66:81:8e:88:6b:a6:e0:\n
0e:9a:54:69:08:96:ad:42:d4:43:0c:8a:48:7b:fc:72:9c:b8:\n
7c:f9:7b:6f:55:35:86:66:26:92:2c:5f:8d:0a:85:94:87:c4:\n
41:cb:b7:35:52:80:a6:5a:f4:0d:a8:93:bc:88:41:29:d5:cf:\n
af:bd:f2:e5:28:a1:cb:d6:d2:aa:c3:e4:0e:0b:11:e9:85:ea:\n
7b:2d:7b:14\n
-----BEGIN CERTIFICATE-----\n
MIIEBTCCAu2gAwIBAgIBAjANBgkqhkiG9w0BAQUFADCBpzELMAkGA1UEBhMCUEwx\n
EDAOBgNVBAgMB1NpbGVzaWExDjAMBgNVBAcMBUJ5dG9tMREwDwYDVQQKDAhMdWtl\n
IEx0ZDFDMEEGA1UEAww6Q2VydGlmaWNhdGUgQXV0aG9yaXR5IGJkYmUyNGJjLTg4\n
OWItMTFlMS05NzNiLTAwMjE1ZGMyZTU5YzEeMBwGCSqGSIb3DQEJARYPbHVrZUBu\n
ZXhlZGkuY29tMB4XDTEyMDQxOTE0MjgwMloXDTIyMDQxNzE0MjgwMlowZzELMAkG\n
A1UEBhMCUEwxEDAOBgNVBAgMB1NpbGVzaWExETAPBgNVBAoMCEx1a2UgTHRkMRMw\n
EQYDVQQDDApTT0ZUSU5TVC0wMR4wHAYJKoZIhvcNAQkBFg9sdWtlQG5leGVkaS5j\n
b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC4mIEcuoXz0Ka9gwZa\n
Bkq2Hu0yRIGel7kzCuHNfAL4HsVWjuZ1xaJEqGA98b60xZEAIaSJpwDDnz1JHu2+\n
NzsGlVYvLwp/gOhpE1dRVG7GFr89dDqEaBDsvrxgWtkH3QAKVXjZbUISw7qT9I8W\n
KQAhTIbMQA9hrSeqQor/WZQhwNEl3JnGIDtD4GAM54bhGLxE6xJ3X/inV2HkY2P4\n
IEhuO2TJl6tL6jrolun/mDaq2MZ3xetIJAWpsEU06oFX32QpoPoOXNL/R1qQY6Y9\n
JxkxiAcO0BeuFxrI/Oh1yhckM5lNUcJrJmk1lIiXPGjRtWuEdVX6DBXRioDRfqoK\n
Tk7nAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wg\n
R2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBTen4ll4XyjiKHueaSBqJfF\n
9eVr2jAfBgNVHSMEGDAWgBSYwbr8rgoOsQ2AeZUae75u9N4xnjANBgkqhkiG9w0B\n
AQUFAAOCAQEAc7LHqeJ1t2mnERuLiusfvTeoc9BnANlUysOC9fThbw2tLFCy7HSu\n
wYe8M06O51a+HHd/fC2QGVTtrKeZywFM38rHn1YyPnqY/r9z/BLTM9z0EBYKH8QQ\n
M+AUCi/del007BqwaNHskcuaxreKBLhpULDvNCpir5VDhltskmUl5W0MlfP3GQ8z\n
cRKA/iHa8Yoku651Pa+2IvQBJjEjH6mNanyoGoF7OBLhlWI8IvFmgY6Ia6bgDppU\n
aQiWrULUQwyKSHv8cpy4fPl7b1U1hmYmkixfjQqFlIfEQcu3NVKAplr0DaiTvIhB\n
KdXPr73y5Sihy9bSqsPkDgsR6YXqey17FA==\n
-----END CERTIFICATE-----\n
</string> </value>
</item>
<item>
<key> <string>ssl_key</string> </key>
<value> <string>-----BEGIN PRIVATE KEY-----\n
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC4mIEcuoXz0Ka9\n
gwZaBkq2Hu0yRIGel7kzCuHNfAL4HsVWjuZ1xaJEqGA98b60xZEAIaSJpwDDnz1J\n
Hu2+NzsGlVYvLwp/gOhpE1dRVG7GFr89dDqEaBDsvrxgWtkH3QAKVXjZbUISw7qT\n
9I8WKQAhTIbMQA9hrSeqQor/WZQhwNEl3JnGIDtD4GAM54bhGLxE6xJ3X/inV2Hk\n
Y2P4IEhuO2TJl6tL6jrolun/mDaq2MZ3xetIJAWpsEU06oFX32QpoPoOXNL/R1qQ\n
Y6Y9JxkxiAcO0BeuFxrI/Oh1yhckM5lNUcJrJmk1lIiXPGjRtWuEdVX6DBXRioDR\n
fqoKTk7nAgMBAAECggEAMh9et3FCHADktYKVP+6DbM4a89I8K9bgt6ZVx5jLqZmZ\n
VbZ5hzMBq4jYkRlKAgW/KHz6E1JgV72uQ2N9hG+0vEXiX+9y90oGUTmqNPArH+hf\n
Rw1/MiKbrdzgg31HfuYYM7YfmVIcZcH1sGTwUUESwvfnhiBCzO/aXFWzLkChg0RE\n
l3Nk732x5EhY1TdwzWP74QMFOfSfg63LC0+nJByxOYyBZorV16v1VRqGzghRTeGP\n
v/OpsvhMYXm7kh0kfq7qbXpaeWPnWS06qWM1ekBmdYSgzw4wShgeUrOeb23VmjOW\n
I8ICPcl4jlrO2tVK1aHupcTZCAvl8SW+0c4jB1qk8QKBgQDjwT/Qz8WKhRw25wlx\n
I1vJMR1WeoF2FBESojLY3ZZPr035KOM8PjIPPLcjQIvOdOsHhrlvdiI0FYj+3I6q\n
jB8X3Lq6xBEw7F5516+xVxsfxEE8itMJXK6QNMaeOO2mrnJv6j6Ss6SXQRliqJlO\n
AQTKeghYWmLlKERpPzPmkGXy2QKBgQDPfQpJQkZbfmKbb+TusycsHj/XVgWTasJS\n
SuIW9DeFMYfbBLLunzVjBy87XbXpyHeR1XqoPEM6ICDQlUJS5IDwsttJJfrF1iJ3\n
scGgFg4JIzruqG2t8RLLXKsWpgxQz2Qxqx5DgCdXXAbVdjHkJjQ+PdWb6kDvN+bX\n
qR+UOa23vwKBgQDaoehgyxMWpjEvgxnNQeQafstq+K7OavT4rjuhcxWX6PEw/c8l\n
RY9IkUA81vled14nG21nUkADP6kC/zb1AQ3YGkwmfZEDJeSLkkFWPAgNtpfpRlrP\n
4eixBfikaoG4QD4asQLgURLvH87+plqERvYSaJMaPaox0TXa0pFAA93aAQKBgC6o\n
LnT0yz9ttxy+15r5fDiGgNKaTFyu6A17O0XwGr//uE3+y4GvGWEwT2WpF+v/ISwQ\n
9ij4jCF48ggVWDmtmnUFsxvKx45PLab+uMyXyQYy/uCFzUwM5q4GI47PPfu59wzY\n
LtD881vInNzJXESydpL8cplB3uIsDuO16xz4r2CfAoGBAM57WPeUCBoGUzDXKPR/\n
XDcGie2q0bRdlCAUMdCucO2A6Nh3WkDu+ZEMW/JwpwYJGTIZ/kN9158Gn4qPYRtg\n
ZtyrVc7LkDpSHECXGMnvVN8pHoF8bKUS6r1yCvq9Ta+JM7S1M1hwTCkKPACLa7hC\n
wEsr7FKBunKvatC4k/gNd6dc\n
-----END PRIVATE KEY-----\n
</string> </value>
</item>
<item>
<key> <string>text_content</string> </key>
<value> <string encoding="cdata"><![CDATA[
<?xml version="1.0" encoding="utf-8"?>\n
<instance>\n
<parameter id="parameter1">valueof1</parameter>\n
<parameter id="parameter2">valueof2</parameter>\n
</instance>
]]></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Template Software Instance</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
<item>destination_project</item> <item>destination_project</item>
<item>destination_section</item> <item>destination_section</item>
<item>specialise</item> <item>specialise</item>
<item>subordination</item>
</portal_type> </portal_type>
<portal_type id="Slave Instance"> <portal_type id="Slave Instance">
<item>aggregate</item> <item>aggregate</item>
......
...@@ -83,15 +83,21 @@ ...@@ -83,15 +83,21 @@
</item> </item>
<item> <item>
<key> <string>preferred_aggregated_consumption_sale_trade_condition</string> </key> <key> <string>preferred_aggregated_consumption_sale_trade_condition</string> </key>
<value> <string>sale_trade_condition_module/slapos_aggregated_consumption_trade_condition</string> </value> <value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>preferred_aggregated_sale_trade_condition</string> </key> <key> <string>preferred_aggregated_sale_trade_condition</string> </key>
<value> <string>sale_trade_condition_module/slapos_aggregated_trade_condition_v3</string> </value> <value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>preferred_aggregated_subscription_sale_trade_condition</string> </key> <key> <string>preferred_aggregated_subscription_sale_trade_condition</string> </key>
<value> <string>sale_trade_condition_module/slapos_aggregated_subscription_trade_condition_v3</string> </value> <value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>preferred_authentication_failure_block_duration</string> </key> <key> <string>preferred_authentication_failure_block_duration</string> </key>
...@@ -112,12 +118,16 @@ ...@@ -112,12 +118,16 @@
</value> </value>
</item> </item>
<item> <item>
<key> <string>preferred_credential_alarm_automatic_call</string> </key> <key> <string>preferred_cloud_contract_enabled</string> </key>
<value> <int>1</int> </value> <value> <int>1</int> </value>
</item> </item>
<item>
<key> <string>preferred_credential_alarm_automatic_call</string> </key>
<value> <int>0</int> </value>
</item>
<item> <item>
<key> <string>preferred_credential_recovery_automatic_approval</string> </key> <key> <string>preferred_credential_recovery_automatic_approval</string> </key>
<value> <int>1</int> </value> <value> <int>0</int> </value>
</item> </item>
<item> <item>
<key> <string>preferred_credential_request_automatic_approval</string> </key> <key> <string>preferred_credential_request_automatic_approval</string> </key>
...@@ -129,13 +139,15 @@ ...@@ -129,13 +139,15 @@
</item> </item>
<item> <item>
<key> <string>preferred_default_pre_payment_template</string> </key> <key> <string>preferred_default_pre_payment_template</string> </key>
<value> <string>accounting_module/slapos_pre_payment_template</string> </value> <value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>preferred_document_conversion_server_url</string> </key> <key> <string>preferred_document_conversion_server_url</string> </key>
<value> <value>
<tuple> <tuple>
<string>https://cloudooo.erp5.net/</string> <string>https://cloudooo.erp5.net/,https://cloudooo1.erp5.net/</string>
</tuple> </tuple>
</value> </value>
</item> </item>
...@@ -175,19 +187,9 @@ ...@@ -175,19 +187,9 @@
</item> </item>
<item> <item>
<key> <string>preferred_instance_delivery_template</string> </key> <key> <string>preferred_instance_delivery_template</string> </key>
<value> <string>sale_packing_list_module/slapos_accounting_instance_delivery_template</string> </value> <value>
</item> <none/>
<item> </value>
<key> <string>preferred_instance_destroy_movement_template</string> </key>
<value> <string>sale_packing_list_module/slapos_accounting_instance_delivery_line_template/destroy</string> </value>
</item>
<item>
<key> <string>preferred_instance_setup_movement_template</string> </key>
<value> <string>sale_packing_list_module/slapos_accounting_instance_delivery_line_template/setup</string> </value>
</item>
<item>
<key> <string>preferred_instance_update_movement_template</string> </key>
<value> <string>sale_packing_list_module/slapos_accounting_instance_delivery_line_template/update</string> </value>
</item> </item>
<item> <item>
<key> <string>preferred_max_authentication_failure</string> </key> <key> <string>preferred_max_authentication_failure</string> </key>
...@@ -284,7 +286,9 @@ ...@@ -284,7 +286,9 @@
</item> </item>
<item> <item>
<key> <string>preferred_regularisation_request_template</string> </key> <key> <string>preferred_regularisation_request_template</string> </key>
<value> <string>regularisation_request_module/slapos_crm_regularisation_request_template</string> </value> <value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>preferred_regularisation_request_use</string> </key> <key> <string>preferred_regularisation_request_use</string> </key>
...@@ -313,6 +317,7 @@ ...@@ -313,6 +317,7 @@
<value> <value>
<tuple> <tuple>
<string>function/customer</string> <string>function/customer</string>
<string>role/client</string>
</tuple> </tuple>
</value> </value>
</item> </item>
...@@ -332,7 +337,9 @@ ...@@ -332,7 +337,9 @@
</item> </item>
<item> <item>
<key> <string>preferred_support_request_template</string> </key> <key> <string>preferred_support_request_template</string> </key>
<value> <string>support_request_module/slapos_crm_support_request_template</string> </value> <value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>preferred_support_request_use</string> </key> <key> <string>preferred_support_request_use</string> </key>
...@@ -352,7 +359,9 @@ ...@@ -352,7 +359,9 @@
</item> </item>
<item> <item>
<key> <string>preferred_web_message_template</string> </key> <key> <string>preferred_web_message_template</string> </key>
<value> <string>event_module/slapos_crm_web_message_template</string> </value> <value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>preferred_wechat_integration_site</string> </key> <key> <string>preferred_wechat_integration_site</string> </key>
......
portal = context.getPortalObject() portal = context.getPortalObject()
select_dict= {'default_aggregate_uid': None}
portal.portal_catalog.searchAndActivate( portal.portal_catalog.searchAndActivate(
portal_type=('Slave Instance', 'Software Instance'), portal_type=('Slave Instance', 'Software Instance'),
validation_state='validated', validation_state='validated',
default_aggregate_uid=None,
select_dict=select_dict,
left_join_list=select_dict.keys(),
method_id='SoftwareInstance_tryToInvalidateIfDestroyed', method_id='SoftwareInstance_tryToInvalidateIfDestroyed',
activate_kw={'tag': tag}, activate_kw={'tag': tag},
**{"slapos_item.slap_state": "destroy_requested"} **{"slapos_item.slap_state": "destroy_requested"}
......
...@@ -5,6 +5,7 @@ portal.portal_catalog.searchAndActivate( ...@@ -5,6 +5,7 @@ portal.portal_catalog.searchAndActivate(
free_for_request=0, free_for_request=0,
parent_portal_type='Remote Node', parent_portal_type='Remote Node',
method_id='ComputePartition_propagateRemoteNode', method_id='ComputePartition_propagateRemoteNode',
method_kw={"activate_kw": {'tag': tag}},
activate_kw={'tag': tag} activate_kw={'tag': tag}
) )
......
portal = context.getPortalObject() portal = context.getPortalObject()
aggregate_value = portal.restrictedTraverse(aggregate)
return portal.portal_catalog.getResultValue( return portal.portal_catalog.getResultValue(
portal_type = 'Support Request', portal_type='Support Request',
title = title, title={'query': title, 'key': 'ExactMatch'},
simulation_state = ["validated", "submitted", "suspended"], simulation_state=["validated", "submitted", "suspended"],
default_aggregate_uid = aggregate_value.getUid(), causality__uid=context.getUid(),
) )
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>title, aggregate</string> </value> <value> <string>title</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
...@@ -4,8 +4,9 @@ alarm_tool = portal.portal_alarms ...@@ -4,8 +4,9 @@ alarm_tool = portal.portal_alarms
if alarm_tool.isSubscribed() and len(alarm_id_list): if alarm_tool.isSubscribed() and len(alarm_id_list):
# No alarm tool is not subscribed, respect this choice and do not activate any alarm # No alarm tool is not subscribed, respect this choice and do not activate any alarm
tag = "%s-%s" % (script.id, context.getRelativeUrl()) tag = None
if must_reindex_context: if must_reindex_context:
tag = "%s-%s" % (script.id, context.getRelativeUrl())
context.reindexObject(activate_kw={'tag': tag}) context.reindexObject(activate_kw={'tag': tag})
for alarm_id in alarm_id_list: for alarm_id in alarm_id_list:
...@@ -13,10 +14,28 @@ if alarm_tool.isSubscribed() and len(alarm_id_list): ...@@ -13,10 +14,28 @@ if alarm_tool.isSubscribed() and len(alarm_id_list):
if alarm.isEnabled(): if alarm.isEnabled():
# do nothing if the alarm is not enabled # do nothing if the alarm is not enabled
if alarm.isActive(): if tag is not None:
activate_kw = {}
activate_kw['activity'] = 'SQLQueue'
activate_kw['after_tag'] = tag
# Wait for the previous alarm run to be finished # Wait for the previous alarm run to be finished
context.activate(after_path=alarm.getPath()).Base_reindexAndSenseAlarm([alarm_id], must_reindex_context=False) context.activate(**activate_kw).Base_reindexAndSenseAlarm([alarm_id],
must_reindex_context=False)
elif alarm.isActive():
activate_kw = {}
activate_kw['priority'] = 3
activate_kw['after_path_and_method_id'] = (alarm.getPath(), 'getId')
# Wait for the previous alarm run to be finished
# call on alarm tool to gather and drop with sqldict
alarm_tool.activate(**activate_kw).Base_reindexAndSenseAlarm([alarm_id],
must_reindex_context=False)
else: else:
# Do not call directly call activeSense, because in case of concurrency,
# it will trigger the alarm multiple time in parallel
# Wait for the previous alarm run to be finished
# wait for the context to be reindexed before activating the alarm # wait for the context to be reindexed before activating the alarm
# ROMAIN: SQLQueue is used, because I'm not sure if SQLDict drop activities with different after_tag # ROMAIN: getId is used, because most alarm script ends with an getId activity
alarm.activate(queue='SQLQueue', after_tag=tag).activeSense() # priority=3, to be executed after all reindex, but also execute simulation _expand
alarm.activate(priority=3).activeSense()
# Prevent 2 nodes to call activateSense concurrently
alarm.serialize()
...@@ -13,14 +13,13 @@ elif slap_state == 'busy': ...@@ -13,14 +13,13 @@ elif slap_state == 'busy':
instance = portal.portal_catalog.getResultValue( instance = portal.portal_catalog.getResultValue(
portal_type="Software Instance", portal_type="Software Instance",
validation_state="validated",
aggregate__uid=context.getUid(), aggregate__uid=context.getUid(),
) )
if (instance is None) or (instance.getSlapState() not in ["start_requested", "stop_requested"]): if (instance is None):
# XXX Not very elegant # XXX Not very elegant
if (compute_node.getPortalType() == 'Remote Node') and (context.getId() == 'SHARED_REMOTE'): if (compute_node.getPortalType() == 'Remote Node') and (context.getId() == 'SHARED_REMOTE'):
return ['ANY_URL'] return ['ANY_URL']
return [] return ['INSTANCE NOT INDEXED YET']
else: else:
return [instance.getUrlString()] return [instance.getUrlString()]
......
from zExceptions import Unauthorized
if REQUEST is not None:
raise Unauthorized
portal = context.getPortalObject() portal = context.getPortalObject()
compute_partition = context compute_partition = context
...@@ -7,22 +11,88 @@ assert remote_node.getPortalType() == 'Remote Node' ...@@ -7,22 +11,88 @@ assert remote_node.getPortalType() == 'Remote Node'
remote_project = remote_node.getDestinationProjectValue(portal_type='Project') remote_project = remote_node.getDestinationProjectValue(portal_type='Project')
remote_person = remote_node.getDestinationSectionValue(portal_type='Person') remote_person = remote_node.getDestinationSectionValue(portal_type='Person')
if compute_partition.getId() == 'SHARED_REMOTE': if local_instance_list is None:
if compute_partition.getId() == 'SHARED_REMOTE':
# Hardcoded ID behaviour # Hardcoded ID behaviour
local_instance_list = portal.portal_catalog( local_instance_list = portal.portal_catalog(
portal_type='Slave Instance', portal_type='Slave Instance',
aggregate__uid=compute_partition.getUid() aggregate__uid=compute_partition.getUid(),
validation_state='validated'
) )
else: else:
local_instance_list = [portal.portal_catalog.getResultValue( local_instance_list = portal.portal_catalog(
portal_type='Software Instance', portal_type='Software Instance',
aggregate__uid=compute_partition.getUid() aggregate__uid=compute_partition.getUid(),
)] validation_state='validated'
)
else:
local_instance_list = [portal.restrictedTraverse(x) for x in local_instance_list]
for local_instance in local_instance_list: for local_instance in local_instance_list:
# XXX TODO this will increase the workflow history assert local_instance.getAggregate() == compute_partition.getRelativeUrl()
# If local instance destruction has been propagated, do nothing
if local_instance.getValidationState() != 'validated':
continue
# if local instance is destroyed, propagate blindly
if local_instance.getSlapState() == 'destroy_requested':
remote_person.requestSoftwareInstance(
project_reference=remote_project.getReference(),
software_release=local_instance.getUrlString(),
software_title='_remote_%s_%s' % (remote_node.getFollowUpReference(), local_instance.getReference()),
software_type=local_instance.getSourceReference(),
instance_xml=local_instance.getTextContent(),
sla_xml=None,
shared=(local_instance.getPortalType() == 'Slave Instance'),
state='destroyed'
)
local_instance.invalidate(comment='Remote destruction has been propagated')
# Try to no trigger the script again on this object
local_instance.reindexObject(activate_kw=activate_kw)
requested_instance_tree = context.REQUEST.get('request_instance_tree')
if requested_instance_tree is not None:
requested_instance_tree.reindexObject(activate_kw=activate_kw)
return
# do not increase the workflow history
# Use the 'cached' API instead # Use the 'cached' API instead
# manually search the instance and compare all parameters
remote_instance_tree = portal.portal_catalog.getResultValue(
portal_type='Instance Tree',
validation_state='validated',
destination_section__uid=remote_person.getUid(),
follow_up__uid=remote_project.getUid(),
title={'query': '_remote_%s_%s' % (local_instance.getFollowUpReference(),
local_instance.getReference()),
'key': 'ExactMatch'}
)
if remote_instance_tree is not None:
requested_software_instance = remote_instance_tree.getSuccessorValue(title=remote_instance_tree.getTitle())
if (remote_instance_tree is not None) and \
((local_instance.getUrlString() != remote_instance_tree.getUrlString()) or \
(local_instance.getSourceReference() != remote_instance_tree.getSourceReference())):
# Try to create an Upgrade Decision for the new release
# XXX Move this code to InstanceTree_createUpgradeDecision, and pass only string arguments to it
_, new_release_variation, new_type_variation = remote_instance_tree.asContext(
url_string=local_instance.getUrlString(),
source_reference=local_instance.getSourceReference()
).InstanceTree_getSoftwareProduct()
if new_release_variation is None:
return
else:
return remote_instance_tree.InstanceTree_createUpgradeDecision(
target_software_release=new_release_variation,
target_software_type=new_type_variation
)
if (remote_instance_tree is None) or \
(local_instance.getTextContent() != remote_instance_tree.getTextContent()) or \
(local_instance.getSlapState() != remote_instance_tree.getSlapState()):
remote_person.requestSoftwareInstance( remote_person.requestSoftwareInstance(
project_reference=remote_project.getReference(), project_reference=remote_project.getReference(),
software_release=local_instance.getUrlString(), software_release=local_instance.getUrlString(),
...@@ -34,5 +104,16 @@ for local_instance in local_instance_list: ...@@ -34,5 +104,16 @@ for local_instance in local_instance_list:
state={'start_requested': 'started', 'stop_requested': 'stopped'}[local_instance.getSlapState()] state={'start_requested': 'started', 'stop_requested': 'stopped'}[local_instance.getSlapState()]
) )
requested_software_instance = context.REQUEST.get('request_instance') requested_software_instance = context.REQUEST.get('request_instance')
requested_instance_tree = context.REQUEST.get('request_instance_tree')
# Try to no trigger the script again on this object
requested_instance_tree.reindexObject(activate_kw=activate_kw)
if requested_software_instance is not None: if requested_software_instance is not None:
local_instance.setConnectionXml(requested_software_instance.getConnectionXml()) requested_software_instance.reindexObject(activate_kw=activate_kw)
if (requested_software_instance is not None) and \
(requested_software_instance.getConnectionXml() != local_instance.getConnectionXml()):
# Try to no trigger the script again on this object
local_instance.edit(
connection_xml=requested_software_instance.getConnectionXml(),
activate_kw=activate_kw
)
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string></string> </value> <value> <string>local_instance_list=None, activate_kw=None, REQUEST=None</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>editable</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_reference</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_read_only_reference</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>editable</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_title</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_title</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_translated_validation_state_title</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_translated_workflow_state_title</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
"""Hook called when a compute_node object is closed.
We want to reset reference, which is the user login in ERP5Security.
One exception is when a person object is installed from business template.
"""
if context.getPortalType() != "Instance Node":
return
context.setUserId(None)
context.InstanceNode_init()
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="Workflow Script" module="erp5.portal_type"/> <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
...@@ -50,20 +50,42 @@ ...@@ -50,20 +50,42 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>state_change</string> </value> <value> <string></string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>_proxy_roles</string> </key>
<value> <string>script_Instance_invalidate</string> </value> <value>
<tuple>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value>
</item> </item>
<item> <item>
<key> <string>portal_type</string> </key> <key> <string>guard</string> </key>
<value> <string>Workflow Script</string> </value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>InstanceNode_afterClone</string> </value>
</item> </item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Guard" module="Products.DCWorkflow.Guard"/>
</pickle>
<pickle>
<dictionary>
<item> <item>
<key> <string>title</string> </key> <key> <string>roles</string> </key>
<value> <value>
<none/> <tuple>
<string>Owner</string>
</tuple>
</value> </value>
</item> </item>
</dictionary> </dictionary>
......
...@@ -26,7 +26,7 @@ if url_string: ...@@ -26,7 +26,7 @@ if url_string:
software_type = portal.portal_catalog.getResultValue( software_type = portal.portal_catalog.getResultValue(
parent_uid=software_product.getUid(), parent_uid=software_product.getUid(),
title=context.getSourceReference(), title={'query': context.getSourceReference(), 'key': 'ExactMatch'},
portal_type="Software Product Type Variation" portal_type="Software Product Type Variation"
) )
......
...@@ -112,20 +112,10 @@ if 'network_guid' in filter_kw: ...@@ -112,20 +112,10 @@ if 'network_guid' in filter_kw:
network_guid = filter_kw.pop('network_guid') network_guid = filter_kw.pop('network_guid')
query_kw["default_subordination_reference"] = SimpleQuery(default_subordination_reference=network_guid) query_kw["default_subordination_reference"] = SimpleQuery(default_subordination_reference=network_guid)
"""
if 'project_guid' in filter_kw: if 'project_guid' in filter_kw:
# This implementation isn't optimal, as we would prefere place a direct query rather them make an # This is kept for compatibility for instance trees containing such parameter
# direct query. # If the reference does not match the project_uid, it will never be allocated
project_reference = filter_kw.pop("project_guid") query_kw['parent__follow_up__reference'] = filter_kw.pop("project_guid")
if 'parent_reference' not in query_kw:
# Get Compute Node list from Tracking API
from DateTime import DateTime
project = context.portal_catalog.getResultValue(portal_type="Project", reference=project_reference)
if project is not None:
query_kw["parent_reference"] = SimpleQuery(parent_reference=project.Project_getComputeNodeReferenceList())
"""
if computer_network_query: if computer_network_query:
if query_kw.get("default_subordination_reference"): if query_kw.get("default_subordination_reference"):
......
"""Hook called when a compute_node object is closed.
We want to reset reference, which is the user login in ERP5Security.
One exception is when a person object is installed from business template.
"""
if context.getPortalType() != "Remote Node":
return
context.setUserId(None)
context.RemoteNode_init()
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="Workflow Script" module="erp5.portal_type"/> <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
...@@ -50,25 +50,43 @@ ...@@ -50,25 +50,43 @@
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>state_change</string> </value> <value> <string></string> </value>
</item> </item>
<item> <item>
<key> <string>description</string> </key> <key> <string>_proxy_roles</string> </key>
<value> <value>
<none/> <tuple>
<string>Manager</string>
<string>Owner</string>
</tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>guard</string> </key>
<value> <string>script_Person_requestSupportRequest</string> </value> <value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item> </item>
<item> <item>
<key> <string>portal_type</string> </key> <key> <string>id</string> </key>
<value> <string>Workflow Script</string> </value> <value> <string>RemoteNode_afterClone</string> </value>
</item> </item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Guard" module="Products.DCWorkflow.Guard"/>
</pickle>
<pickle>
<dictionary>
<item> <item>
<key> <string>title</string> </key> <key> <string>roles</string> </key>
<value> <string>Person_requestSupportRequest</string> </value> <value>
<tuple>
<string>Owner</string>
</tuple>
</value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -4,7 +4,7 @@ We want to reset reference, which is the user login in ERP5Security. ...@@ -4,7 +4,7 @@ We want to reset reference, which is the user login in ERP5Security.
One exception is when a person object is installed from business template. One exception is when a person object is installed from business template.
""" """
# Slave Instance don't have user id to be set. # Slave Instance don't have user id to be set.
if context.getPortalType() in ["Slave Instance", "Subscription Condition"]: if context.getPortalType() in ["Slave Instance"]:
return return
context.setUserId(None) context.setUserId(None)
......
...@@ -6,7 +6,17 @@ if context.getPortalType() not in ('Software Instance', 'Slave Instance'): ...@@ -6,7 +6,17 @@ if context.getPortalType() not in ('Software Instance', 'Slave Instance'):
raise TypeError('%s is not supported' % context.getPortalType()) raise TypeError('%s is not supported' % context.getPortalType())
software_instance = context software_instance = context
if software_instance.getValidationState() == 'validated' \ if (software_instance.getValidationState() == 'validated') \
and software_instance.getSlapState() == 'destroy_requested' \ and (software_instance.getSlapState() == 'destroy_requested'):
and software_instance.getAggregateValue(portal_type='Compute Partition') is None:
partition = software_instance.getAggregateValue(portal_type='Compute Partition')
if partition is None:
software_instance.invalidate(comment='Invalidated as unallocated and destroyed') software_instance.invalidate(comment='Invalidated as unallocated and destroyed')
elif (partition.getParentValue().getPortalType() == 'Compute Node') and \
(software_instance.getPortalType() == 'Slave Instance'):
# Invalidate ONLY IF the partition is inside a Compute Node, which does not report destruction
software_instance.invalidate(comment='Invalidated as Compute Node does not report destruction of Slave Instance')
# Software Instance allocated on a Compute Node is invalidated by SlapTool
instance = context instance = context
if instance.getSlapState() != 'destroy_requested': if instance.getSlapState() != 'destroy_requested':
return return
if instance.getValidationState() != 'invalidated':
# Node must confirm the destruction before unallocation
return
partition = instance.getAggregateValue(portal_type="Compute Partition") partition = instance.getAggregateValue(portal_type="Compute Partition")
portal = instance.getPortalObject() portal = instance.getPortalObject()
...@@ -13,7 +16,7 @@ if partition is not None: ...@@ -13,7 +16,7 @@ if partition is not None:
instance.unallocatePartition() instance.unallocatePartition()
instance_sql_list = portal.portal_catalog( instance_sql_list = portal.portal_catalog(
portal_type=["Software Instance", "Slave Instance"], portal_type=["Software Instance", "Slave Instance"],
default_aggregate_uid=partition.getUid(), aggregate__uid=partition.getUid(),
) )
count = len(instance_sql_list) count = len(instance_sql_list)
if count == 0: if count == 0:
......
...@@ -85,10 +85,6 @@ ...@@ -85,10 +85,6 @@
<key> <string>center</string> </key> <key> <string>center</string> </key>
<value> <value>
<list> <list>
<string>my_preferred_aggregated_sale_trade_condition</string>
<string>my_preferred_aggregated_subscription_sale_trade_condition</string>
<string>my_preferred_aggregated_consumption_sale_trade_condition</string>
<string>my_preferred_default_pre_payment_subscription_invoice_template</string>
<string>my_preferred_rest_api_token_server_url</string> <string>my_preferred_rest_api_token_server_url</string>
</list> </list>
</value> </value>
...@@ -103,12 +99,9 @@ ...@@ -103,12 +99,9 @@
<key> <string>left</string> </key> <key> <string>left</string> </key>
<value> <value>
<list> <list>
<string>my_preferred_default_pre_payment_template</string>
<string>my_preferred_instance_delivery_template</string>
<string>my_preferred_hateoas_url</string> <string>my_preferred_hateoas_url</string>
<string>my_preferred_slapos_web_site_url</string> <string>my_preferred_slapos_web_site_url</string>
<string>my_preferred_shacache_website_expected_state</string> <string>my_preferred_shacache_website_expected_state</string>
<string>my_preferred_cloud_contract_enabled</string>
<string>my_preferred_wechat_integration_site</string> <string>my_preferred_wechat_integration_site</string>
<string>my_preferred_wechat_payment_service_reference</string> <string>my_preferred_wechat_payment_service_reference</string>
<string>my_preferred_payzen_integration_site</string> <string>my_preferred_payzen_integration_site</string>
...@@ -121,10 +114,7 @@ ...@@ -121,10 +114,7 @@
<value> <value>
<list> <list>
<string>my_preferred_regularisation_request_resource</string> <string>my_preferred_regularisation_request_resource</string>
<string>my_preferred_regularisation_request_template</string>
<string>my_preferred_regularisation_request_use_list</string> <string>my_preferred_regularisation_request_use_list</string>
<string>my_preferred_support_request_template</string>
<string>my_preferred_web_message_template</string>
<string>my_preferred_support_request_creation_limit</string> <string>my_preferred_support_request_creation_limit</string>
</list> </list>
</value> </value>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_preferred_aggregated_consumption_sale_trade_condition</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_string_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Preferred Aggregated Consumption Sale Trade Condition</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_preferred_aggregated_sale_trade_condition</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_string_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Preferred Aggregated Sale Trade Condition</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_preferred_aggregated_subscription_sale_trade_condition</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_string_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Preferred Aggregated Subscription Sale Trade Condition</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="CheckBoxField" module="Products.Formulator.StandardFields"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>my_preferred_cloud_contract_enabled</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
<item>
<key> <string>required_not_found</string> </key>
<value> <string>This field is mandatory.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>alternate_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>enabled</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>extra</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>hidden</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>required</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Cloud Contract Enabled</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_preferred_default_pre_payment_subscription_invoice_template</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_string_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Preferred Default Pre Payment Sale Invoice Template</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_preferred_default_pre_payment_template</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_string_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Preferred Default Pre Payment Template</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_preferred_instance_delivery_template</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_string_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Preferred Instance Delivery Template</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_preferred_regularisation_request_template</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_string_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Preferred Regularisation Request Template</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_preferred_support_request_template</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_string_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Preferred Support Request Template</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_preferred_web_message_template</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_string_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Preferred Web Message Template</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -37,8 +37,7 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin): ...@@ -37,8 +37,7 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
preference.edit( preference.edit(
preferred_credential_alarm_automatic_call=0, preferred_credential_alarm_automatic_call=0,
preferred_credential_recovery_automatic_approval=0, preferred_credential_recovery_automatic_approval=0,
preferred_credential_request_automatic_approval=1, preferred_credential_request_automatic_approval=1
preferred_cloud_contract_enabled=True
) )
""" """
...@@ -70,8 +69,8 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin): ...@@ -70,8 +69,8 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
) )
if admin_user_login is None: if admin_user_login is None:
admin_user = self.portal.person_module.template_member.\ admin_user = self.portal.person_module\
Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Person")
admin_user.newContent( admin_user.newContent(
portal_type="ERP5 Login", portal_type="ERP5 Login",
...@@ -102,7 +101,8 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin): ...@@ -102,7 +101,8 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
if [q for q in candidate[1] if email in q] and body in candidate[2]: if [q for q in candidate[1] if email in q] and body in candidate[2]:
return candidate[2] return candidate[2]
credential_request_form = self.web_site.hateoas.connection.join_form() self.portal.portal_skins.changeSkin('RJS')
credential_request_form = self.web_site.slapos_master_panel.hateoas.connection.join_form()
expected_message = 'You will receive a confirmation email to activate your account.' expected_message = 'You will receive a confirmation email to activate your account.'
self.assertTrue(expected_message in credential_request_form, self.assertTrue(expected_message in credential_request_form,
...@@ -110,7 +110,7 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin): ...@@ -110,7 +110,7 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
email = '%s@example.com' % reference email = '%s@example.com' % reference
redirect_url = self.web_site.hateoas.connection.WebSection_newCredentialRequest( redirect_url = self.web_site.slapos_master_panel.hateoas.connection.WebSection_newCredentialRequest(
reference=reference, reference=reference,
default_email_text=email, default_email_text=email,
first_name="Joe", first_name="Joe",
...@@ -140,7 +140,8 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin): ...@@ -140,7 +140,8 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
join_key = to_click_url.split('=')[-1] join_key = to_click_url.split('=')[-1]
self.assertNotEqual(join_key, None) self.assertNotEqual(join_key, None)
web_site.hateoas.connection.ERP5Site_activeLogin(key=join_key) self.portal.portal_skins.changeSkin('RJS')
web_site.slapos_master_panel.hateoas.connection.ERP5Site_activeLogin(key=join_key)
self.assertEqual(self.portal.REQUEST.RESPONSE.getStatus(), 303) self.assertEqual(self.portal.REQUEST.RESPONSE.getStatus(), 303)
self.assertIn(self.web_site.getId() + "/%23%21login%3Fp.page%3Dslapos%7B%26n.me%7D", self.assertIn(self.web_site.getId() + "/%23%21login%3Fp.page%3Dslapos%7B%26n.me%7D",
...@@ -199,23 +200,6 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin): ...@@ -199,23 +200,6 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
server.edit(capacity_scope='open') server.edit(capacity_scope='open')
self.tic() self.tic()
@changeSkin('RJS')
def setServerOpenSubscription(self, server):
server.edit(
allocation_scope='open/subscription')
self.assertEqual('open/subscription', server.getAllocationScope())
self.assertEqual('close', server.getCapacityScope())
server.edit(capacity_scope='open')
self.tic()
@changeSkin('RJS')
def setServerOpenPersonal(self, server):
server.edit(
allocation_scope='open/personal', subject_list=[])
self.assertEqual('open/personal', server.getAllocationScope())
self.assertEqual('open', server.getCapacityScope())
self.tic()
def formatComputeNode(self, compute_node, partition_count=10): def formatComputeNode(self, compute_node, partition_count=10):
compute_node_dict = dict( compute_node_dict = dict(
software_root='/opt', software_root='/opt',
...@@ -552,6 +536,27 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin): ...@@ -552,6 +536,27 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
self.assertEqual(0, len(instance_tree_list)) self.assertEqual(0, len(instance_tree_list))
def checkRemoteInstanceUnallocation(self, person_user_id,
person_reference, instance_title,
software_release, software_type, server,
project_reference):
self.login(person_user_id)
self.personRequestInstanceNotReady(
software_release=software_release,
software_type=software_type,
partition_reference=instance_title,
state='<marshal><string>destroyed</string></marshal>',
project_reference=project_reference
)
# let's find instances of user and check connection strings
instance_tree_list = [q.getObject() for q in
self._getCurrentInstanceTreeList()
if q.getTitle() == instance_title]
self.assertEqual(0, len(instance_tree_list))
def checkInstanceUnallocation(self, person_user_id, def checkInstanceUnallocation(self, person_user_id,
person_reference, instance_title, person_reference, instance_title,
software_release, software_type, server, project_reference): software_release, software_type, server, project_reference):
...@@ -637,122 +642,6 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin): ...@@ -637,122 +642,6 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
partition.contentValues(portal_type='Internet Protocol Address')], partition.contentValues(portal_type='Internet Protocol Address')],
connection_dict.values()) connection_dict.values())
def assertInstanceTreeSimulationCoverage(self, subscription):
self.login()
# this is document level assertion, as simulation and its specific delivery
# is covered by unit tests
packing_list_line_list = subscription.getAggregateRelatedValueList(
portal_type='Sale Packing List Line')
self.assertEqual(len(packing_list_line_list), 1)
for packing_list_line in packing_list_line_list:
packing_list = packing_list_line.getParentValue()
self.assertEqual('Sale Packing List',
packing_list.getPortalType())
self.assertEqual('delivered',
packing_list.getSimulationState())
causality_state = packing_list.getCausalityState()
self.assertEqual('solved', causality_state)
def assertAggregatedSalePackingList(self, delivery):
self.assertEqual('delivered', delivery.getSimulationState())
self.assertEqual('solved', delivery.getCausalityState())
invoice_list= delivery.getCausalityRelatedValueList(
portal_type='Sale Invoice Transaction')
self.assertEqual(1, len(invoice_list))
invoice = invoice_list[0].getObject()
causality_list = invoice.getCausalityValueList()
self.assertSameSet([delivery], causality_list)
self.assertEqual('stopped', invoice.getSimulationState())
self.assertEqual('solved', invoice.getCausalityState())
payment_list = invoice.getCausalityRelatedValueList(
portal_type='Payment Transaction')
self.assertEqual(0, len(payment_list))
def assertPersonDocumentCoverage(self, person):
self.login()
subscription_list = self.portal.portal_catalog(
portal_type='Instance Tree',
default_destination_section_uid=person.getUid())
for subscription in subscription_list:
self.assertInstanceTreeSimulationCoverage(
subscription.getObject())
aggregated_delivery_list = self.portal.portal_catalog(
portal_type='Sale Packing List',
default_destination_section_uid=person.getUid(),
specialise_uid=[self.portal.restrictedTraverse(self.portal\
.portal_preferences.getPreferredAggregatedSaleTradeCondition()\
).getUid()
] + [
i.uid for i in self.portal.ERP5Site_searchRelatedInheritedSpecialiseList(
specialise_uid=self.portal.restrictedTraverse(self.portal
.portal_preferences.getPreferredAggregatedSaleTradeCondition()
).getUid())
]
)
if len(subscription_list) == 0:
self.assertEqual(0, len(aggregated_delivery_list))
return
self.assertNotEqual(0, len(aggregated_delivery_list))
for aggregated_delivery in aggregated_delivery_list:
self.assertAggregatedSalePackingList(aggregated_delivery.getObject())
def assertOpenSaleOrderCoverage(self, person_reference):
self.login()
person = self.portal.portal_catalog.getResultValue(
portal_type='ERP5 Login',
reference=person_reference).getParentValue()
instance_tree_list = self.portal.portal_catalog(
portal_type='Instance Tree',
default_destination_section_uid=person.getUid()
)
open_sale_order_list = self.portal.portal_catalog(
portal_type='Open Sale Order',
default_destination_uid=person.getUid(),
)
if len(instance_tree_list) == 0:
self.assertEqual(0, len(open_sale_order_list))
return
self.assertEqual(len(instance_tree_list), len(open_sale_order_list))
archived_open_sale_order_list = [q for q in open_sale_order_list
if q.getValidationState() == 'archived']
self.assertEqual(len(instance_tree_list), len(archived_open_sale_order_list))
line_list = []
for open_sale_order in archived_open_sale_order_list:
archived_line_list = open_sale_order.contentValues(
portal_type='Open Sale Order Line')
self.assertEqual(1, len(archived_line_list))
line_list.extend(archived_line_list)
self.assertEqual(len(instance_tree_list), len(line_list))
self.assertSameSet(
[q.getRelativeUrl() for q in instance_tree_list],
[q.getAggregate(portal_type="Instance Tree") for q in line_list]
)
# Every line must have 2 aggregate categories:
# one Instance Tree and one Hosting Subscription
for line in line_list:
self.assertEqual(2, len(line.getAggregateList()))
self.assertEqual(1, len(line.getAggregateList(portal_type="Hosting Subscription")))
validated_open_sale_order_list = [q for q in open_sale_order_list
if q.getValidationState() == 'validated']
# if no line, all open orders are kept archived
self.assertEqual(len(validated_open_sale_order_list), 0)
def findMessage(self, email, body): def findMessage(self, email, body):
for candidate in reversed(self.portal.MailHost.getMessageList()): for candidate in reversed(self.portal.MailHost.getMessageList()):
if [q for q in candidate[1] if email in q] and body in candidate[2]: if [q for q in candidate[1] if email in q] and body in candidate[2]:
...@@ -772,55 +661,6 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin): ...@@ -772,55 +661,6 @@ class DefaultScenarioMixin(TestSlapOSSecurityMixin):
else: else:
self.assertEqual(None, to_click_message) self.assertEqual(None, to_click_message)
@changeSkin('RJS')
def usePaymentManually(self, web_site, user_id, is_email_expected=True, subscription_request=None):
person = self.portal.portal_catalog.getResultValue(
portal_type="Person",
user_id=user_id)
self.assertNotEqual(person, None)
self.assertInvoiceNotification(person, is_email_expected)
invoice_list = person.Entity_getOutstandingAmountList()
self.login()
if subscription_request is not None:
expected_causality = subscription_request.getRelativeUrl()
filtered_invoice_list = []
for invoice in invoice_list:
spl = invoice.getCausalityValue()
if spl is not None and spl.getCausality() == expected_causality:
filtered_invoice_list.append(invoice)
self.assertEqual(len(filtered_invoice_list), 1)
invoice_list = filtered_invoice_list
else:
self.assertEqual(len(invoice_list), 1)
self.login(user_id)
document_id = invoice_list[0].getId()
web_site.accounting_module[document_id].\
SaleInvoiceTransaction_redirectToManualSlapOSPayment()
self.tic()
def assertSubscriptionStopped(self, person):
self.login()
subscription_list = self.portal.portal_catalog(
portal_type='Instance Tree',
default_destination_section_uid=person.getUid())
self.assertEqual(len(subscription_list), 1)
for subscription in subscription_list:
self.assertEqual(subscription.getSlapState(), "stop_requested")
def assertSubscriptionDestroyed(self, person):
self.login()
subscription_list = self.portal.portal_catalog(
portal_type='Instance Tree',
default_destination_section_uid=person.getUid())
self.assertEqual(len(subscription_list), 1)
for subscription in subscription_list:
self.assertEqual(subscription.getSlapState(), "destroy_requested")
def requestInstance(self, person_user_id, instance_title, def requestInstance(self, person_user_id, instance_title,
software_release, software_type, project_reference): software_release, software_type, project_reference):
......
...@@ -137,12 +137,6 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -137,12 +137,6 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
self.portal.portal_activities.unsubscribe() self.portal.portal_activities.unsubscribe()
self.new_id = self.generateNewId() self.new_id = self.generateNewId()
instance_template = self.portal.software_instance_module.template_software_instance
if len(instance_template.objectValues()):
instance_template.manage_delObjects(
ids=[i.getId() for i in instance_template.objectValues()])
def beforeDumpExpectedConfiguration(self): def beforeDumpExpectedConfiguration(self):
"""Overwrite this function on project context to tweak production focus tests""" """Overwrite this function on project context to tweak production focus tests"""
pass pass
...@@ -176,6 +170,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -176,6 +170,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
def addProject(self, organisation=None, currency=None, person=None, is_accountable=False): def addProject(self, organisation=None, currency=None, person=None, is_accountable=False):
assert organisation is None assert organisation is None
if person is None: if person is None:
assert not is_accountable
project = self.portal.project_module.newContent( project = self.portal.project_module.newContent(
portal_type='Project', portal_type='Project',
title='project-%s' % self.generateNewId() title='project-%s' % self.generateNewId()
...@@ -226,8 +221,8 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -226,8 +221,8 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
if new_id is None: if new_id is None:
new_id = self.generateNewId() new_id = self.generateNewId()
# Clone person document # Clone person document
person_user = self.portal.person_module.template_member.\ person_user = self.portal.person_module\
Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Person")
person_user.edit( person_user.edit(
title="live_test_%s" % new_id, title="live_test_%s" % new_id,
reference="live_test_%s" % new_id, reference="live_test_%s" % new_id,
...@@ -278,7 +273,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -278,7 +273,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
person_user.requestSoftwareInstance(**request_kw) person_user.requestSoftwareInstance(**request_kw)
return person_user.REQUEST.get('request_instance_tree') return person_user.REQUEST.get('request_instance_tree')
def _makeTree(self, project, requested_template_id='template_software_instance'): def _makeTree(self, project):
new_id = self.generateNewId() new_id = self.generateNewId()
self.request_kw = dict( self.request_kw = dict(
...@@ -296,9 +291,9 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -296,9 +291,9 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
self.commit() self.commit()
# prepare part of tree # prepare part of tree
self.instance_tree = self.portal.instance_tree_module\ self.instance_tree = self.portal.instance_tree_module\
.template_instance_tree.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Instance Tree")
self.software_instance = self.portal.software_instance_module\ self.software_instance = self.portal.software_instance_module\
[requested_template_id].Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Software Instance")
self.instance_tree.edit( self.instance_tree.edit(
title=self.request_kw['software_title'], title=self.request_kw['software_title'],
...@@ -316,7 +311,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -316,7 +311,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
self.portal.portal_workflow._jumpToStateFor(self.instance_tree, 'start_requested') self.portal.portal_workflow._jumpToStateFor(self.instance_tree, 'start_requested')
self.requested_software_instance = self.portal.software_instance_module\ self.requested_software_instance = self.portal.software_instance_module\
.template_software_instance.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Software Instance")
self.software_instance.edit( self.software_instance.edit(
title=self.request_kw['software_title'], title=self.request_kw['software_title'],
reference="TESTSI-%s" % new_id, reference="TESTSI-%s" % new_id,
...@@ -326,7 +321,9 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -326,7 +321,9 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
sla_xml=self.request_kw['sla_xml'], sla_xml=self.request_kw['sla_xml'],
specialise=self.instance_tree.getRelativeUrl(), specialise=self.instance_tree.getRelativeUrl(),
successor=self.requested_software_instance.getRelativeUrl(), successor=self.requested_software_instance.getRelativeUrl(),
follow_up_value=project follow_up_value=project,
ssl_key='foo',
ssl_certificate='bar'
) )
self.portal.portal_workflow._jumpToStateFor(self.software_instance, 'start_requested') self.portal.portal_workflow._jumpToStateFor(self.software_instance, 'start_requested')
self.software_instance.validate() self.software_instance.validate()
...@@ -340,28 +337,37 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -340,28 +337,37 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
text_content=self.request_kw['instance_xml'], text_content=self.request_kw['instance_xml'],
sla_xml=self.request_kw['sla_xml'], sla_xml=self.request_kw['sla_xml'],
specialise=self.instance_tree.getRelativeUrl(), specialise=self.instance_tree.getRelativeUrl(),
follow_up_value=project follow_up_value=project,
ssl_key='foo',
ssl_certificate='bar'
) )
self.portal.portal_workflow._jumpToStateFor(self.requested_software_instance, 'start_requested') self.portal.portal_workflow._jumpToStateFor(self.requested_software_instance, 'start_requested')
self.requested_software_instance.validate() self.requested_software_instance.validate()
self.tic() self.tic()
def _makeSlaveTree(self, project, requested_template_id='template_slave_instance'): def addComputeNodeAndPartition(self, project=None,
return self._makeTree(project, requested_template_id=requested_template_id) portal_type='Compute Node'):
def addComputeNodeAndPartition(self, project=None):
# XXX replace _makeComputeNode # XXX replace _makeComputeNode
if project is None: if project is None:
project = self.addProject() project = self.addProject()
self.tic() self.tic()
edit_kw = {}
if portal_type == 'Remote Node':
# Be nice, and create remote user/project
remote_project = self.addProject()
remote_user = self.makePerson(remote_project)
edit_kw['destination_project_value'] = remote_project
edit_kw['destination_section_value'] = remote_user
reference = 'TESTCOMP-%s' % self.generateNewId() reference = 'TESTCOMP-%s' % self.generateNewId()
compute_node = self.portal.compute_node_module.newContent( compute_node = self.portal.compute_node_module.newContent(
portal_type="Compute Node", portal_type=portal_type,
#allocation_scope=allocation_scope, #allocation_scope=allocation_scope,
reference=reference, reference=reference,
title=reference, title=reference,
follow_up_value=project follow_up_value=project,
**edit_kw
) )
# The edit above will update capacity scope due the interaction workflow # The edit above will update capacity scope due the interaction workflow
# The line above force capacity scope to be open, keeping the previous # The line above force capacity scope to be open, keeping the previous
...@@ -381,8 +387,8 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -381,8 +387,8 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
return compute_node, partition return compute_node, partition
def _makeComputeNode(self, project, allocation_scope='open'): def _makeComputeNode(self, project, allocation_scope='open'):
self.compute_node = self.portal.compute_node_module.template_compute_node\ self.compute_node = self.portal.compute_node_module\
.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Compute Node")
reference = 'TESTCOMP-%s' % self.generateNewId() reference = 'TESTCOMP-%s' % self.generateNewId()
self.compute_node.edit( self.compute_node.edit(
allocation_scope=allocation_scope, allocation_scope=allocation_scope,
...@@ -430,7 +436,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -430,7 +436,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
p.validate() p.validate()
self.start_requested_software_installation = self.portal.software_installation_module\ self.start_requested_software_installation = self.portal.software_installation_module\
.template_software_installation.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Software Installation")
self.start_requested_software_installation.edit( self.start_requested_software_installation.edit(
url_string=self.generateNewSoftwareReleaseUrl(), url_string=self.generateNewSoftwareReleaseUrl(),
aggregate=self.compute_node.getRelativeUrl(), aggregate=self.compute_node.getRelativeUrl(),
...@@ -442,7 +448,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -442,7 +448,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
self.start_requested_software_installation.requestStart() self.start_requested_software_installation.requestStart()
self.destroy_requested_software_installation = self.portal.software_installation_module\ self.destroy_requested_software_installation = self.portal.software_installation_module\
.template_software_installation.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Software Installation")
self.destroy_requested_software_installation.edit( self.destroy_requested_software_installation.edit(
url_string=self.generateNewSoftwareReleaseUrl(), url_string=self.generateNewSoftwareReleaseUrl(),
aggregate=self.compute_node.getRelativeUrl(), aggregate=self.compute_node.getRelativeUrl(),
...@@ -455,7 +461,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -455,7 +461,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
self.destroy_requested_software_installation.requestDestroy() self.destroy_requested_software_installation.requestDestroy()
self.destroyed_software_installation = self.portal.software_installation_module\ self.destroyed_software_installation = self.portal.software_installation_module\
.template_software_installation.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Software Installation")
self.destroyed_software_installation.edit( self.destroyed_software_installation.edit(
url_string=self.generateNewSoftwareReleaseUrl(), url_string=self.generateNewSoftwareReleaseUrl(),
aggregate=self.compute_node.getRelativeUrl(), aggregate=self.compute_node.getRelativeUrl(),
...@@ -474,7 +480,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -474,7 +480,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
# prepare some trees # prepare some trees
instance_tree = self.portal.instance_tree_module\ instance_tree = self.portal.instance_tree_module\
.template_instance_tree.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Instance Tree")
instance_tree.validate() instance_tree.validate()
instance_tree.edit( instance_tree.edit(
title=self.generateNewSoftwareTitle(), title=self.generateNewSoftwareTitle(),
...@@ -502,7 +508,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -502,7 +508,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
if with_slave: if with_slave:
instance_tree = self.portal.instance_tree_module\ instance_tree = self.portal.instance_tree_module\
.template_instance_tree.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Instance Tree")
instance_tree.validate() instance_tree.validate()
instance_tree.edit( instance_tree.edit(
title=self.generateNewSoftwareTitle(), title=self.generateNewSoftwareTitle(),
...@@ -528,7 +534,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -528,7 +534,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
self.start_requested_slave_instance.edit(aggregate=self.compute_node.partition1.getRelativeUrl()) self.start_requested_slave_instance.edit(aggregate=self.compute_node.partition1.getRelativeUrl())
instance_tree = self.portal.instance_tree_module\ instance_tree = self.portal.instance_tree_module\
.template_instance_tree.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Instance Tree")
instance_tree.validate() instance_tree.validate()
instance_tree.edit( instance_tree.edit(
title=self.generateNewSoftwareTitle(), title=self.generateNewSoftwareTitle(),
...@@ -557,7 +563,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -557,7 +563,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
) )
instance_tree = self.portal.instance_tree_module\ instance_tree = self.portal.instance_tree_module\
.template_instance_tree.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Instance Tree")
instance_tree.validate() instance_tree.validate()
instance_tree.edit( instance_tree.edit(
title=self.generateNewSoftwareTitle(), title=self.generateNewSoftwareTitle(),
...@@ -589,7 +595,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -589,7 +595,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
) )
instance_tree = self.portal.instance_tree_module\ instance_tree = self.portal.instance_tree_module\
.template_instance_tree.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Instance Tree")
instance_tree.validate() instance_tree.validate()
instance_tree.edit( instance_tree.edit(
title=self.generateNewSoftwareTitle(), title=self.generateNewSoftwareTitle(),
...@@ -619,7 +625,8 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -619,7 +625,8 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
aggregate=self.compute_node.partition4.getRelativeUrl() aggregate=self.compute_node.partition4.getRelativeUrl()
) )
self.destroyed_software_instance.requestDestroy(**kw) self.destroyed_software_instance.requestDestroy(**kw)
self.destroyed_software_instance.invalidate() # Do not invalidate, as it will unlink the partition
#self.destroyed_software_instance.invalidate()
self.tic() self.tic()
if with_slave: if with_slave:
...@@ -668,7 +675,9 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -668,7 +675,9 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
is_accountable=False, base_price=None, has_organisation=False): is_accountable=False, base_price=None, has_organisation=False):
if allocation_state not in ('impossible', 'possible', 'allocated'): if allocation_state not in ('impossible', 'possible', 'allocated'):
raise ValueError('Not supported allocation_state: %s' % allocation_state) raise ValueError('Not supported allocation_state: %s' % allocation_state)
project = self.addProject(is_accountable=is_accountable) project = self.addProject(
#is_accountable=is_accountable
)
person = self.makePerson(project) person = self.makePerson(project)
if has_organisation: if has_organisation:
organisation = self.portal.organisation_module.newContent( organisation = self.portal.organisation_module.newContent(
...@@ -681,11 +690,37 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -681,11 +690,37 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
release_variation = software_product.contentValues(portal_type='Software Product Release Variation')[0] release_variation = software_product.contentValues(portal_type='Software Product Release Variation')[0]
type_variation = software_product.contentValues(portal_type='Software Product Type Variation')[0] type_variation = software_product.contentValues(portal_type='Software Product Type Variation')[0]
if is_accountable and (base_price is not None): if is_accountable:
currency = self.portal.currency_module.newContent(
portal_type="Currency",
title="test %s" % self.generateNewId()
)
currency.validate()
seller_organisation = self.portal.organisation_module.newContent(
portal_type="Organisation",
title="seller-%s" % self.generateNewId()
)
seller_bank_account = seller_organisation.newContent(
portal_type="Bank Account",
title="test_bank_account_%s" % self.generateNewId(),
price_currency_value=currency
)
seller_bank_account.validate()
seller_organisation.validate()
sale_trade_condition = self.portal.sale_trade_condition_module.newContent(
portal_type="Sale Trade Condition",
trade_condition_type="instance_tree",
source_section_value=seller_organisation,
source_project_value=project,
price_currency_value=currency,
specialise="business_process_module/slapos_ultimate_business_process"
)
sale_trade_condition.validate()
if (base_price is not None):
sale_supply = self.portal.sale_supply_module.newContent( sale_supply = self.portal.sale_supply_module.newContent(
portal_type="Sale Supply", portal_type="Sale Supply",
destination_project_value=project, destination_project_value=project,
price_currency=project.Project_getAccountingCurrency() price_currency_value=currency
) )
sale_supply.newContent( sale_supply.newContent(
portal_type="Sale Supply Line", portal_type="Sale Supply Line",
...@@ -932,7 +967,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin): ...@@ -932,7 +967,7 @@ class SlapOSTestCaseMixin(testSlapOSMixin):
destination_project_value=destination_project_value, destination_project_value=destination_project_value,
payment_mode=payment_mode, payment_mode=payment_mode,
ledger="automated", ledger="automated",
specialise="sale_trade_condition_module/slapos_aggregated_trade_condition_v3", #specialise="sale_trade_condition_module/XXX",
created_by_builder=1 # to prevent init script to create lines created_by_builder=1 # to prevent init script to create lines
) )
self.portal.portal_workflow._jumpToStateFor(invoice, 'stopped') self.portal.portal_workflow._jumpToStateFor(invoice, 'stopped')
......
...@@ -494,8 +494,8 @@ class TestSlapOSCloudSlapOSComputeNodeMixin_getCacheComputeNodeInformation( ...@@ -494,8 +494,8 @@ class TestSlapOSCloudSlapOSComputeNodeMixin_getCacheComputeNodeInformation(
self.project = self.addProject() self.project = self.addProject()
# Prepare compute_node # Prepare compute_node
self.compute_node = self.portal.compute_node_module.template_compute_node\ self.compute_node = self.portal.compute_node_module\
.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Compute Node")
self.compute_node.edit( self.compute_node.edit(
title="Compute Node %s" % self.new_id, title="Compute Node %s" % self.new_id,
reference="TESTCOMP-%s" % self.new_id, reference="TESTCOMP-%s" % self.new_id,
......
...@@ -227,6 +227,8 @@ class TestSlapOSFreeComputePartitionAlarm(SlapOSTestCaseMixin): ...@@ -227,6 +227,8 @@ class TestSlapOSFreeComputePartitionAlarm(SlapOSTestCaseMixin):
partition.markBusy() partition.markBusy()
self.portal.portal_workflow._jumpToStateFor(software_instance, self.portal.portal_workflow._jumpToStateFor(software_instance,
'destroy_requested') 'destroy_requested')
self.portal.portal_workflow._jumpToStateFor(software_instance,
'invalidated')
self.tic() self.tic()
software_instance.SoftwareInstance_tryToUnallocatePartition() software_instance.SoftwareInstance_tryToUnallocatePartition()
...@@ -242,6 +244,8 @@ class TestSlapOSFreeComputePartitionAlarm(SlapOSTestCaseMixin): ...@@ -242,6 +244,8 @@ class TestSlapOSFreeComputePartitionAlarm(SlapOSTestCaseMixin):
partition.markBusy() partition.markBusy()
self.portal.portal_workflow._jumpToStateFor(software_instance, self.portal.portal_workflow._jumpToStateFor(software_instance,
'destroy_requested') 'destroy_requested')
self.portal.portal_workflow._jumpToStateFor(software_instance,
'invalidated')
self.tic() self.tic()
software_instance.SoftwareInstance_tryToUnallocatePartition() software_instance.SoftwareInstance_tryToUnallocatePartition()
...@@ -257,6 +261,8 @@ class TestSlapOSFreeComputePartitionAlarm(SlapOSTestCaseMixin): ...@@ -257,6 +261,8 @@ class TestSlapOSFreeComputePartitionAlarm(SlapOSTestCaseMixin):
partition.markBusy() partition.markBusy()
self.portal.portal_workflow._jumpToStateFor(software_instance, self.portal.portal_workflow._jumpToStateFor(software_instance,
'destroy_requested') 'destroy_requested')
self.portal.portal_workflow._jumpToStateFor(software_instance,
'invalidated')
self.tic() self.tic()
partition.activate(tag="allocate_%s" % partition.getRelativeUrl()\ partition.activate(tag="allocate_%s" % partition.getRelativeUrl()\
...@@ -288,6 +294,8 @@ class TestSlapOSFreeComputePartitionAlarm(SlapOSTestCaseMixin): ...@@ -288,6 +294,8 @@ class TestSlapOSFreeComputePartitionAlarm(SlapOSTestCaseMixin):
'busy') 'busy')
self.portal.portal_workflow._jumpToStateFor(software_instance, self.portal.portal_workflow._jumpToStateFor(software_instance,
'destroy_requested') 'destroy_requested')
self.portal.portal_workflow._jumpToStateFor(software_instance,
'invalidated')
self.tic() self.tic()
software_instance.SoftwareInstance_tryToUnallocatePartition() software_instance.SoftwareInstance_tryToUnallocatePartition()
...@@ -316,6 +324,21 @@ class TestSlapOSFreeComputePartitionAlarm(SlapOSTestCaseMixin): ...@@ -316,6 +324,21 @@ class TestSlapOSFreeComputePartitionAlarm(SlapOSTestCaseMixin):
self.assertEqual(partition.getRelativeUrl(), software_instance.getAggregate()) self.assertEqual(partition.getRelativeUrl(), software_instance.getAggregate())
self.assertEqual('busy', partition.getSlapState()) self.assertEqual('busy', partition.getSlapState())
def test_SoftwareInstance_tryToUnallocatePartition_script_notInvalidated(self):
instance_tree = self.addInstanceTree()
software_instance = instance_tree.getSuccessorValue()
_, partition = self.addComputeNodeAndPartition(project=instance_tree.getFollowUpValue())
software_instance.setAggregateValue(partition)
partition.markBusy()
self.portal.portal_workflow._jumpToStateFor(software_instance,
'destroy_requested')
self.tic()
software_instance.SoftwareInstance_tryToUnallocatePartition()
self.assertEqual(partition.getRelativeUrl(), software_instance.getAggregate())
self.assertEqual('busy', partition.getSlapState())
class TestSlapOSGarbageCollectDestroyedRootTreeAlarm(SlapOSTestCaseMixin): class TestSlapOSGarbageCollectDestroyedRootTreeAlarm(SlapOSTestCaseMixin):
################################################################# #################################################################
...@@ -919,6 +942,8 @@ class TestSlapOSInvalidateDestroyedInstance(SlapOSTestCaseMixin): ...@@ -919,6 +942,8 @@ class TestSlapOSInvalidateDestroyedInstance(SlapOSTestCaseMixin):
) )
def test_tryToInvalidateIfDestroyed_alarm_softwareInstanceAllocated(self): def test_tryToInvalidateIfDestroyed_alarm_softwareInstanceAllocated(self):
# This use case is not needed by the alarm
# But it keeps alarm search way simpler
instance_tree = self.addInstanceTree() instance_tree = self.addInstanceTree()
software_instance = instance_tree.getSuccessorValue() software_instance = instance_tree.getSuccessorValue()
...@@ -930,7 +955,25 @@ class TestSlapOSInvalidateDestroyedInstance(SlapOSTestCaseMixin): ...@@ -930,7 +955,25 @@ class TestSlapOSInvalidateDestroyedInstance(SlapOSTestCaseMixin):
self.portal.portal_workflow._jumpToStateFor(software_instance, 'destroy_requested') self.portal.portal_workflow._jumpToStateFor(software_instance, 'destroy_requested')
self.tic() self.tic()
self._test_alarm_not_visited( self._test_alarm(
self.portal.portal_alarms.slapos_cloud_invalidate_destroyed_instance,
software_instance,
'SoftwareInstance_tryToInvalidateIfDestroyed'
)
def test_tryToInvalidateIfDestroyed_alarm_slaveInstanceAllocated(self):
instance_tree = self.addInstanceTree(shared=True)
software_instance = instance_tree.getSuccessorValue()
_, partition = self.addComputeNodeAndPartition(project=instance_tree.getFollowUpValue())
software_instance.setAggregateValue(partition)
partition.markBusy()
self.portal.portal_workflow._jumpToStateFor(software_instance, 'validated')
self.portal.portal_workflow._jumpToStateFor(software_instance, 'destroy_requested')
self.tic()
self._test_alarm(
self.portal.portal_alarms.slapos_cloud_invalidate_destroyed_instance, self.portal.portal_alarms.slapos_cloud_invalidate_destroyed_instance,
software_instance, software_instance,
'SoftwareInstance_tryToInvalidateIfDestroyed' 'SoftwareInstance_tryToInvalidateIfDestroyed'
...@@ -994,3 +1037,523 @@ class TestSlapOSInvalidateDestroyedInstance(SlapOSTestCaseMixin): ...@@ -994,3 +1037,523 @@ class TestSlapOSInvalidateDestroyedInstance(SlapOSTestCaseMixin):
self.assertEqual(software_instance.getValidationState(), "validated") self.assertEqual(software_instance.getValidationState(), "validated")
self.assertEqual(software_instance.getSlapState(), "destroy_requested") self.assertEqual(software_instance.getSlapState(), "destroy_requested")
def test_tryToInvalidateIfDestroyed_script_allocatedSlaveInstance(self):
instance_tree = self.addInstanceTree(shared=True)
software_instance = instance_tree.getSuccessorValue()
_, partition = self.addComputeNodeAndPartition(project=instance_tree.getFollowUpValue())
software_instance.setAggregateValue(partition)
partition.markBusy()
self.portal.portal_workflow._jumpToStateFor(software_instance, 'validated')
self.portal.portal_workflow._jumpToStateFor(software_instance, 'destroy_requested')
software_instance.SoftwareInstance_tryToInvalidateIfDestroyed()
self.assertEqual(software_instance.getValidationState(), "invalidated")
self.assertEqual(software_instance.getSlapState(), "destroy_requested")
def test_tryToInvalidateIfDestroyed_script_allocatedInstanceOnRemoteNode(self):
instance_tree = self.addInstanceTree()
software_instance = instance_tree.getSuccessorValue()
_, partition = self.addComputeNodeAndPartition(
project=instance_tree.getFollowUpValue(),
portal_type="Remote Node"
)
software_instance.setAggregateValue(partition)
partition.markBusy()
self.portal.portal_workflow._jumpToStateFor(software_instance, 'validated')
self.portal.portal_workflow._jumpToStateFor(software_instance, 'destroy_requested')
software_instance.SoftwareInstance_tryToInvalidateIfDestroyed()
self.assertEqual(software_instance.getValidationState(), "validated")
self.assertEqual(software_instance.getSlapState(), "destroy_requested")
def test_tryToInvalidateIfDestroyed_script_allocatedSlaveInstanceOnRemoteNode(self):
instance_tree = self.addInstanceTree(shared=True)
software_instance = instance_tree.getSuccessorValue()
_, partition = self.addComputeNodeAndPartition(
project=instance_tree.getFollowUpValue(),
portal_type="Remote Node"
)
software_instance.setAggregateValue(partition)
partition.markBusy()
self.portal.portal_workflow._jumpToStateFor(software_instance, 'validated')
self.portal.portal_workflow._jumpToStateFor(software_instance, 'destroy_requested')
software_instance.SoftwareInstance_tryToInvalidateIfDestroyed()
self.assertEqual(software_instance.getValidationState(), "validated")
self.assertEqual(software_instance.getSlapState(), "destroy_requested")
class TestSlapOSPropagateRemoteNodeInstance(SlapOSTestCaseMixin):
#################################################################
# slapos_cloud_propagate_remote_node_instance
#################################################################
def test_propagateRemoteNode_alarm_busyPartitionInRemoteNode(self):
instance_tree = self.addInstanceTree()
software_instance = instance_tree.getSuccessorValue()
_, partition = self.addComputeNodeAndPartition(
project=instance_tree.getFollowUpValue(),
portal_type='Remote Node'
)
software_instance.setAggregateValue(partition)
partition.markBusy()
with TemporaryAlarmScript(self.portal, 'ComputePartition_propagateRemoteNode', ""):
self.tic()
self._test_alarm(
self.portal.portal_alarms.slapos_cloud_propagate_remote_node_instance,
partition,
'ComputePartition_propagateRemoteNode'
)
def test_propagateRemoteNode_alarm_busyPartitionInComputeNode(self):
instance_tree = self.addInstanceTree()
software_instance = instance_tree.getSuccessorValue()
_, partition = self.addComputeNodeAndPartition(
project=instance_tree.getFollowUpValue()
)
software_instance.setAggregateValue(partition)
partition.markBusy()
with TemporaryAlarmScript(self.portal, 'ComputePartition_propagateRemoteNode', ""):
self.tic()
self._test_alarm_not_visited(
self.portal.portal_alarms.slapos_cloud_propagate_remote_node_instance,
partition,
'ComputePartition_propagateRemoteNode'
)
def test_propagateRemoteNode_alarm_freePartitionInRemoteNode(self):
instance_tree = self.addInstanceTree()
_, partition = self.addComputeNodeAndPartition(
project=instance_tree.getFollowUpValue(),
portal_type='Remote Node'
)
with TemporaryAlarmScript(self.portal, 'ComputePartition_propagateRemoteNode', ""):
self.tic()
self._test_alarm_not_visited(
self.portal.portal_alarms.slapos_cloud_propagate_remote_node_instance,
partition,
'ComputePartition_propagateRemoteNode'
)
#################################################################
# ComputePartition_propagateRemoteNode
#################################################################
def test_propagateRemoteNode_REQUEST_disallowed(self):
instance_tree = self.addInstanceTree()
_, partition = self.addComputeNodeAndPartition(
project=instance_tree.getFollowUpValue(),
portal_type='Remote Node'
)
self.assertRaises(
Unauthorized,
partition.ComputePartition_propagateRemoteNode,
REQUEST={})
def test_propagateRemoteNode_script_unexpectedContext(self):
instance_tree = self.addInstanceTree()
_, partition = self.addComputeNodeAndPartition(
project=instance_tree.getFollowUpValue()
)
self.assertRaises(
AssertionError,
partition.ComputePartition_propagateRemoteNode,
)
def test_propagateRemoteNode_script_createRemoteInstanceTree(self):
instance_tree = self.addInstanceTree()
software_instance = instance_tree.getSuccessorValue()
remote_node, partition = self.addComputeNodeAndPartition(
project=instance_tree.getFollowUpValue(),
portal_type='Remote Node'
)
software_instance.setAggregateValue(partition)
partition.markBusy()
with TemporaryAlarmScript(self.portal, 'ComputePartition_propagateRemoteNode', ""):
self.tic()
partition.ComputePartition_propagateRemoteNode()
self.tic()
remote_user = remote_node.getDestinationSectionValue()
remote_project = remote_node.getDestinationProjectValue()
remote_instance_tree = self.portal.portal_catalog.getResultValue(
portal_type='Instance Tree',
destination_section__uid=remote_user.getUid(),
follow_up__uid=remote_project.getUid(),
title='_remote_%s_%s' % (software_instance.getFollowUpReference(),
software_instance.getReference())
)
self.assertEqual(remote_instance_tree.getValidationState(), "validated")
self.assertEqual(remote_instance_tree.getSlapState(), "start_requested")
self.assertEqual(remote_instance_tree.getUrlString(),
software_instance.getUrlString())
self.assertEqual(remote_instance_tree.getSourceReference(),
software_instance.getSourceReference())
self.assertEqual(remote_instance_tree.getTextContent(),
software_instance.getTextContent())
self.assertEqual(remote_instance_tree.getSlaXml(), None)
self.assertEqual(remote_instance_tree.isRootSlave(False),
software_instance.getPortalType() == 'Slave Instance')
self.assertEqual(software_instance.getConnectionXml(), None)
def test_propagateRemoteNode_script_doNotRequestIfNotNeeded(self):
instance_tree = self.addInstanceTree()
software_instance = instance_tree.getSuccessorValue()
remote_node, partition = self.addComputeNodeAndPartition(
project=instance_tree.getFollowUpValue(),
portal_type='Remote Node'
)
software_instance.setAggregateValue(partition)
partition.markBusy()
with TemporaryAlarmScript(self.portal, 'ComputePartition_propagateRemoteNode', ""):
self.tic()
partition.ComputePartition_propagateRemoteNode()
self.tic()
remote_user = remote_node.getDestinationSectionValue()
remote_project = remote_node.getDestinationProjectValue()
remote_instance_tree = self.portal.portal_catalog.getResultValue(
portal_type='Instance Tree',
destination_section__uid=remote_user.getUid(),
follow_up__uid=remote_project.getUid(),
title='_remote_%s_%s' % (software_instance.getFollowUpReference(),
software_instance.getReference())
)
remote_modification_date = remote_instance_tree.getModificationDate()
partition.ComputePartition_propagateRemoteNode()
self.assertEqual(remote_instance_tree.getModificationDate(),
remote_modification_date)
def test_propagateRemoteNode_script_propageParameterChangesToRemoteInstanceTree(self):
instance_tree = self.addInstanceTree()
software_instance = instance_tree.getSuccessorValue()
remote_node, partition = self.addComputeNodeAndPartition(
project=instance_tree.getFollowUpValue(),
portal_type='Remote Node'
)
software_instance.setAggregateValue(partition)
partition.markBusy()
with TemporaryAlarmScript(self.portal, 'ComputePartition_propagateRemoteNode', ""):
self.tic()
partition.ComputePartition_propagateRemoteNode()
self.tic()
remote_user = remote_node.getDestinationSectionValue()
remote_project = remote_node.getDestinationProjectValue()
remote_instance_tree = self.portal.portal_catalog.getResultValue(
portal_type='Instance Tree',
destination_section__uid=remote_user.getUid(),
follow_up__uid=remote_project.getUid(),
title='_remote_%s_%s' % (software_instance.getFollowUpReference(),
software_instance.getReference())
)
remote_modification_date = remote_instance_tree.getModificationDate()
self.portal.portal_workflow._jumpToStateFor(software_instance, 'stop_requested')
software_instance.edit(
#url_string=self.generateNewSoftwareReleaseUrl(),
#source_reference=self.generateNewSoftwareType(),
text_content=self.generateSafeXml(),
sla_xml=self.generateSafeXml()
)
partition.ComputePartition_propagateRemoteNode()
self.assertNotEqual(remote_instance_tree.getModificationDate(),
remote_modification_date)
self.assertEqual(remote_instance_tree.getValidationState(), "validated")
self.assertEqual(remote_instance_tree.getSlapState(), "stop_requested")
self.assertEqual(remote_instance_tree.getUrlString(),
software_instance.getUrlString())
self.assertEqual(remote_instance_tree.getSourceReference(),
software_instance.getSourceReference())
self.assertEqual(remote_instance_tree.getTextContent(),
software_instance.getTextContent())
self.assertEqual(remote_instance_tree.getSlaXml(), None)
self.assertEqual(remote_instance_tree.isRootSlave(False),
software_instance.getPortalType() == 'Slave Instance')
self.assertEqual(software_instance.getConnectionXml(), None)
def test_propagateRemoteNode_script_propageReleaseChangesToUpgradeDecision(self):
instance_tree = self.addInstanceTree()
software_instance = instance_tree.getSuccessorValue()
remote_node, partition = self.addComputeNodeAndPartition(
project=instance_tree.getFollowUpValue(),
portal_type='Remote Node'
)
software_instance.setAggregateValue(partition)
partition.markBusy()
with TemporaryAlarmScript(self.portal, 'ComputePartition_propagateRemoteNode', ""):
self.tic()
with TemporaryAlarmScript(self.portal, 'Item_getSubscriptionStatus', "'subscribed'"):
partition.ComputePartition_propagateRemoteNode()
self.tic()
remote_user = remote_node.getDestinationSectionValue()
remote_project = remote_node.getDestinationProjectValue()
remote_instance_tree = self.portal.portal_catalog.getResultValue(
portal_type='Instance Tree',
destination_section__uid=remote_user.getUid(),
follow_up__uid=remote_project.getUid(),
title='_remote_%s_%s' % (software_instance.getFollowUpReference(),
software_instance.getReference())
)
remote_software_instance = remote_instance_tree.getSuccessorValue()
# Create allocated partition to allow Upgrade Decision
remote_compute_node, remote_partition = self.addComputeNodeAndPartition(
project=remote_instance_tree.getFollowUpValue(),
)
remote_software_instance.setAggregateValue(remote_partition)
remote_partition.markBusy()
# Create remote Software Product, to allow generating the Upgrade Decision
new_id = self.generateNewId()
software_product = self.portal.software_product_module.newContent(
reference='TESTSOFTPROD-%s' % new_id,
title='Test software product %s' % new_id,
follow_up_value=remote_project
)
old_release_variation = software_product.newContent(
portal_type='Software Product Release Variation',
url_string=remote_instance_tree.getUrlString()
)
type_variation = software_product.newContent(
portal_type='Software Product Type Variation',
reference=remote_instance_tree.getSourceReference()
)
software_product.publish()
new_release_variation = self._makeSoftwareRelease(software_product)
self.addAllocationSupply("old release compute node", remote_compute_node, software_product,
old_release_variation, type_variation, disable_alarm=True)
self.addAllocationSupply("new release compute node", remote_compute_node, software_product,
new_release_variation, type_variation, disable_alarm=True)
self.tic()
self.portal.portal_workflow._jumpToStateFor(software_instance, 'stop_requested')
old_release_url = software_instance.getUrlString()
old_text_content = software_instance.getTextContent()
software_instance.edit(
url_string=new_release_variation.getUrlString(),
text_content=self.generateSafeXml()
)
with TemporaryAlarmScript(self.portal, 'Item_getSubscriptionStatus', "'subscribed'"):
partition.ComputePartition_propagateRemoteNode()
# Instance tree is not modified
self.assertEqual(remote_instance_tree.getValidationState(), "validated")
self.assertEqual(remote_instance_tree.getSlapState(), "start_requested")
self.assertEqual(remote_instance_tree.getUrlString(),
old_release_url)
self.assertEqual(remote_instance_tree.getSourceReference(),
software_instance.getSourceReference())
self.assertEqual(remote_instance_tree.getTextContent(),
old_text_content)
self.assertEqual(remote_instance_tree.getSlaXml(), None)
self.assertEqual(remote_instance_tree.isRootSlave(False),
software_instance.getPortalType() == 'Slave Instance')
self.assertEqual(software_instance.getConnectionXml(), None)
self.tic()
# An upgrade decision is proposed
upgrade_decision = self.portal.portal_catalog.getResultValue(
portal_type='Upgrade Decision',
destination_section__uid=remote_user.getUid(),
destination_project__uid=remote_project.getUid(),
aggregate__uid=remote_instance_tree.getUid(),
resource__uid=software_product.getUid(),
software_release__uid=new_release_variation.getUid(),
software_type__uid=type_variation.getUid(),
simulation_state='confirmed'
)
self.assertNotEqual(upgrade_decision, None)
def test_propagateRemoteNode_script_doNotPropageConnectionXmlIfNotChanged(self):
instance_tree = self.addInstanceTree()
software_instance = instance_tree.getSuccessorValue()
_, partition = self.addComputeNodeAndPartition(
project=instance_tree.getFollowUpValue(),
portal_type='Remote Node'
)
software_instance.setAggregateValue(partition)
partition.markBusy()
with TemporaryAlarmScript(self.portal, 'ComputePartition_propagateRemoteNode', ""):
self.tic()
with TemporaryAlarmScript(self.portal, 'Item_getSubscriptionStatus', "'subscribed'"):
partition.ComputePartition_propagateRemoteNode()
self.tic()
modification_date = software_instance.getModificationDate()
with TemporaryAlarmScript(self.portal, 'Item_getSubscriptionStatus', "'subscribed'"):
partition.ComputePartition_propagateRemoteNode()
self.assertEqual(software_instance.getModificationDate(), modification_date)
def test_propagateRemoteNode_script_propageConnectionXmlFromRemoteInstanceTree(self):
instance_tree = self.addInstanceTree()
software_instance = instance_tree.getSuccessorValue()
remote_node, partition = self.addComputeNodeAndPartition(
project=instance_tree.getFollowUpValue(),
portal_type='Remote Node'
)
software_instance.setAggregateValue(partition)
partition.markBusy()
with TemporaryAlarmScript(self.portal, 'ComputePartition_propagateRemoteNode', ""):
self.tic()
with TemporaryAlarmScript(self.portal, 'Item_getSubscriptionStatus', "'subscribed'"):
partition.ComputePartition_propagateRemoteNode()
self.tic()
remote_user = remote_node.getDestinationSectionValue()
remote_project = remote_node.getDestinationProjectValue()
remote_instance_tree = self.portal.portal_catalog.getResultValue(
portal_type='Instance Tree',
destination_section__uid=remote_user.getUid(),
follow_up__uid=remote_project.getUid(),
title='_remote_%s_%s' % (software_instance.getFollowUpReference(),
software_instance.getReference())
)
modification_date = software_instance.getModificationDate()
remote_instance = remote_instance_tree.getSuccessorValue()
remote_instance.edit(
connection_xml=self.generateSafeXml()
)
with TemporaryAlarmScript(self.portal, 'Item_getSubscriptionStatus', "'subscribed'"):
partition.ComputePartition_propagateRemoteNode()
self.assertNotEqual(software_instance.getModificationDate(), modification_date)
self.assertEqual(remote_instance_tree.getValidationState(), "validated")
self.assertEqual(remote_instance_tree.getSlapState(), "start_requested")
self.assertEqual(remote_instance_tree.getUrlString(),
software_instance.getUrlString())
self.assertEqual(remote_instance_tree.getSourceReference(),
software_instance.getSourceReference())
self.assertEqual(remote_instance_tree.getTextContent(),
software_instance.getTextContent())
self.assertEqual(remote_instance_tree.getSlaXml(), None)
self.assertEqual(remote_instance_tree.isRootSlave(False),
software_instance.getPortalType() == 'Slave Instance')
self.assertEqual(software_instance.getConnectionXml(),
remote_instance.getConnectionXml())
def test_propagateRemoteNode_script_propagateDestructionIfValidated(self):
instance_tree = self.addInstanceTree()
software_instance = instance_tree.getSuccessorValue()
remote_node, partition = self.addComputeNodeAndPartition(
project=instance_tree.getFollowUpValue(),
portal_type='Remote Node'
)
software_instance.setAggregateValue(partition)
partition.markBusy()
with TemporaryAlarmScript(self.portal, 'ComputePartition_propagateRemoteNode', ""):
self.tic()
partition.ComputePartition_propagateRemoteNode()
self.tic()
remote_user = remote_node.getDestinationSectionValue()
remote_project = remote_node.getDestinationProjectValue()
remote_instance_tree = self.portal.portal_catalog.getResultValue(
portal_type='Instance Tree',
destination_section__uid=remote_user.getUid(),
follow_up__uid=remote_project.getUid(),
title='_remote_%s_%s' % (software_instance.getFollowUpReference(),
software_instance.getReference())
)
remote_modification_date = remote_instance_tree.getModificationDate()
self.portal.portal_workflow._jumpToStateFor(software_instance, 'destroy_requested')
self.tic()
self.assertEqual(software_instance.getValidationState(), 'validated')
partition.ComputePartition_propagateRemoteNode()
self.assertNotEqual(remote_instance_tree.getModificationDate(),
remote_modification_date)
self.assertEqual(remote_instance_tree.getValidationState(), "archived")
self.assertEqual(remote_instance_tree.getSlapState(), "destroy_requested")
self.assertEqual(remote_instance_tree.getUrlString(),
software_instance.getUrlString())
self.assertEqual(remote_instance_tree.getSourceReference(),
software_instance.getSourceReference())
self.assertEqual(remote_instance_tree.getTextContent(),
software_instance.getTextContent())
self.assertEqual(remote_instance_tree.getSlaXml(), None)
self.assertEqual(remote_instance_tree.isRootSlave(False),
software_instance.getPortalType() == 'Slave Instance')
self.assertEqual(software_instance.getConnectionXml(), None)
self.assertEqual(software_instance.getValidationState(), 'invalidated')
def test_propagateRemoteNode_script_doNotPropagateDestructionIfInvalidated(self):
instance_tree = self.addInstanceTree()
software_instance = instance_tree.getSuccessorValue()
remote_node, partition = self.addComputeNodeAndPartition(
project=instance_tree.getFollowUpValue(),
portal_type='Remote Node'
)
software_instance.setAggregateValue(partition)
partition.markBusy()
with TemporaryAlarmScript(self.portal, 'ComputePartition_propagateRemoteNode', ""):
self.tic()
partition.ComputePartition_propagateRemoteNode()
self.tic()
remote_user = remote_node.getDestinationSectionValue()
remote_project = remote_node.getDestinationProjectValue()
remote_instance_tree = self.portal.portal_catalog.getResultValue(
portal_type='Instance Tree',
destination_section__uid=remote_user.getUid(),
follow_up__uid=remote_project.getUid(),
title='_remote_%s_%s' % (software_instance.getFollowUpReference(),
software_instance.getReference())
)
remote_modification_date = remote_instance_tree.getModificationDate()
self.portal.portal_workflow._jumpToStateFor(software_instance, 'destroy_requested')
self.portal.portal_workflow._jumpToStateFor(software_instance, 'invalidated')
self.tic()
partition.ComputePartition_propagateRemoteNode()
self.assertEqual(remote_instance_tree.getModificationDate(),
remote_modification_date)
...@@ -53,7 +53,7 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin): ...@@ -53,7 +53,7 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin):
def _installSoftware(self, compute_node, url): def _installSoftware(self, compute_node, url):
software_installation = self.portal.software_installation_module\ software_installation = self.portal.software_installation_module\
.template_software_installation.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Software Installation")
software_installation.edit(url_string=url, software_installation.edit(url_string=url,
reference='TESTSOFTINST-%s' % self.generateNewId(), reference='TESTSOFTINST-%s' % self.generateNewId(),
aggregate=compute_node.getRelativeUrl()) aggregate=compute_node.getRelativeUrl())
...@@ -63,10 +63,6 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin): ...@@ -63,10 +63,6 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin):
compute_node.reindexObject() compute_node.reindexObject()
self.tic() self.tic()
def _makeSlaveTreeXXX(self, project, requested_template_id='template_slave_instance'):
SlapOSTestCaseMixin._makeTree(self, project,
requested_template_id=requested_template_id)
def test_person_allocation_checked(self): def test_person_allocation_checked(self):
software_instance, _, _ = self.makeAllocableSoftwareInstance() software_instance, _, _ = self.makeAllocableSoftwareInstance()
with TemporaryAlarmScript(self.portal, 'Person_isAllowedToAllocate', with TemporaryAlarmScript(self.portal, 'Person_isAllowedToAllocate',
...@@ -389,7 +385,7 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin): ...@@ -389,7 +385,7 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin):
portal_type='Compute Partition')) portal_type='Compute Partition'))
software_instance2 = self.portal.software_instance_module\ software_instance2 = self.portal.software_instance_module\
.template_software_instance.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Software Instance")
software_instance2.edit( software_instance2.edit(
title=self.generateNewSoftwareTitle(), title=self.generateNewSoftwareTitle(),
reference="TESTSI-%s" % self.generateNewId(), reference="TESTSI-%s" % self.generateNewId(),
...@@ -398,7 +394,9 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin): ...@@ -398,7 +394,9 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin):
text_content=self.generateSafeXml(), text_content=self.generateSafeXml(),
sla_xml=sla_xml, sla_xml=sla_xml,
specialise_value=instance_tree, specialise_value=instance_tree,
follow_up_value=project follow_up_value=project,
ssl_key='foo',
ssl_certificate='bar'
) )
self.portal.portal_workflow._jumpToStateFor(software_instance2, 'start_requested') self.portal.portal_workflow._jumpToStateFor(software_instance2, 'start_requested')
self.portal.portal_workflow._jumpToStateFor(software_instance2, 'validated') self.portal.portal_workflow._jumpToStateFor(software_instance2, 'validated')
...@@ -482,7 +480,7 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin): ...@@ -482,7 +480,7 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin):
) )
software_instance2 = self.portal.software_instance_module\ software_instance2 = self.portal.software_instance_module\
.template_software_instance.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Software Instance")
software_instance2.edit( software_instance2.edit(
title=self.generateNewSoftwareTitle(), title=self.generateNewSoftwareTitle(),
reference="TESTSI-%s" % self.generateNewId(), reference="TESTSI-%s" % self.generateNewId(),
...@@ -491,7 +489,9 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin): ...@@ -491,7 +489,9 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin):
text_content=self.generateSafeXml(), text_content=self.generateSafeXml(),
sla_xml=sla_xml, sla_xml=sla_xml,
specialise=instance_tree.getRelativeUrl(), specialise=instance_tree.getRelativeUrl(),
follow_up_value=project follow_up_value=project,
ssl_key='foo',
ssl_certificate='bar'
) )
self.portal.portal_workflow._jumpToStateFor(software_instance2, 'start_requested') self.portal.portal_workflow._jumpToStateFor(software_instance2, 'start_requested')
software_instance2.validate() software_instance2.validate()
...@@ -503,7 +503,7 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin): ...@@ -503,7 +503,7 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin):
) )
software_instance3 = self.portal.software_instance_module\ software_instance3 = self.portal.software_instance_module\
.template_software_instance.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Software Instance")
software_instance3.edit( software_instance3.edit(
title=self.generateNewSoftwareTitle(), title=self.generateNewSoftwareTitle(),
reference="TESTSI-%s" % self.generateNewId(), reference="TESTSI-%s" % self.generateNewId(),
...@@ -512,7 +512,9 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin): ...@@ -512,7 +512,9 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin):
text_content=self.generateSafeXml(), text_content=self.generateSafeXml(),
sla_xml=sla_xml, sla_xml=sla_xml,
specialise=instance_tree.getRelativeUrl(), specialise=instance_tree.getRelativeUrl(),
follow_up_value=project follow_up_value=project,
ssl_key='foo',
ssl_certificate='bar'
) )
self.portal.portal_workflow._jumpToStateFor(software_instance3, 'start_requested') self.portal.portal_workflow._jumpToStateFor(software_instance3, 'start_requested')
software_instance3.validate() software_instance3.validate()
...@@ -609,7 +611,7 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin): ...@@ -609,7 +611,7 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin):
portal_type='Compute Partition')) portal_type='Compute Partition'))
software_instance2 = self.portal.software_instance_module\ software_instance2 = self.portal.software_instance_module\
.template_software_instance.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Software Instance")
software_instance2.edit( software_instance2.edit(
title=self.generateNewSoftwareTitle(), title=self.generateNewSoftwareTitle(),
reference="TESTSI-%s" % self.generateNewId(), reference="TESTSI-%s" % self.generateNewId(),
...@@ -618,7 +620,9 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin): ...@@ -618,7 +620,9 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin):
text_content=self.generateSafeXml(), text_content=self.generateSafeXml(),
sla_xml=sla_xml, sla_xml=sla_xml,
specialise_value=instance_tree, specialise_value=instance_tree,
follow_up_value=project follow_up_value=project,
ssl_key='foo',
ssl_certificate='bar'
) )
self.portal.portal_workflow._jumpToStateFor(software_instance2, 'start_requested') self.portal.portal_workflow._jumpToStateFor(software_instance2, 'start_requested')
self.portal.portal_workflow._jumpToStateFor(software_instance2, 'validated') self.portal.portal_workflow._jumpToStateFor(software_instance2, 'validated')
...@@ -763,38 +767,39 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin): ...@@ -763,38 +767,39 @@ class TestSlapOSAllocation(SlapOSTestCaseMixin):
def check_allocation_capability(self, capability, bad_capability_list, def check_allocation_capability(self, capability, bad_capability_list,
good_capability=None): good_capability=None):
good_capability = good_capability or capability good_capability = good_capability or capability
self._makeTree()
self._makeComputeNode() software_instance, compute_node, partition = self.makeAllocableSoftwareInstance()
self.partition.edit(subject=capability)
self._installSoftware(self.compute_node, partition.edit(subject=capability)
self.software_instance.getUrlString()) self.assertEqual(compute_node.getAllocationScope(), "open")
self.assertEqual(compute_node.getCapacityScope(), "open")
self.assertEqual(None, self.tic()
self.software_instance.getAggregate(portal_type='Compute Partition'))
self.assertEqual(None, software_instance.getAggregateValue(
portal_type='Compute Partition'))
for bad_capability in bad_capability_list: for bad_capability in bad_capability_list:
self.software_instance.setSlaXml("""<?xml version='1.0' encoding='utf-8'?> software_instance.setSlaXml("""<?xml version='1.0' encoding='utf-8'?>
<instance> <instance>
<parameter id='capability'>%s</parameter> <parameter id='capability'>%s</parameter>
</instance>""" % bad_capability) </instance>""" % bad_capability)
self.software_instance.SoftwareInstance_tryToAllocatePartition() software_instance.SoftwareInstance_tryToAllocatePartition()
try: try:
partition = self.software_instance.getAggregate( allocated_partition = software_instance.getAggregate(
portal_type='Compute Partition') portal_type='Compute Partition')
self.assertEqual(None, partition) self.assertEqual(None, allocated_partition)
except AssertionError: except AssertionError:
raise AssertionError("Allocated %s on %s with capability %s" % ( raise AssertionError("Allocated %s on %s with capability %s" % (
bad_capability, partition, capability)) bad_capability, allocated_partition, capability))
self.software_instance.setSlaXml("""<?xml version='1.0' encoding='utf-8'?> software_instance.setSlaXml("""<?xml version='1.0' encoding='utf-8'?>
<instance> <instance>
<parameter id='capability'>%s</parameter> <parameter id='capability'>%s</parameter>
</instance>""" % good_capability) </instance>""" % good_capability)
self.software_instance.SoftwareInstance_tryToAllocatePartition() software_instance.SoftwareInstance_tryToAllocatePartition()
self.assertEqual(self.partition.getRelativeUrl(), self.assertEqual(partition.getRelativeUrl(),
self.software_instance.getAggregate(portal_type='Compute Partition')) software_instance.getAggregate(portal_type='Compute Partition'))
@simulate('Person_isAllowedToAllocate', '*args, **kwargs', 'return True') @simulate('Person_isAllowedToAllocate', '*args, **kwargs', 'return True')
def test_allocation_capability(self): def test_allocation_capability(self):
......
...@@ -29,8 +29,8 @@ class TestSlapOSCoreComputeNodeSlapInterfaceWorkflow(SlapOSTestCaseMixin): ...@@ -29,8 +29,8 @@ class TestSlapOSCoreComputeNodeSlapInterfaceWorkflow(SlapOSTestCaseMixin):
SlapOSTestCaseMixin.afterSetUp(self) SlapOSTestCaseMixin.afterSetUp(self)
self.project = self.addProject() self.project = self.addProject()
# Clone compute_node document # Clone compute_node document
self.compute_node = self.portal.compute_node_module.template_compute_node\ self.compute_node = self.portal.compute_node_module\
.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Compute Node")
new_id = self.generateNewId() new_id = self.generateNewId()
self.compute_node.edit( self.compute_node.edit(
title="compute node %s" % (new_id, ), title="compute node %s" % (new_id, ),
...@@ -491,8 +491,8 @@ class TestSlapOSCoreComputeNodeSlapInterfaceWorkflowSupply(SlapOSTestCaseMixin): ...@@ -491,8 +491,8 @@ class TestSlapOSCoreComputeNodeSlapInterfaceWorkflowSupply(SlapOSTestCaseMixin):
self.project = self.addProject() self.project = self.addProject()
# Clone compute_node document # Clone compute_node document
compute_node = portal.compute_node_module.template_compute_node\ compute_node = portal.compute_node_module\
.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Compute Node")
# Clone person document # Clone person document
person_user = self.makePerson(self.project, new_id=self.new_id, index=0) person_user = self.makePerson(self.project, new_id=self.new_id, index=0)
self.addProjectProductionManagerAssignment(person_user, self.project) self.addProjectProductionManagerAssignment(person_user, self.project)
......
...@@ -26,8 +26,8 @@ class TestSlapOSCoreComputePartitionSlapInterfaceWorkflow(SlapOSTestCaseMixin): ...@@ -26,8 +26,8 @@ class TestSlapOSCoreComputePartitionSlapInterfaceWorkflow(SlapOSTestCaseMixin):
self.login() self.login()
SlapOSTestCaseMixin.afterSetUp(self) SlapOSTestCaseMixin.afterSetUp(self)
# Clone compute_node document # Clone compute_node document
self.compute_node = self.portal.compute_node_module.template_compute_node\ self.compute_node = self.portal.compute_node_module\
.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Compute Node")
self.compute_node.edit( self.compute_node.edit(
title="compute node %s" % (self.new_id, ), title="compute node %s" % (self.new_id, ),
reference="TESTCOMP-%s" % (self.new_id, ), reference="TESTCOMP-%s" % (self.new_id, ),
......
...@@ -45,12 +45,12 @@ class TestSlapOSConstraintMixin(SlapOSTestCaseMixin): ...@@ -45,12 +45,12 @@ class TestSlapOSConstraintMixin(SlapOSTestCaseMixin):
class TestSlapOSComputePartitionConstraint(TestSlapOSConstraintMixin): class TestSlapOSComputePartitionConstraint(TestSlapOSConstraintMixin):
def test_non_busy_partition_has_no_related_instance(self): def test_non_busy_partition_has_no_related_instance(self):
compute_node = self.portal.compute_node_module.template_compute_node\ compute_node = self.portal.compute_node_module\
.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Compute Node")
partition = compute_node.newContent(portal_type='Compute Partition') partition = compute_node.newContent(portal_type='Compute Partition')
self.portal.portal_workflow._jumpToStateFor(partition, 'free') self.portal.portal_workflow._jumpToStateFor(partition, 'free')
software_instance = self.portal.software_instance_module\ software_instance = self.portal.software_instance_module\
.template_software_instance.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Software Instance")
slave_instance = self.portal.software_instance_module.newContent( slave_instance = self.portal.software_instance_module.newContent(
portal_type='Slave Instance') portal_type='Slave Instance')
...@@ -84,15 +84,15 @@ class TestSlapOSComputePartitionConstraint(TestSlapOSConstraintMixin): ...@@ -84,15 +84,15 @@ class TestSlapOSComputePartitionConstraint(TestSlapOSConstraintMixin):
self.portal.portal_workflow._jumpToStateFor(partition, 'free') self.portal.portal_workflow._jumpToStateFor(partition, 'free')
def test_busy_partition_has_one_related_instance(self): def test_busy_partition_has_one_related_instance(self):
compute_node = self.portal.compute_node_module.template_compute_node\ compute_node = self.portal.compute_node_module\
.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Compute Node")
partition = compute_node.newContent(portal_type='Compute Partition') partition = compute_node.newContent(portal_type='Compute Partition')
self.portal.portal_workflow._jumpToStateFor(partition, 'busy') self.portal.portal_workflow._jumpToStateFor(partition, 'busy')
software_instance = self.portal.software_instance_module\ software_instance = self.portal.software_instance_module\
.template_software_instance.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Software Instance")
software_instance.edit(aggregate=partition.getRelativeUrl()) software_instance.edit(aggregate=partition.getRelativeUrl())
software_instance_2 = self.portal.software_instance_module\ software_instance_2 = self.portal.software_instance_module\
.template_software_instance.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Software Instance")
slave_instance = self.portal.software_instance_module.newContent( slave_instance = self.portal.software_instance_module.newContent(
portal_type='Slave Instance') portal_type='Slave Instance')
slave_instance_2 = self.portal.software_instance_module.newContent( slave_instance_2 = self.portal.software_instance_module.newContent(
...@@ -475,21 +475,6 @@ class TestSlapOSInstanceTreeConstraint(TestSlapOSConstraintMixin): ...@@ -475,21 +475,6 @@ class TestSlapOSInstanceTreeConstraint(TestSlapOSConstraintMixin):
class TestSlapOSPersonConstraint(TestSlapOSConstraintMixin): class TestSlapOSPersonConstraint(TestSlapOSConstraintMixin):
def test_role(self):
person = self.portal.person_module.newContent(portal_type='Person')
consistency_message = 'One role should be defined'
self.assertTrue(consistency_message in self.getMessageList(person))
role_id_list = list(self.portal.portal_categories.role.objectIds())
self.assertTrue(len(role_id_list) >= 2)
person.setRole(role_id_list[0])
self.assertFalse(consistency_message in self.getMessageList(person))
person.setRoleList(role_id_list)
self.assertTrue(consistency_message in self.getMessageList(person))
person.setRole(role_id_list[0])
self.assertFalse(consistency_message in self.getMessageList(person))
def test_subordination_state(self): def test_subordination_state(self):
organisation = self.portal.organisation_module.newContent( organisation = self.portal.organisation_module.newContent(
portal_type='Organisation') portal_type='Organisation')
......
...@@ -46,9 +46,9 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflow(SlapOSTestCaseMixin): ...@@ -46,9 +46,9 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflow(SlapOSTestCaseMixin):
# prepare part of tree # prepare part of tree
instance_tree = portal.instance_tree_module\ instance_tree = portal.instance_tree_module\
.template_instance_tree.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Instance Tree")
self.software_instance = portal.software_instance_module\ self.software_instance = portal.software_instance_module\
.template_software_instance.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Software Instance")
instance_tree.edit( instance_tree.edit(
title=self.request_kw['software_title'], title=self.request_kw['software_title'],
...@@ -72,7 +72,9 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflow(SlapOSTestCaseMixin): ...@@ -72,7 +72,9 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflow(SlapOSTestCaseMixin):
text_content=self.request_kw['instance_xml'], text_content=self.request_kw['instance_xml'],
sla_xml=self.request_kw['sla_xml'], sla_xml=self.request_kw['sla_xml'],
specialise=instance_tree.getRelativeUrl(), specialise=instance_tree.getRelativeUrl(),
follow_up_value=self.project follow_up_value=self.project,
ssl_key='foo',
ssl_certificate='bar'
) )
self.portal.portal_workflow._jumpToStateFor(self.software_instance, 'start_requested') self.portal.portal_workflow._jumpToStateFor(self.software_instance, 'start_requested')
self.software_instance.validate() self.software_instance.validate()
...@@ -1068,9 +1070,9 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflowTransfer(SlapOSTestCaseMixin): ...@@ -1068,9 +1070,9 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflowTransfer(SlapOSTestCaseMixin):
# prepare part of tree # prepare part of tree
self.instance_tree = portal.instance_tree_module\ self.instance_tree = portal.instance_tree_module\
.template_instance_tree.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Instance Tree")
self.software_instance = portal.software_instance_module\ self.software_instance = portal.software_instance_module\
.template_software_instance.Base_createCloneDocument(batch_mode=1) .newContent(portal_type="Software Instance")
self.instance_tree.edit( self.instance_tree.edit(
title=self.request_kw['software_title'], title=self.request_kw['software_title'],
...@@ -1094,7 +1096,9 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflowTransfer(SlapOSTestCaseMixin): ...@@ -1094,7 +1096,9 @@ class TestSlapOSCoreInstanceSlapInterfaceWorkflowTransfer(SlapOSTestCaseMixin):
text_content=self.request_kw['instance_xml'], text_content=self.request_kw['instance_xml'],
sla_xml=self.request_kw['sla_xml'], sla_xml=self.request_kw['sla_xml'],
specialise=self.instance_tree.getRelativeUrl(), specialise=self.instance_tree.getRelativeUrl(),
follow_up_value=self.project follow_up_value=self.project,
ssl_key='foo',
ssl_certificate='bar'
) )
self.portal.portal_workflow._jumpToStateFor(self.software_instance, 'start_requested') self.portal.portal_workflow._jumpToStateFor(self.software_instance, 'start_requested')
self.software_instance.validate() self.software_instance.validate()
......
...@@ -20,29 +20,8 @@ ...@@ -20,29 +20,8 @@
############################################################################## ##############################################################################
from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin
class TestSlapOSCoreSlapOSCloudInteractionWorkflow(SlapOSTestCaseMixin):
def test_ComputeNode_setSubjectList(self):
project = self.addProject()
self.person_user = self.makePerson(project)
self.addProjectProductionManagerAssignment(self.person_user, project)
self.tic()
self.login(self.person_user.getUserId())
new_id = self.generateNewId()
compute_node = self.portal.compute_node_module.newContent(
portal_type='Compute Node',
title="Compute Node %s for %s" % (new_id, self.person_user.getReference()),
reference="TESTCOMP-%s" % new_id,
follow_up_value=project
)
self.tic()
assert compute_node.getDestinationSectionValue() is None
compute_node.edit(subject_list=[self.person_user.getDefaultEmailText()]) class TestSlapOSCoreSlapOSCloudInteractionWorkflow(SlapOSTestCaseMixin):
self.tic()
assert compute_node.getDestinationSection() == \
self.person_user.getRelativeUrl()
def check_Instance_validate(self, portal_type): def check_Instance_validate(self, portal_type):
project = self.addProject() project = self.addProject()
...@@ -97,44 +76,6 @@ class TestSlapOSCoreSlapOSCloudInteractionWorkflow(SlapOSTestCaseMixin): ...@@ -97,44 +76,6 @@ class TestSlapOSCoreSlapOSCloudInteractionWorkflow(SlapOSTestCaseMixin):
def test_SlaveInstance_validate(self): def test_SlaveInstance_validate(self):
return self.check_Instance_validate("Slave Instance") return self.check_Instance_validate("Slave Instance")
def test_SlaveInstance_requestDestroy(self):
project = self.addProject()
self.person_user = self.makePerson(project)
self.login(self.person_user.getUserId())
# Instance Tree required for security.
hs = self.portal.instance_tree_module.newContent(
portal_type='Instance Tree',
title="HS %s for %s" % (self.new_id, self.person_user.getReference()),
reference="TESTHS-%s" % self.new_id,
destination_reference="TESTHS-%s" % self.new_id,
destination_section=self.person_user.getRelativeUrl(),
follow_up_value=project
)
instance = self.portal.software_instance_module.newContent(
portal_type='Slave Instance',
title="Instance %s for %s" % (self.new_id, self.person_user.getReference()),
reference="TESTINST-%s" % self.new_id,
destination_reference="TESTINST-%s" % self.new_id,
destination_section=self.person_user.getRelativeUrl(),
specialise_value=hs,
follow_up_value=project
)
request_kw = dict(
software_release='http://example.org',
software_type='http://example.org',
instance_xml=self.generateSafeXml(),
sla_xml=self.generateSafeXml(),
shared=True,
)
instance.requestStop(**request_kw)
self.assertEqual(instance.getValidationState(), 'draft')
instance.validate()
self.assertEqual(instance.getValidationState(), 'validated')
instance.requestDestroy(**request_kw)
self.assertEqual(instance.getValidationState(), 'invalidated')
def check_SoftwareInstallation_changeState(self, method_id): def check_SoftwareInstallation_changeState(self, method_id):
project = self.addProject() project = self.addProject()
self.person_user = self.makePerson(project) self.person_user = self.makePerson(project)
...@@ -191,15 +132,11 @@ class TestSlapOSCoreSlapOSCloudInteractionWorkflow(SlapOSTestCaseMixin): ...@@ -191,15 +132,11 @@ class TestSlapOSCoreSlapOSCloudInteractionWorkflow(SlapOSTestCaseMixin):
compute_node = self.portal.compute_node_module.newContent( compute_node = self.portal.compute_node_module.newContent(
portal_type='Compute Node', portal_type='Compute Node',
title="Compute Node %s for %s" % (new_id, self.person_user.getReference()), title="Compute Node %s for %s" % (new_id, self.person_user.getReference()),
<<<<<<< HEAD
reference="TESTCOMP-%s" % new_id)
self._addCertificateLogin(compute_node)
=======
reference="TESTCOMP-%s" % new_id, reference="TESTCOMP-%s" % new_id,
follow_up_value=project follow_up_value=project
) )
self._addERP5Login(compute_node) self._addCertificateLogin(compute_node)
>>>>>>> 1561dc0c2 (slapos_cloud: assignment needed to touch compute node)
partition = compute_node.newContent( partition = compute_node.newContent(
portal_type='Compute Partition', portal_type='Compute Partition',
title="Partition Compute Node %s for %s" % (new_id, title="Partition Compute Node %s for %s" % (new_id,
......
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
############################################################################## ##############################################################################
from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin from erp5.component.test.SlapOSTestCaseMixin import SlapOSTestCaseMixin
import transaction import transaction
from unittest import expectedFailure
from AccessControl.SecurityManagement import getSecurityManager, \ from AccessControl.SecurityManagement import getSecurityManager, \
setSecurityManager setSecurityManager
...@@ -326,7 +325,6 @@ class TestSlapOSCorePersonRequest(SlapOSTestCaseMixin): ...@@ -326,7 +325,6 @@ class TestSlapOSCorePersonRequest(SlapOSTestCaseMixin):
project_reference=self.project.getReference() project_reference=self.project.getReference()
) )
@expectedFailure
def test_Person_requestSoftwareInstance_updateInstanceTree(self): def test_Person_requestSoftwareInstance_updateInstanceTree(self):
person = self.portal.portal_membership.getAuthenticatedMember().getUserValue() person = self.portal.portal_membership.getAuthenticatedMember().getUserValue()
...@@ -352,7 +350,7 @@ class TestSlapOSCorePersonRequest(SlapOSTestCaseMixin): ...@@ -352,7 +350,7 @@ class TestSlapOSCorePersonRequest(SlapOSTestCaseMixin):
project_reference=self.project.getReference() project_reference=self.project.getReference()
) )
instance_tree = person.REQUEST.get('request_instance_tree') instance_tree = person.REQUEST.get('request_instance_tree')
instance_tree_reference = instance_tree.getReference() # instance_tree_reference = instance_tree.getReference()
transaction.commit() transaction.commit()
self.tic() self.tic()
...@@ -370,6 +368,7 @@ class TestSlapOSCorePersonRequest(SlapOSTestCaseMixin): ...@@ -370,6 +368,7 @@ class TestSlapOSCorePersonRequest(SlapOSTestCaseMixin):
shared2 = False shared2 = False
state2 = "stopped" state2 = "stopped"
try:
person.requestSoftwareInstance( person.requestSoftwareInstance(
software_release=software_release2, software_release=software_release2,
software_title=software_title, software_title=software_title,
...@@ -380,21 +379,19 @@ class TestSlapOSCorePersonRequest(SlapOSTestCaseMixin): ...@@ -380,21 +379,19 @@ class TestSlapOSCorePersonRequest(SlapOSTestCaseMixin):
state=state2, state=state2,
project_reference=self.project.getReference() project_reference=self.project.getReference()
) )
except NotImplementedError:
pass
else:
raise AssertionError('User is not supposed to change the release/type/shared')
instance_tree2 = person.REQUEST.get('request_instance_tree') self.assertEqual(software_release,
self.assertEqual(instance_tree.getRelativeUrl(),
instance_tree2.getRelativeUrl())
self.assertEqual(instance_tree_reference,
instance_tree2.getReference())
self.assertEqual(software_release2,
instance_tree.getUrlString()) instance_tree.getUrlString())
self.assertEqual(software_title, instance_tree.getTitle()) self.assertEqual(software_title, instance_tree.getTitle())
self.assertEqual(software_type2, instance_tree.getSourceReference()) self.assertEqual(software_type, instance_tree.getSourceReference())
self.assertEqual(instance_xml2, instance_tree.getTextContent()) self.assertEqual(instance_xml, instance_tree.getTextContent())
self.assertEqual(sla_xml2, instance_tree.getSlaXml()) self.assertEqual(sla_xml, instance_tree.getSlaXml())
self.assertEqual(shared2, instance_tree.getRootSlave()) self.assertEqual(shared, instance_tree.getRootSlave())
self.assertEqual("stop_requested", instance_tree.getSlapState()) self.assertEqual("start_requested", instance_tree.getSlapState())
self.assertEqual("validated", instance_tree.getValidationState()) self.assertEqual("validated", instance_tree.getValidationState())
def test_Person_requestSoftwareInstance_duplicatedInstanceTree(self): def test_Person_requestSoftwareInstance_duplicatedInstanceTree(self):
...@@ -978,208 +975,3 @@ class TestSlapOSCorePersonRequestToken(SlapOSTestCaseMixin): ...@@ -978,208 +975,3 @@ class TestSlapOSCorePersonRequestToken(SlapOSTestCaseMixin):
token.getPortalType(), "One Time Restricted Access Token") token.getPortalType(), "One Time Restricted Access Token")
self.assertEqual(token.getUrlMethod(), "POST") self.assertEqual(token.getUrlMethod(), "POST")
class TestSlapOSCorePersonNotify(SlapOSTestCaseMixin):
def afterSetUp(self):
SlapOSTestCaseMixin.afterSetUp(self)
self.project = self.addProject()
self.person = self.makePerson(self.project)
self.tic()
def beforeTearDown(self):
pass
def test_Person_notify_mandatory_argument(self):
self.assertRaises(TypeError, self.person.notify)
self.assertRaises(TypeError, self.person.notify, support_request_title="a")
self.assertRaises(TypeError, self.person.notify, support_request_title="a", support_request_description="b")
def test_Person_notify_unknown_aggregate(self):
self.assertRaises(KeyError, self.person.notify,
support_request_title="a", support_request_description="b", aggregate="c")
def test_Person_notify_computer_node(self):
compute_node, _ = self._makeComputeNode(self.project)
self._test_Person_notify(compute_node)
def test_Person_notify_instance_tree(self):
person = self.portal.person_module.template_member\
.Base_createCloneDocument(batch_mode=1)
instance_tree = self.portal\
.instance_tree_module.template_instance_tree\
.Base_createCloneDocument(batch_mode=1)
instance_tree.validate()
new_id = self.generateNewId()
instance_tree.edit(
title= "Test hosting sub ticket %s" % new_id,
reference="TESTHST-%s" % new_id,
destination_section_value=person
)
self._test_Person_notify(instance_tree)
def test_Person_notify_software_installation(self):
self._makeComputeNode(self.project)
software_installation = self.portal\
.software_installation_module.template_software_installation\
.Base_createCloneDocument(batch_mode=1)
software_installation.edit(
url_string=self.generateNewSoftwareReleaseUrl(),
aggregate=self.compute_node.getRelativeUrl(),
reference='TESTSOFTINSTS-%s' % self.generateNewId(),
title='Start requested for %s' % self.compute_node.getUid()
)
software_installation.validate()
software_installation.requestStart()
self._test_Person_notify(software_installation)
def _test_Person_notify(self, aggregate_value):
# Step 1: Notify
self.person.notify(
support_request_title="A",
support_request_description="B",
aggregate=aggregate_value.getRelativeUrl()
)
# Step 2: Check return
support_request_relative_url = self.person.REQUEST.get(
"support_request_relative_url", None)
self.assertNotEqual(None, support_request_relative_url)
support_request_in_progress = self.person.REQUEST.get(
"support_request_in_progress", None)
self.assertEqual(support_request_in_progress, support_request_relative_url)
support_request = self.portal.restrictedTraverse(support_request_in_progress)
self.assertEqual(support_request.getSimulationState(),
"validated")
self.assertEqual(support_request.getTitle(), "A")
self.assertEqual(support_request.getDescription(), "B")
self.assertNotEqual(support_request.getStartDate(), None)
self.assertEqual(support_request.getDestinationDecision(),
self.person.getRelativeUrl())
self.assertEqual(support_request.getAggregateValue(),
aggregate_value)
self.assertEqual(support_request.getResource(),
"service_module/slapos_crm_monitoring")
# Step 3: Reset REQUEST and check in progress before catalog
self.person.REQUEST.set(
"support_request_relative_url", None)
support_request_relative_url = self.person.REQUEST.get(
"support_request_relative_url", None)
self.assertEqual(None, support_request_relative_url)
self.person.notify(
support_request_title="A",
support_request_description="B",
aggregate=aggregate_value.getRelativeUrl()
)
support_request_relative_url = self.person.REQUEST.get(
"support_request_relative_url", None)
self.assertNotEqual(None, support_request_relative_url)
self.assertEqual(support_request_in_progress, support_request_relative_url)
self.tic()
# Step 4: Reset parameters and check if the support request is got again.
self.person.REQUEST.set(
"support_request_relative_url", None)
support_request_relative_url = self.person.REQUEST.get(
"support_request_relative_url", None)
self.assertEqual(None, support_request_relative_url)
support_request_in_progress = self.person.REQUEST.set(
"support_request_in_progress", None)
support_request_in_progress = self.person.REQUEST.set(
"support_request_in_progress", None)
self.assertEqual(support_request_in_progress, None)
self.commit()
self.person.notify(
support_request_title="A",
support_request_description="B",
aggregate=aggregate_value.getRelativeUrl()
)
support_request_relative_url = self.person.REQUEST.get(
"support_request_relative_url", None)
self.assertNotEqual(None, support_request_relative_url)
support_request_in_progress = self.person.REQUEST.get(
"support_request_in_progress", None)
self.assertEqual(support_request_in_progress, support_request_relative_url)
# Check if it is the same Support Request as before
self.assertEqual(support_request.getRelativeUrl(),
support_request_relative_url)
# Step 5: Retry the same thing, but now on suspended state
support_request.suspend()
self.tic()
self.person.REQUEST.set(
"support_request_relative_url", None)
support_request_relative_url = self.person.REQUEST.get(
"support_request_relative_url", None)
self.assertEqual(None, support_request_relative_url)
support_request_in_progress = self.person.REQUEST.set(
"support_request_in_progress", None)
support_request_in_progress = self.person.REQUEST.set(
"support_request_in_progress", None)
self.assertEqual(support_request_in_progress, None)
self.commit()
self.person.notify(
support_request_title="A",
support_request_description="B",
aggregate=aggregate_value.getRelativeUrl()
)
support_request_relative_url = self.person.REQUEST.get(
"support_request_relative_url", None)
self.assertNotEqual(None, support_request_relative_url)
support_request_in_progress = self.person.REQUEST.get(
"support_request_in_progress", None)
self.assertEqual(support_request_in_progress, support_request_relative_url)
# Check if it is the same Support Request as before and still suspended
self.assertEqual(support_request.getRelativeUrl(),
support_request_relative_url)
self.assertEqual(support_request.getSimulationState(), "suspended")
# Step 6: If the support request is closed, create indeed a new one.
support_request.invalidate()
self.tic()
self.person.REQUEST.set("support_request_relative_url", None)
support_request_relative_url = self.person.REQUEST.get(
"support_request_relative_url", None)
self.assertEqual(None, support_request_relative_url)
support_request_in_progress = self.person.REQUEST.set(
"support_request_in_progress", None)
support_request_in_progress = self.person.REQUEST.set(
"support_request_in_progress", None)
self.assertEqual(support_request_in_progress, None)
self.commit()
self.person.notify(
support_request_title="A",
support_request_description="B",
aggregate=aggregate_value.getRelativeUrl()
)
support_request_relative_url = self.person.REQUEST.get(
"support_request_relative_url", None)
self.assertNotEqual(None, support_request_relative_url)
support_request_in_progress = self.person.REQUEST.get(
"support_request_in_progress", None)
self.assertEqual(support_request_in_progress, support_request_relative_url)
# Check if it is the another Support Request
self.assertEqual(support_request.getSimulationState(), "invalidated")
self.assertNotEqual(support_request.getRelativeUrl(),
support_request_relative_url)
person = state_change['object']
portal = person.getPortalObject()
# Get required arguments
kwargs = state_change.kwargs
# Required args
# Raise TypeError if all parameters are not provided
try:
support_request_title = kwargs['support_request_title']
description = kwargs['support_request_description']
# Aggregate can be None, so it isn't included on the kwargs
aggregate = kwargs["aggregate"]
except KeyError:
raise TypeError, "Person_requestSupportRequest takes exactly 3 arguments"
aggregate_value = portal.restrictedTraverse(aggregate)
support_request_in_progress = person.Base_getSupportRequestInProgress(
title=support_request_title,
aggregate=aggregate
)
if support_request_in_progress is not None:
context.REQUEST.set("support_request_relative_url",
support_request_in_progress.getRelativeUrl())
context.REQUEST.set("support_request_in_progress",
support_request_in_progress.getRelativeUrl())
return
support_request_in_progress = context.REQUEST.get("support_request_in_progress", None)
if support_request_in_progress is not None:
support_request = portal.restrictedTraverse(support_request_in_progress, None)
if support_request and support_request.getTitle() == support_request_title and \
support_request.getAggregateUid() == aggregate_value.getUid():
context.REQUEST.set("support_request_relative_url", support_request_in_progress)
return
# Ensure resoure is Monitoring
resource = portal.service_module.\
slapos_crm_monitoring.getRelativeUrl()
support_request = portal.restrictedTraverse(
portal.portal_preferences.getPreferredSupportRequestTemplate())\
.Base_createCloneDocument(batch_mode=1)
support_request.edit(
title = support_request_title,
description = description,
start_date = DateTime(),
destination_decision=person.getRelativeUrl(),
aggregate_value=aggregate_value,
resource=resource
)
support_request.validate()
context.REQUEST.set("support_request_relative_url", support_request.getRelativeUrl())
context.REQUEST.set("support_request_in_progress", support_request.getRelativeUrl())
...@@ -31,7 +31,7 @@ if len(project_list) != 1: ...@@ -31,7 +31,7 @@ if len(project_list) != 1:
compute_node_portal_type = "Compute Node" compute_node_portal_type = "Compute Node"
compute_node_list = portal.portal_catalog.portal_catalog( compute_node_list = portal.portal_catalog.portal_catalog(
portal_type=compute_node_portal_type, portal_type=compute_node_portal_type,
title=compute_node_title, title={'query': compute_node_title, 'key': 'ExactMatch'},
follow_up__uid=project_list[0].getUid(), follow_up__uid=project_list[0].getUid(),
limit=2 limit=2
) )
......
...@@ -31,7 +31,7 @@ if len(project_list) != 1: ...@@ -31,7 +31,7 @@ if len(project_list) != 1:
computer_network_portal_type = "Computer Network" computer_network_portal_type = "Computer Network"
computer_network_list = portal.portal_catalog.portal_catalog( computer_network_list = portal.portal_catalog.portal_catalog(
portal_type=computer_network_portal_type, portal_type=computer_network_portal_type,
title=computer_network_title, title={'query': computer_network_title, 'key': 'ExactMatch'},
follow_up__uid=project_list[0].getUid(), follow_up__uid=project_list[0].getUid(),
#validation_state="validated", #validation_state="validated",
limit=2) limit=2)
......
...@@ -42,7 +42,7 @@ request_instance_tree_list = portal.portal_catalog( ...@@ -42,7 +42,7 @@ request_instance_tree_list = portal.portal_catalog(
portal_type=instance_tree_portal_type, portal_type=instance_tree_portal_type,
title={'query': software_title, 'key': 'ExactMatch'}, title={'query': software_title, 'key': 'ExactMatch'},
validation_state="validated", validation_state="validated",
default_destination_section_uid=person.getUid(), destination_section__uid=person.getUid(),
limit=2, limit=2,
) )
if len(request_instance_tree_list) > 1: if len(request_instance_tree_list) > 1:
...@@ -55,6 +55,14 @@ elif len(request_instance_tree_list) == 1: ...@@ -55,6 +55,14 @@ elif len(request_instance_tree_list) == 1:
(request_instance_tree.getValidationState() != "validated") or \ (request_instance_tree.getValidationState() != "validated") or \
(request_instance_tree.getDestinationSection() != person.getRelativeUrl()): (request_instance_tree.getDestinationSection() != person.getRelativeUrl()):
raise NotImplementedError, "The system was not able to get the expected instance tree" raise NotImplementedError, "The system was not able to get the expected instance tree"
# Do not allow user to change the release/type/shared status
# This is not compatible with invoicing the service
# Instance release change will be handled by allocation supply and upgrade decision
if ((request_instance_tree.getUrlString() != software_release_url_string) or \
(request_instance_tree.getSourceReference() != software_type) or \
(request_instance_tree.getRootSlave() != is_slave)) and \
(not kwargs.get("force_software_change", False)):
raise NotImplementedError, "You can not change the release / type / shared states"
else: else:
if (root_state == "destroyed"): if (root_state == "destroyed"):
# No need to create destroyed subscription. # No need to create destroyed subscription.
......
person = state_change['object']
portal = person.getPortalObject()
# Get required arguments
kwargs = state_change.kwargs
# Required args
# Raise TypeError if all parameters are not provided
try:
support_request_title = kwargs['support_request_title']
resource = kwargs['support_request_resource']
description = kwargs['support_request_description']
project_reference = kwargs['project_reference']
# Aggregate can be None, so it isn't included on the kwargs
aggregate = kwargs.get("support_request_aggregate", None)
except KeyError:
raise TypeError, "Person_requestSupportRequest takes exactly 5 arguments"
tag = "%s_%s_SupportRequestInProgress" % (person.getUid(),
support_request_title)
if (portal.portal_activities.countMessageWithTag(tag) > 0):
# The software instance is already under creation but can not be fetched from catalog
# As it is not possible to fetch informations, it is better to raise an error
raise NotImplementedError(tag)
# Ensure project is correctly set
project_list = portal.portal_catalog.portal_catalog(portal_type='Project', reference=project_reference,
validation_state='validated', limit=2)
if len(project_list) != 1:
raise NotImplementedError("%i projects '%s'" % (len(project_list), project_reference))
support_request_portal_type = "Support Request"
module = portal.getDefaultModule(portal_type=support_request_portal_type)
support_request = module.newContent(
portal_type=support_request_portal_type,
title=support_request_title,
description=description,
resource=resource,
destination_decision_value=person,
destination_project_value=project_list[0],
aggregate=aggregate,
specialise="sale_trade_condition_module/slapos_ticket_trade_condition",
activate_kw={'tag': tag}
)
context.REQUEST.set("support_request_relative_url", support_request.getRelativeUrl())
support_request.approveRegistration()
...@@ -16,11 +16,9 @@ ...@@ -16,11 +16,9 @@
<key> <string>categories</string> </key> <key> <string>categories</string> </key>
<value> <value>
<tuple> <tuple>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_notify</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_compute_node</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_compute_node</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_network</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_network</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_software_instance</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_software_instance</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_support</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_token</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_token</string>
</tuple> </tuple>
</value> </value>
......
...@@ -17,11 +17,9 @@ ...@@ -17,11 +17,9 @@
<value> <value>
<tuple> <tuple>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_draft</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_draft</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_notify</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_compute_node</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_compute_node</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_network</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_network</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_software_instance</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_software_instance</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_support</string>
<string>destination/portal_workflow/person_slap_interface_workflow/transition_request_token</string> <string>destination/portal_workflow/person_slap_interface_workflow/transition_request_token</string>
</tuple> </tuple>
</value> </value>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Transition" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>before_script/portal_workflow/person_slap_interface_workflow/script_Person_checkConsistency</string>
<string>after_script/portal_workflow/person_slap_interface_workflow/script_Person_notify</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_notify</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Notify</string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Transition" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>action_name</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/workflow</string>
<string>before_script/portal_workflow/person_slap_interface_workflow/script_Person_checkConsistency</string>
<string>after_script/portal_workflow/person_slap_interface_workflow/script_Person_requestSupportRequest</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>guard_permission</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>transition_request_support</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Transition</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Request Support</string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<key> <string>categories</string> </key> <key> <string>categories</string> </key>
<value> <value>
<tuple> <tuple>
<string>after_script/portal_workflow/slapos_cloud_interaction_workflow/script_Instance_invalidate</string> <string>after_script/portal_workflow/slapos_cloud_interaction_workflow/script_Instance_triggerInvalidationAlarm</string>
</tuple> </tuple>
</value> </value>
</item> </item>
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>interaction_SlaveInstance_requestDestroy</string> </value> <value> <string>interaction_Instance_requestDestroy</string> </value>
</item> </item>
<item> <item>
<key> <string>portal_type</string> </key> <key> <string>portal_type</string> </key>
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
<value> <value>
<tuple> <tuple>
<string>Slave Instance</string> <string>Slave Instance</string>
<string>Software Instance</string>
</tuple> </tuple>
</value> </value>
</item> </item>
...@@ -46,6 +47,10 @@ ...@@ -46,6 +47,10 @@
<key> <string>temporary_document_disallowed</string> </key> <key> <string>temporary_document_disallowed</string> </key>
<value> <int>0</int> </value> <value> <int>0</int> </value>
</item> </item>
<item>
<key> <string>title</string> </key>
<value> <string>Instance_requestDestroy</string> </value>
</item>
<item> <item>
<key> <string>trigger_method_id</string> </key> <key> <string>trigger_method_id</string> </key>
<value> <value>
......
instance = state_change["object"]
assert instance.getPortalType() == "Slave Instance"
instance.invalidate()
return state_change['object'].Base_reindexAndSenseAlarm(['slapos_cloud_invalidate_destroyed_instance'])
...@@ -60,7 +60,7 @@ ...@@ -60,7 +60,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>script_Person_notify</string> </value> <value> <string>script_Instance_triggerInvalidationAlarm</string> </value>
</item> </item>
<item> <item>
<key> <string>portal_type</string> </key> <key> <string>portal_type</string> </key>
...@@ -68,7 +68,7 @@ ...@@ -68,7 +68,7 @@
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
<value> <string>Person_notify</string> </value> <value> <string>Instance_triggerInvalidationAlarm</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -14,6 +14,7 @@ Instance Node | view ...@@ -14,6 +14,7 @@ Instance Node | view
Instance Tree Module | view Instance Tree Module | view
Instance Tree | create_hs_upgrade Instance Tree | create_hs_upgrade
Instance Tree | view Instance Tree | view
Instance Tree | view_editor
One Time Virtual Master Access Token | view One Time Virtual Master Access Token | view
Person | jump_to_instance_tree Person | jump_to_instance_tree
Remote Node | view Remote Node | view
......
instance_tree_module/template_**
person_module/template_member
portal_catalog/** portal_catalog/**
portal_preferences/slapos_default_site_preference portal_preferences/slapos_default_site_preference
portal_preferences/slapos_default_system_preference portal_preferences/slapos_default_system_preference
\ No newline at end of file
acl_users/slapos_access_token_extraction acl_users/slapos_access_token_extraction
acl_users/slapos_machine acl_users/slapos_machine
acl_users/slapos_shadow acl_users/slapos_shadow
compute_node_module/template_compute_node
compute_node_module/template_compute_node/**
computer_model_module/template_computer_model
computer_model_module/template_computer_model/**
hosting_subscription_module/template_hosting_subscription
instance_tree_module/template_instance_tree
person_module/template_member
person_module/template_member/**
portal_alarms/slapos_allocate_instance portal_alarms/slapos_allocate_instance
portal_alarms/slapos_assert_instance_tree_successor portal_alarms/slapos_assert_instance_tree_successor
portal_alarms/slapos_cloud_garbage_collect_one_time_virtual_master_access_token portal_alarms/slapos_cloud_garbage_collect_one_time_virtual_master_access_token
...@@ -26,6 +18,3 @@ portal_caches/compute_node_information_cache_factory/persistent_cache_plugin ...@@ -26,6 +18,3 @@ portal_caches/compute_node_information_cache_factory/persistent_cache_plugin
portal_caches/last_stored_data_cache_factory portal_caches/last_stored_data_cache_factory
portal_caches/last_stored_data_cache_factory/volatile_cache_plugin portal_caches/last_stored_data_cache_factory/volatile_cache_plugin
product_module/compute_node product_module/compute_node
\ No newline at end of file
software_installation_module/template_software_installation
software_instance_module/template_slave_instance
software_instance_module/template_software_instance
\ No newline at end of file
...@@ -10,6 +10,7 @@ One Time Virtual Master Access Token | agent ...@@ -10,6 +10,7 @@ One Time Virtual Master Access Token | agent
Remote Node | destination_project Remote Node | destination_project
Remote Node | destination_section Remote Node | destination_section
Remote Node | specialise Remote Node | specialise
Remote Node | subordination
Slave Instance | aggregate Slave Instance | aggregate
Slave Instance | specialise Slave Instance | specialise
Software Installation Module | business_application Software Installation Module | business_application
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment