Commit 1f835cba authored by Rafael Monnerat's avatar Rafael Monnerat

Merge remote-tracking branch 'origin/operation-control'

Conflicts:
	master/bt5/slapos_cloud/bt/revision
	master/bt5/slapos_pdm/bt/revision
parents 2c7ba44e faf2b0b5
...@@ -52,6 +52,8 @@ ...@@ -52,6 +52,8 @@
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[ <value> <string encoding="cdata"><![CDATA[
from DateTime import DateTime\n
\n
portal = context.getPortalObject()\n portal = context.getPortalObject()\n
\n \n
if software_product_reference is None:\n if software_product_reference is None:\n
...@@ -81,12 +83,20 @@ if len(product_list) > 1:\n ...@@ -81,12 +83,20 @@ if len(product_list) > 1:\n
raise NotImplementedError(\'Several Software Product with the same title.\')\n raise NotImplementedError(\'Several Software Product with the same title.\')\n
\n \n
software_release_list = product_list[0].getAggregateRelatedValueList()\n software_release_list = product_list[0].getAggregateRelatedValueList()\n
\n
def sortkey(software_release):\n
publication_date = software_release.getEffectiveDate()\n
if publication_date:\n
if (publication_date - DateTime()) > 0:\n
return DateTime(\'1900/05/02\')\n
return publication_date\n
return software_release.getCreationDate()\n
\n
software_release_list = sorted(\n software_release_list = sorted(\n
software_release_list,\n software_release_list,\n
key=lambda software_release: software_release.getCreationDate(),\n key=sortkey, reverse=True,\n
reverse=True,\n
)\n )\n
\n \n
return [software_release for software_release in software_release_list\n return [software_release for software_release in software_release_list\n
if software_release.getValidationState() in\n if software_release.getValidationState() in\n
["published"]\n ["published"]\n
......
...@@ -50,20 +50,11 @@ ...@@ -50,20 +50,11 @@
</item> </item>
<item> <item>
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string>software_release_url = context.getUrlString()\n <value> <string>network_list = []\n
portal = context.getPortalObject()\n for computer in context.SoftwareRelease_getUsableComputerList():\n
network_list = []\n network = computer.getSubordinationValue()\n
\n if network and not network in network_list:\n
kw[\'portal_type\']=\'Computer Network\'\n network_list.append(network)\n
kw[\'validation_state\']=\'validated\'\n
\n
full_network_list = portal.portal_catalog(**kw)\n
for network in full_network_list:\n
computer_list = network.getSubordinationRelatedValueList()\n
for computer in computer_list:\n
if software_release_url in computer.Computer_getSoftwareReleaseUrlStringList():\n
network_list.append(network)\n
break\n
\n \n
return network_list\n return network_list\n
</string> </value> </string> </value>
......
...@@ -50,10 +50,13 @@ ...@@ -50,10 +50,13 @@
</item> </item>
<item> <item>
<key> <string>_body</string> </key> <key> <string>_body</string> </key>
<value> <string>software_installation_list = context.portal_catalog(url_string=context.getUrlString(),\n <value> <string>kw[\'portal_type\'] = \'Software Installation\'\n
portal_type=\'Software Installation\', validation_state=\'validated\')\n kw[\'validation_state\'] = \'validated\'\n
kw[\'url_string\'] = context.getUrlString()\n
\n
software_installation_list = context.portal_catalog(**kw)\n
computer_list = []\n computer_list = []\n
allocation_scope_list = [\'open/personal\', \'open/public\', \'open/frien\']\n allocation_scope_list = [\'open/personal\', \'open/public\', \'open/friend\']\n
for software_installation in software_installation_list:\n for software_installation in software_installation_list:\n
computer = software_installation.getAggregateValue()\n computer = software_installation.getAggregateValue()\n
if software_installation.getSlapState() == \'start_requested\' and \\\n if software_installation.getSlapState() == \'start_requested\' and \\\n
......
...@@ -115,6 +115,7 @@ ...@@ -115,6 +115,7 @@
<string>my_crawling_scope</string> <string>my_crawling_scope</string>
<string>my_crawling_depth</string> <string>my_crawling_depth</string>
<string>my_update_frequency</string> <string>my_update_frequency</string>
<string>my_effective_date</string>
</list> </list>
</value> </value>
</item> </item>
......
<?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>default_now</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_effective_date</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>default_now</string> </key>
<value> <int>1</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_effective_date</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Document_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>
...@@ -15,8 +15,10 @@ ...@@ -15,8 +15,10 @@
<string>hide_rows_on_no_search_criterion</string> <string>hide_rows_on_no_search_criterion</string>
<string>list_method</string> <string>list_method</string>
<string>portal_types</string> <string>portal_types</string>
<string>search</string>
<string>search_columns</string> <string>search_columns</string>
<string>select</string> <string>select</string>
<string>sort_columns</string>
<string>title</string> <string>title</string>
</list> </list>
</value> </value>
...@@ -130,6 +132,10 @@ ...@@ -130,6 +132,10 @@
</list> </list>
</value> </value>
</item> </item>
<item>
<key> <string>search</string> </key>
<value> <int>0</int> </value>
</item>
<item> <item>
<key> <string>search_columns</string> </key> <key> <string>search_columns</string> </key>
<value> <value>
...@@ -145,6 +151,12 @@ ...@@ -145,6 +151,12 @@
<key> <string>select</string> </key> <key> <string>select</string> </key>
<value> <int>0</int> </value> <value> <int>0</int> </value>
</item> </item>
<item>
<key> <string>sort_columns</string> </key>
<value>
<list/>
</value>
</item>
<item> <item>
<key> <string>target</string> </key> <key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value> <value> <string>Click to edit the target</string> </value>
......
...@@ -149,7 +149,8 @@ class TestSoftwareReleaseListFromSoftwareProduct(testSlapOSMixin): ...@@ -149,7 +149,8 @@ class TestSoftwareReleaseListFromSoftwareProduct(testSlapOSMixin):
software_release1 = self._makeSoftwareRelease(new_id) software_release1 = self._makeSoftwareRelease(new_id)
software_release1.edit( software_release1.edit(
aggregate_value=software_product.getRelativeUrl(), aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/1-%s.cfg' % new_id url_string='http://example.org/1-%s.cfg' % new_id,
effective_date=(DateTime() + 5)
) )
software_release1.publish() software_release1.publish()
software_release2 = self._makeSoftwareRelease(self.generateNewId()) software_release2 = self._makeSoftwareRelease(self.generateNewId())
...@@ -185,14 +186,16 @@ class TestSoftwareReleaseListFromSoftwareProduct(testSlapOSMixin): ...@@ -185,14 +186,16 @@ class TestSoftwareReleaseListFromSoftwareProduct(testSlapOSMixin):
software_release2.publish() software_release2.publish()
software_release2.edit( software_release2.edit(
aggregate_value=software_product.getRelativeUrl(), aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/2-%s.cfg' % new_id url_string='http://example.org/2-%s.cfg' % new_id,
effective_date=(DateTime() - 2)
) )
# Newest software release # Newest software release
software_release1 = self._makeSoftwareRelease(new_id) software_release1 = self._makeSoftwareRelease(new_id)
software_release1.publish() software_release1.publish()
software_release1.edit( software_release1.edit(
aggregate_value=software_product.getRelativeUrl(), aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/1-%s.cfg' % new_id url_string='http://example.org/1-%s.cfg' % new_id,
effective_date=DateTime()
) )
self.tic() self.tic()
...@@ -280,6 +283,7 @@ class TestSlapOSUpgradeHostingSubscription(BaseTestSlapOSMixin): ...@@ -280,6 +283,7 @@ class TestSlapOSUpgradeHostingSubscription(BaseTestSlapOSMixin):
True) True)
self.portal.portal_workflow._jumpToStateFor(hosting_subscription, 'destroy_requested') self.portal.portal_workflow._jumpToStateFor(hosting_subscription, 'destroy_requested')
self.tic()
self.assertEqual(hosting_subscription.HostingSubscription_isUpgradable(), self.assertEqual(hosting_subscription.HostingSubscription_isUpgradable(),
False) False)
\ No newline at end of file
...@@ -32,7 +32,9 @@ ...@@ -32,7 +32,9 @@
</item> </item>
<item> <item>
<key> <string>periodicity_hour_frequency</string> </key> <key> <string>periodicity_hour_frequency</string> </key>
<value> <int>1</int> </value> <value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>periodicity_minute</string> </key> <key> <string>periodicity_minute</string> </key>
...@@ -42,9 +44,7 @@ ...@@ -42,9 +44,7 @@
</item> </item>
<item> <item>
<key> <string>periodicity_minute_frequency</string> </key> <key> <string>periodicity_minute_frequency</string> </key>
<value> <value> <int>30</int> </value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>periodicity_month</string> </key> <key> <string>periodicity_month</string> </key>
......
...@@ -26,13 +26,15 @@ ...@@ -26,13 +26,15 @@
<key> <string>periodicity_hour</string> </key> <key> <string>periodicity_hour</string> </key>
<value> <value>
<tuple> <tuple>
<int>1</int> <int>0</int>
</tuple> </tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>periodicity_hour_frequency</string> </key> <key> <string>periodicity_hour_frequency</string> </key>
<value> <int>1</int> </value> <value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>periodicity_minute</string> </key> <key> <string>periodicity_minute</string> </key>
...@@ -44,9 +46,7 @@ ...@@ -44,9 +46,7 @@
</item> </item>
<item> <item>
<key> <string>periodicity_minute_frequency</string> </key> <key> <string>periodicity_minute_frequency</string> </key>
<value> <value> <int>30</int> </value>
<none/>
</value>
</item> </item>
<item> <item>
<key> <string>periodicity_month</string> </key> <key> <string>periodicity_month</string> </key>
......
...@@ -63,20 +63,21 @@ software_instance_list = context.portal_catalog(\n ...@@ -63,20 +63,21 @@ software_instance_list = context.portal_catalog(\n
# XXX slap_state=["start_requested", "stop_requested"],\n # XXX slap_state=["start_requested", "stop_requested"],\n
default_aggregate_uid=None,\n default_aggregate_uid=None,\n
select_dict=select_dict,\n select_dict=select_dict,\n
left_join_list=select_dict.keys()\n left_join_list=select_dict.keys(),\n
group_by="specialise_uid"\n
)\n )\n
\n \n
#Get the list of concerned Hosting Subscription reference\n #Get the list of concerned Hosting Subscription reference\n
hs_reference_list = set([si.getSpecialiseReference() for si in software_instance_list \n hs_reference_list = [si.getSpecialiseReference() for si in software_instance_list \n
if si.getSlapState() in [\'start_requested\', \'stop_requested\']\n if si.getSlapState() in [\'start_requested\', \'stop_requested\']\n
])\n ]\n
\n \n
if len(hs_reference_list) > 0:\n if len(hs_reference_list) > 0:\n
portal.portal_catalog.searchAndActivate(\n portal.portal_catalog.searchAndActivate(\n
portal_type=\'Hosting Subscription\',\n portal_type=\'Hosting Subscription\',\n
validation_state=\'validated\',\n validation_state=\'validated\',\n
reference=hs_reference_list,\n reference=hs_reference_list,\n
method_id=\'HostingSubscription_checkSofwareInstanceState\',\n method_id=\'HostingSubscription_checkSofwareInstanceAllocationState\',\n
activate_kw = {\'tag\':tag}\n activate_kw = {\'tag\':tag}\n
)\n )\n
\n \n
......
...@@ -59,6 +59,8 @@ if source_project_value.getPortalType() == "Computer":\n ...@@ -59,6 +59,8 @@ if source_project_value.getPortalType() == "Computer":\n
destination_decision = source_project_value.getSourceAdministration()\n destination_decision = source_project_value.getSourceAdministration()\n
elif source_project_value.getPortalType() == "Software Instance":\n elif source_project_value.getPortalType() == "Software Instance":\n
destination_decision = source_project_value.getSpecialiseValue().getDestinationSection()\n destination_decision = source_project_value.getSpecialiseValue().getDestinationSection()\n
elif source_project_value.getPortalType() == "Hosting Subscription":\n
destination_decision = source_project_value.getDestinationSection()\n
else:\n else:\n
destination_decision = None\n destination_decision = None\n
\n \n
...@@ -66,6 +68,8 @@ if portal.ERP5Site_isSupportRequestCreationClosed(destination_decision):\n ...@@ -66,6 +68,8 @@ if portal.ERP5Site_isSupportRequestCreationClosed(destination_decision):\n
# Stop ticket creation\n # Stop ticket creation\n
return\n return\n
\n \n
if not title.startswith(\'[MONITORING]\'):\n
title = \'[MONITORING] \' + title\n
support_request_in_progress = portal.portal_catalog.getResultValue(\n support_request_in_progress = portal.portal_catalog.getResultValue(\n
portal_type = \'Support Request\',\n portal_type = \'Support Request\',\n
title = title,\n title = title,\n
...@@ -74,6 +78,8 @@ support_request_in_progress = portal.portal_catalog.getResultValue(\n ...@@ -74,6 +78,8 @@ support_request_in_progress = portal.portal_catalog.getResultValue(\n
)\n )\n
\n \n
if support_request_in_progress is None:\n if support_request_in_progress is None:\n
ressource = portal.service_module.\\\n
slapos_crm_monitoring.getRelativeUrl()\n
support_request = portal.\\\n support_request = portal.\\\n
support_request_module.\\\n support_request_module.\\\n
slapos_crm_support_request_template_for_monitoring.\\\n slapos_crm_support_request_template_for_monitoring.\\\n
...@@ -83,7 +89,8 @@ if support_request_in_progress is None:\n ...@@ -83,7 +89,8 @@ if support_request_in_progress is None:\n
description = description,\n description = description,\n
start_date = DateTime(),\n start_date = DateTime(),\n
destination_decision=destination_decision,\n destination_decision=destination_decision,\n
source_project_value = source_relative_url\n source_project_value = source_relative_url,\n
ressource=ressource\n
)\n )\n
support_request.validate()\n support_request.validate()\n
\n \n
......
...@@ -80,18 +80,9 @@ if not is_service_provider:\n ...@@ -80,18 +80,9 @@ if not is_service_provider:\n
\n \n
# Create a ticket (or re-open it) for this issue!\n # Create a ticket (or re-open it) for this issue!\n
support_request = None\n support_request = None\n
request_title = \'Allocation scope has been changed for %s\' % computer_reference\n request_title = \'[MONITORING] Allocation scope has been changed for %s\' % computer_reference\n
request_description = \'Allocation scope has been changed back to \' \\\n request_description = \'Allocation scope has been changed back to \' \\\n
\'open/personal for %s\' % computer_reference\n \'open/personal for %s\' % computer_reference\n
message_title = \'We have changed allocation scope for %s\' % computer_reference\n
notification_reference = \'slapos-crm-computer_allocation_scope.notification\'\n
notification_message = portal.portal_notifications.getDocumentValue(\n
reference=notification_reference)\n
mapping_dict = {\'computer_title\':computer.getTitle(),\n
\'computer_id\':computer_reference,\n
\'allocation_scope\':allocation_scope}\n
message = notification_message.asText(\n
substitution_method_parameter_dict={\'mapping_dict\':mapping_dict})\n
\n \n
support_request_url = context.Base_generateSupportRequestForSlapOS(\n support_request_url = context.Base_generateSupportRequestForSlapOS(\n
request_title,\n request_title,\n
...@@ -114,6 +105,26 @@ if not is_service_provider:\n ...@@ -114,6 +105,26 @@ if not is_service_provider:\n
# Existing ticket not found, can not create event for the moment\n # Existing ticket not found, can not create event for the moment\n
return\n return\n
\n \n
# Send notification message\n
message_title = \'We have changed allocation scope for %s\' % computer_reference\n
notification_reference = \'slapos-crm-computer_allocation_scope.notification\'\n
notification_message = portal.portal_notifications.getDocumentValue(\n
reference=notification_reference)\n
if notification_message is None:\n
message = """Dear user,\n
%s.\n
Do not hesitate to visit the web forum (http://community.slapos.org/forum) in case of question.\n
\n
Regards,\n
\n
The slapos team""" % request_description\n
else:\n
mapping_dict = {\'computer_title\':computer.getTitle(),\n
\'computer_id\':computer_reference,\n
\'allocation_scope\':allocation_scope}\n
message = notification_message.asText(\n
substitution_method_parameter_dict={\'mapping_dict\':mapping_dict})\n
\n
support_request.SupportRequest_trySendNotificationMessage(message_title,\n support_request.SupportRequest_trySendNotificationMessage(message_title,\n
message, person.getRelativeUrl())\n message, person.getRelativeUrl())\n
</string> </value> </string> </value>
......
...@@ -62,29 +62,81 @@ if portal.ERP5Site_isSupportRequestCreationClosed():\n ...@@ -62,29 +62,81 @@ if portal.ERP5Site_isSupportRequestCreationClosed():\n
return\n return\n
\n \n
reference = context.getReference()\n reference = context.getReference()\n
computer_title = context.getTitle()\n
ticket_title = "[MONITORING] Lost contact with computer %s" % reference\n
description = ""\n
should_notify = True\n
last_contact = "No Contact Information"\n
\n
memcached_dict = context.getPortalObject().portal_memcached.getMemcachedDict(\n memcached_dict = context.getPortalObject().portal_memcached.getMemcachedDict(\n
key_prefix=\'slap_tool\',\n key_prefix=\'slap_tool\',\n
plugin_path=\'portal_memcached/default_memcached_plugin\')\n plugin_path=\'portal_memcached/default_memcached_plugin\')\n
\n \n
try:\n try:\n
d = memcached_dict[reference]\n d = memcached_dict[reference]\n
d = json.loads(d)\n
last_contact = DateTime(d.get(\'created_at\'))\n
if (DateTime() - last_contact) > 1:\n
description = "The Computer %s (%s) has not contacted the server for more than 24 hours" \\\n
"(last contact date: %s)" % (computer_title, reference, last_contact)\n
else:\n
should_notify = False\n
except KeyError:\n except KeyError:\n
return context.Base_generateSupportRequestForSlapOS(\n ticket_title = "[MONITORING] No information about %s" % reference\n
"No information about %s" % reference,\n description = "The Computer %s (%s) has not contacted the server (No Contact Information)" % (\n
"%s has not contacted the server (No Contact Information)" % reference,\n computer_title, reference)\n
\n
\n
if should_notify:\n
support_request_url = context.Base_generateSupportRequestForSlapOS(\n
ticket_title,\n
description,\n
context.getRelativeUrl()\n context.getRelativeUrl()\n
)\n )\n
\n \n
support_request = None\n
person = context.getSourceAdministrationValue(portal_type="Person")\n
if not person:\n
return support_request_url\n
\n
if support_request_url:\n
support_request = portal.restrictedTraverse(support_request_url, None)\n
else:\n
# XXX - the support request might already exists\n
support_request = portal.portal_catalog.getResultValue(\n
portal_type = \'Support Request\',\n
title = ticket_title,\n
simulation_state = \'validated\',\n
source_project_uid = context.getUid()\n
)\n
if support_request is None:\n
# Existing ticket not found, can not create event for the moment\n
return support_request_url\n
\n
# Send Notification message\n
notification_reference = \'slapos-crm-computer_check_state.notification\'\n
notification_message = portal.portal_notifications.getDocumentValue(\n
reference=notification_reference)\n
if notification_message is None:\n
message = """Dear user,\n
%s.\n
Do not hesitate to visit the web forum (http://community.slapos.org/forum) in case of question.\n
\n \n
d = json.loads(d)\n Regards,\n
last_contact = DateTime(d.get(\'created_at\'))\n
\n \n
if (DateTime() - last_contact) > 1:\n The slapos team""" % description\n
return context.Base_generateSupportRequestForSlapOS(\n else:\n
"Lost contact with %s" % reference,\n mapping_dict = {\'computer_title\':context.getTitle(),\n
"%s has not contacted the server for more than 24 hours (last contact date: %s)" % (reference, last_contact),\n \'computer_id\':reference,\n
context.getRelativeUrl()\n \'last_contact\':last_contact}\n
)\n message = notification_message.asText(\n
substitution_method_parameter_dict={\'mapping_dict\':mapping_dict})\n
\n
support_request.SupportRequest_trySendNotificationMessage(\n
ticket_title.replace(\'[MONITORING] \', \'\'),\n
message, person.getRelativeUrl(), 5)\n
\n
return support_request_url\n
]]></string> </value> ]]></string> </value>
......
...@@ -88,11 +88,10 @@ for instance in software_instance_list:\n ...@@ -88,11 +88,10 @@ for instance in software_instance_list:\n
\n \n
if has_unallocated_instance and has_newest_allocated_instance:\n if has_unallocated_instance and has_newest_allocated_instance:\n
return context.Base_generateSupportRequestForSlapOS(\n return context.Base_generateSupportRequestForSlapOS(\n
"Hosting Subscription %s (%s) is partially allocated" % (hs_title,\n "Hosting Subscription %s is partially allocated" % hs_title,\n
hosting_subscription.getReference()),\n "%s has allocated instance(s) but, the instance %s (%s) has been unallocated for more than 4 hours." % (\n
"%s has allocated instance(s) but, instance %s (%s) has been unallocated for more than 4 hours." % (\n
hs_title, failing_instance.getTitle(), failing_instance.getAbsoluteUrl()),\n hs_title, failing_instance.getTitle(), failing_instance.getAbsoluteUrl()),\n
source_instance.getRelativeUrl())\n hosting_subscription.getRelativeUrl())\n
else:\n else:\n
return\n return\n
...@@ -105,7 +104,7 @@ else:\n ...@@ -105,7 +104,7 @@ else:\n
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>HostingSubscription_checkSofwareInstanceState</string> </value> <value> <string>HostingSubscription_checkSofwareInstanceAllocationState</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
...@@ -62,7 +62,7 @@ last_event = context.portal_catalog.getResultValue(\n ...@@ -62,7 +62,7 @@ last_event = context.portal_catalog.getResultValue(\n
sort_on=[(\'delivery.start_date\', \'DESC\')],\n sort_on=[(\'delivery.start_date\', \'DESC\')],\n
)\n )\n
if last_event and \\\n if last_event and \\\n
(DateTime() - last_event.getStartDate() < 1):\n (DateTime() - last_event.getStartDate() < interval_of_day):\n
# User has already been notified this last 24h.\n # User has already been notified this last 24h.\n
return\n return\n
event = portal.event_module.slapos_crm_web_message_template.\\\n event = portal.event_module.slapos_crm_web_message_template.\\\n
...@@ -77,13 +77,15 @@ event.edit(\n ...@@ -77,13 +77,15 @@ event.edit(\n
)\n )\n
event.stop()\n event.stop()\n
event.deliver()\n event.deliver()\n
\n
return event\n
]]></string> </value> ]]></string> </value>
</item> </item>
<item> <item>
<key> <string>_params</string> </key> <key> <string>_params</string> </key>
<value> <string>message_title, message, source_relative_url</string> </value> <value> <string>message_title, message, source_relative_url, interval_of_day=1</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
...@@ -43,13 +43,8 @@ class TestSlapOSCloudSupportRequestGeneration(testSlapOSMixin): ...@@ -43,13 +43,8 @@ class TestSlapOSCloudSupportRequestGeneration(testSlapOSMixin):
def _cancelTestSupportRequestList(self): def _cancelTestSupportRequestList(self):
for support_request in self.portal.portal_catalog( for support_request in self.portal.portal_catalog(
portal_type="Support Request", portal_type="Support Request",
title="Test Support Request %", title="%Test Support Request %",
simulation_state="validated"): simulation_state=["validated", "suspended"]):
support_request.invalidate()
for support_request in self.portal.portal_catalog(
portal_type="Support Request",
title="Allocation scope has been changed for TESTCOMPT%",
simulation_state="suspended"):
support_request.invalidate() support_request.invalidate()
self.tic() self.tic()
...@@ -188,6 +183,23 @@ class TestSlapOSCloudSupportRequestGeneration(testSlapOSMixin): ...@@ -188,6 +183,23 @@ class TestSlapOSCloudSupportRequestGeneration(testSlapOSMixin):
# The support request is added to computer owner. # The support request is added to computer owner.
self.assertEquals(support_request.getDestinationDecision(), self.assertEquals(support_request.getDestinationDecision(),
host_sub.getDestinationSection()) host_sub.getDestinationSection())
def test_hosting_subscription_Base_generateSupportRequestForSlapOS(self):
host_sub = self._makeHostingSubscription(self.new_id)
title = "Test Support Request %s" % self.new_id
support_request = host_sub.Base_generateSupportRequestForSlapOS(
title, title, host_sub.getRelativeUrl()
)
self.tic()
self.assertNotEqual(support_request, None)
support_request = self.portal.restrictedTraverse(support_request)
# The support request is added to computer owner.
self.assertEquals(support_request.getDestinationDecision(),
host_sub.getDestinationSection())
def test_Base_generateSupportRequestForSlapOS_do_not_recreate_if_open(self): def test_Base_generateSupportRequestForSlapOS_do_not_recreate_if_open(self):
title = "Test Support Request %s" % self.new_id title = "Test Support Request %s" % self.new_id
...@@ -234,6 +246,29 @@ class TestSlapOSCloudSupportRequestGeneration(testSlapOSMixin): ...@@ -234,6 +246,29 @@ class TestSlapOSCloudSupportRequestGeneration(testSlapOSMixin):
self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed( self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed(
other_person.getRelativeUrl())) other_person.getRelativeUrl()))
def test_ERP5Site_isSupportRequestCreationClosed_submitted_state(self):
person = self._makePerson(self.new_id)
url = person.getRelativeUrl()
self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed(url))
self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed())
def newSupportRequest():
sr = self.portal.support_request_module.newContent(\
title="Test Support Request POIUY",
destination_decision=url)
sr.validate()
sr.suspend()
sr.immediateReindexObject()
# Create five tickets, the limit of ticket creation
newSupportRequest()
newSupportRequest()
newSupportRequest()
newSupportRequest()
newSupportRequest()
self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed(url))
self.assertFalse(self.portal.ERP5Site_isSupportRequestCreationClosed())
def test_Base_generateSupportRequestForSlapOS_recreate_if_closed(self): def test_Base_generateSupportRequestForSlapOS_recreate_if_closed(self):
title = "Test Support Request %s" % self.new_id title = "Test Support Request %s" % self.new_id
...@@ -290,6 +325,47 @@ class TestSlapOSCloudSupportRequestGeneration(testSlapOSMixin): ...@@ -290,6 +325,47 @@ class TestSlapOSCloudSupportRequestGeneration(testSlapOSMixin):
self.assertEqual('Visited Base_generateSupportRequestForSlapOS', self.assertEqual('Visited Base_generateSupportRequestForSlapOS',
result) result)
def test_SupportRequest_trySendNotificationMessage(self):
title = "Test Support Request %s" % self.new_id
text_content='Test NM content<br/>%s<br/>' % self.new_id
computer = self._makeComputer(self.new_id)
support_request_url = computer.Base_generateSupportRequestForSlapOS(
title, title, computer.getRelativeUrl()
)
support_request = self.portal.restrictedTraverse(support_request_url)
person = computer.getSourceAdministrationValue()
time_before_next = 2
self.tic()
first_event = support_request.SupportRequest_trySendNotificationMessage(
message_title=title, message=text_content,
source_relative_url=person.getRelativeUrl(),
interval_of_day=time_before_next
)
self.assertNotEqual(first_event, None)
first_event.edit(start_date=(DateTime() - 1.8))
self.tic()
event = support_request.SupportRequest_trySendNotificationMessage(
message_title=title, message=text_content,
source_relative_url=person.getRelativeUrl(),
interval_of_day=time_before_next
)
self.assertEqual(event, None)
time_before_next = 1
event = support_request.SupportRequest_trySendNotificationMessage(
message_title=title, message=text_content,
source_relative_url=person.getRelativeUrl(),
interval_of_day=time_before_next
)
self.assertEqual(event.getTitle(), title)
def test_Computer_checkState_empty_cache(self): def test_Computer_checkState_empty_cache(self):
computer = self._makeComputer(self.new_id) computer = self._makeComputer(self.new_id)
...@@ -757,7 +833,7 @@ portal_workflow.doActionFor(context, action='edit_action', comment='Visited by C ...@@ -757,7 +833,7 @@ portal_workflow.doActionFor(context, action='edit_action', comment='Visited by C
computer.workflow_history['edit_workflow'][-1]['comment']) computer.workflow_history['edit_workflow'][-1]['comment'])
def _simulateHostingSubscription_checkSofwareInstanceState(self): def _simulateHostingSubscription_checkSofwareInstanceState(self):
script_name = 'HostingSubscription_checkSofwareInstanceState' script_name = 'HostingSubscription_checkSofwareInstanceAllocationState'
if script_name in self.portal.portal_skins.custom.objectIds(): if script_name in self.portal.portal_skins.custom.objectIds():
raise ValueError('Precondition failed: %s exists in custom' % script_name) raise ValueError('Precondition failed: %s exists in custom' % script_name)
createZODBPythonScript(self.portal.portal_skins.custom, createZODBPythonScript(self.portal.portal_skins.custom,
...@@ -765,11 +841,11 @@ portal_workflow.doActionFor(context, action='edit_action', comment='Visited by C ...@@ -765,11 +841,11 @@ portal_workflow.doActionFor(context, action='edit_action', comment='Visited by C
'*args, **kw', '*args, **kw',
'# Script body\n' '# Script body\n'
"""portal_workflow = context.portal_workflow """portal_workflow = context.portal_workflow
portal_workflow.doActionFor(context, action='edit_action', comment='Visited by HostingSubscription_checkSofwareInstanceState') """ ) portal_workflow.doActionFor(context, action='edit_action', comment='Visited by HostingSubscription_checkSofwareInstanceAllocationState') """ )
transaction.commit() transaction.commit()
def _dropHostingSubscription_checkSofwareInstanceState(self): def _dropHostingSubscription_checkSofwareInstanceState(self):
script_name = 'HostingSubscription_checkSofwareInstanceState' script_name = 'HostingSubscription_checkSofwareInstanceAllocationState'
if script_name in self.portal.portal_skins.custom.objectIds(): if script_name in self.portal.portal_skins.custom.objectIds():
self.portal.portal_skins.custom.manage_delObjects(script_name) self.portal.portal_skins.custom.manage_delObjects(script_name)
transaction.commit() transaction.commit()
...@@ -788,6 +864,6 @@ portal_workflow.doActionFor(context, action='edit_action', comment='Visited by H ...@@ -788,6 +864,6 @@ portal_workflow.doActionFor(context, action='edit_action', comment='Visited by H
finally: finally:
self._dropHostingSubscription_checkSofwareInstanceState() self._dropHostingSubscription_checkSofwareInstanceState()
self.assertEqual('Visited by HostingSubscription_checkSofwareInstanceState', self.assertEqual('Visited by HostingSubscription_checkSofwareInstanceAllocationState',
host_sub.workflow_history['edit_workflow'][-1]['comment']) host_sub.workflow_history['edit_workflow'][-1]['comment'])
\ No newline at end of file
37 44
\ No newline at end of file \ No newline at end of file
...@@ -1691,11 +1691,13 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin): ...@@ -1691,11 +1691,13 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
self.assertTrue(software_release3.getValidationState() == 'released') self.assertTrue(software_release3.getValidationState() == 'released')
software_release1.edit( software_release1.edit(
aggregate_value=software_product.getRelativeUrl(), aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/1.cfg' url_string='http://example.org/1.cfg',
effective_date=DateTime()
) )
software_release2.edit( software_release2.edit(
aggregate_value=software_product.getRelativeUrl(), aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/2.cfg' url_string='http://example.org/2.cfg',
effective_date=DateTime()
) )
software_release3.edit( software_release3.edit(
aggregate_value=software_product.getRelativeUrl(), aggregate_value=software_product.getRelativeUrl(),
...@@ -1722,6 +1724,56 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin): ...@@ -1722,6 +1724,56 @@ class TestSlapOSSlapToolInstanceAccess(TestSlapOSSlapToolMixin):
""" % (software_release2.getUrlString(), software_release1.getUrlString()) """ % (software_release2.getUrlString(), software_release1.getUrlString())
self.assertEqual(expected_xml, got_xml, self.assertEqual(expected_xml, got_xml,
'\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))])) '\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
def test_getSoftwareReleaseListFromSoftwareProduct_effectiveDate(self):
new_id = self.generateNewId()
software_product = self._makeSoftwareProduct(new_id)
# 3 published software releases
software_release1 = self._makeSoftwareRelease(new_id)
software_release2 = self._makeSoftwareRelease(self.generateNewId())
software_release3 = self._makeSoftwareRelease(self.generateNewId())
software_release1.publish()
software_release2.publish()
software_release3.publish()
software_release1.edit(
aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/1.cfg',
effective_date=(DateTime() - 1)
)
# Should not be considered yet!
software_release2.edit(
aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/2.cfg',
effective_date=(DateTime() + 1)
)
software_release3.edit(
aggregate_value=software_product.getRelativeUrl(),
url_string='http://example.org/3.cfg',
effective_date=DateTime()
)
self.tic()
response = self.portal_slap.getSoftwareReleaseListFromSoftwareProduct(
software_product.getReference())
# check returned XML
xml_fp = StringIO.StringIO()
xml.dom.ext.PrettyPrint(xml.dom.ext.reader.Sax.FromXml(response),
stream=xml_fp)
xml_fp.seek(0)
got_xml = xml_fp.read()
expected_xml = """\
<?xml version='1.0' encoding='UTF-8'?>
<marshal>
<list id='i2'>
<string>%s</string>
<string>%s</string>
<string>%s</string>
</list>
</marshal>
""" % (software_release3.getUrlString(), software_release1.getUrlString(),
software_release2.getUrlString())
self.assertEqual(expected_xml, got_xml,
'\n'.join([q for q in difflib.unified_diff(expected_xml.split('\n'), got_xml.split('\n'))]))
def test_getSoftwareReleaseListFromSoftwareProduct_emptySoftwareProduct(self): def test_getSoftwareReleaseListFromSoftwareProduct_emptySoftwareProduct(self):
new_id = self.generateNewId() new_id = self.generateNewId()
......
34 35
\ No newline at end of file \ No newline at end of file
...@@ -386,9 +386,18 @@ class SlapTool(BaseTool): ...@@ -386,9 +386,18 @@ class SlapTool(BaseTool):
raise NotImplementedError('Several Software Product with the same title.') raise NotImplementedError('Several Software Product with the same title.')
software_release_list = \ software_release_list = \
software_product_list[0].getObject().getAggregateRelatedValueList() software_product_list[0].getObject().getAggregateRelatedValueList()
def sortkey(software_release):
publication_date = software_release.getEffectiveDate()
if publication_date:
if (publication_date - DateTime()) > 0:
return DateTime('1900/05/02')
return publication_date
return software_release.getCreationDate()
software_release_list = sorted( software_release_list = sorted(
software_release_list, software_release_list,
key=lambda software_release: software_release.getCreationDate(), key=sortkey,
reverse=True, reverse=True,
) )
return xml_marshaller.xml_marshaller.dumps( return xml_marshaller.xml_marshaller.dumps(
......
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