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

slapos_cloud: Implement proper revoke/generate Certificate for Software Instance

   This is same API already present on compute node, the core diference here is that the Software Instance oddly store the value.
parent db32d9f0
......@@ -38,10 +38,15 @@ from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod
from zLOG import LOG, INFO
try:
from slapos.slap.slap import \
SoftwareInstance as SlapSoftwareInstance
from slapos.util import xml2dict
except ImportError:
def xml2dict(dictionary):
raise ImportError
class SlapSoftwareInstance:
def __init__(self):
raise ImportError
def _assertACI(document):
sm = getSecurityManager()
......@@ -153,6 +158,36 @@ class SoftwareInstance(Item):
LOG('SoftwareInstance', INFO, 'Issue during parsing xml:', error=True)
return result_dict
def _asSoftwareInstance(self):
parameter_dict = self._asParameterDict()
requested_state = self.getSlapState()
if requested_state == "stop_requested":
state = 'stopped'
elif requested_state == "start_requested":
state = 'started'
elif requested_state == "destroy_requested":
state = 'destroyed'
else:
raise ValueError("Unknown slap state : %s" % requested_state)
# software instance has to define an xml parameter
xml = self._instanceXmlToDict(
parameter_dict.pop('xml'))
connection_xml = self._instanceXmlToDict(
parameter_dict.pop('connection_xml'))
filter_xml = self._instanceXmlToDict(
parameter_dict.pop('filter_xml'))
instance_guid = parameter_dict.pop('instance_guid')
software_instance = SlapSoftwareInstance(**parameter_dict)
software_instance._parameter_dict = xml
software_instance._connection_dict = connection_xml
software_instance._filter_dict = filter_xml
software_instance._requested_state = state
software_instance._instance_guid = instance_guid
return software_instance
@UnrestrictedMethod
def _asParameterDict(self, shared_instance_sql_list=None):
portal = self.getPortalObject()
......
......@@ -33,7 +33,7 @@ try:
from slapos.slap.slap import (
ComputerPartition as SlapComputePartition,
SoftwareRelease)
from slapos.util import dumps, calculate_dict_hash
from slapos.util import calculate_dict_hash
except ImportError:
# Do no prevent instance from starting
# if libs are not installed
......@@ -43,8 +43,6 @@ except ImportError:
class SoftwareRelease:
def __init__(self):
raise ImportError
def dumps(*args):
raise ImportError
def calculate_dict_hash(*args):
raise ImportError
......@@ -58,7 +56,7 @@ def _assertACI(document):
class SlapOSComputePartitionMixin(object):
def _registerComputerPartition(self):
def _registerComputePartition(self):
portal = self.getPortalObject()
computer_reference = self.getParentValue().getReference()
computer_partition_reference = self.getReference()
......@@ -124,4 +122,4 @@ class SlapOSComputePartitionMixin(object):
slave_instance_dict.pop("xml")))
slap_partition._parameter_dict.update(parameter_dict)
return dumps(slap_partition)
return slap_partition
instance = state_change['object']
if instance.getDestinationReference() is not None:
raise ValueError("Certificate still active.")
if instance.getPortalType() != "Software Instance":
# Skip if the instance isn't a Software Instance,
# since Shared Instances cannot find the object.
return
ca = context.getPortalObject().portal_certificate_authority
certificate_dict = ca.getNewCertificate(instance.getReference())
edit_kw = {'destination_reference' : certificate_dict['id'],
'ssl_key' : certificate_dict['key'],
'ssl_certificate': certificate_dict['certificate']
}
instance.edit(**edit_kw)
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_RequestedInstance_generateCertificate</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
instance = state_change['object']
portal = instance.getPortalObject()
if instance.getSslKey() is not None or instance.getSslCertificate() is not None:
instance.edit(ssl_key=None, ssl_certificate=None)
destination_reference = instance.getDestinationReference()
if destination_reference is None:
raise ValueError('No certificate')
try:
portal.portal_certificate_authority\
.revokeCertificate(instance.getDestinationReference())
except ValueError:
# Ignore already revoked certificates, as OpenSSL backend is
# non transactional, so it is ok to allow multiple tries to destruction
# even if certificate was already revoked
pass
instance.setDestinationReference(None)
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Workflow Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_RequestedInstance_revokeCertificate</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Workflow Script</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value>
<none/>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -79,15 +79,10 @@ if (request_software_instance is None):
id_group='slap_software_instance_reference',
id_generator='uid')
new_content_kw = {}
if is_slave == True:
software_instance_portal_type = "Slave Instance"
else:
software_instance_portal_type = "Software Instance"
certificate_dict = portal.portal_certificate_authority.getNewCertificate(reference)
new_content_kw['destination_reference'] = certificate_dict['id']
new_content_kw['ssl_key'] = certificate_dict['key']
new_content_kw['ssl_certificate'] = certificate_dict['certificate']
module = portal.getDefaultModule(portal_type="Software Instance")
request_software_instance = module.newContent(
......@@ -95,9 +90,9 @@ if (request_software_instance is None):
title=software_title,
specialise_value=instance_tree,
reference=reference,
activate_kw={'tag': tag},
**new_content_kw
activate_kw={'tag': tag}
)
request_software_instance.generateCertificate()
request_software_instance.validate()
if software_instance_portal_type == "Software Instance":
# Include Certificate Login so Instance become a User
......
......@@ -52,6 +52,12 @@
<key> <string>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>script_RequesterInstance_request</string> </value>
......
......@@ -17,9 +17,11 @@
<value>
<tuple>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_bang</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_generate_certificate</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_report_compute_partition_error</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_request_instance</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_request_transfer</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_revoke_certificate</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_unallocate_partition</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_update_connection</string>
</tuple>
......
......@@ -17,9 +17,11 @@
<value>
<tuple>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_bang</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_generate_certificate</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_request_start</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_request_stop</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_request_transfer</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_revoke_certificate</string>
</tuple>
</value>
</item>
......
......@@ -18,6 +18,7 @@
<tuple>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_allocate_partition</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_bang</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_generate_certificate</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_rename</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_report_compute_partition_error</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_request_destroy</string>
......@@ -25,6 +26,7 @@
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_request_start</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_request_stop</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_request_transfer</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_revoke_certificate</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_update_connection</string>
</tuple>
</value>
......
......@@ -18,6 +18,7 @@
<tuple>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_allocate_partition</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_bang</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_generate_certificate</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_rename</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_report_compute_partition_error</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_request_destroy</string>
......@@ -25,6 +26,7 @@
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_request_start</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_request_stop</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_request_transfer</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_revoke_certificate</string>
<string>destination/portal_workflow/instance_slap_interface_workflow/transition_update_connection</string>
</tuple>
</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>after_script/portal_workflow/instance_slap_interface_workflow/script_RequestedInstance_generateCertificate</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_generate_certificate</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>Generate Certificate</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>after_script/portal_workflow/instance_slap_interface_workflow/script_RequestedInstance_revokeCertificate</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_revoke_certificate</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>Revoke Certificate</string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -662,7 +662,7 @@ class SlapTool(BaseTool):
compute_partition_document = self._getComputePartitionDocument(
computer_reference, computer_partition_reference)
result = compute_partition_document._registerComputerPartition()
result = compute_partition_document._registerComputePartition()
# Keep in cache server for 7 days
self.REQUEST.response.setStatus(200)
......@@ -822,28 +822,10 @@ class SlapTool(BaseTool):
if instance.getSlapState() == 'destroy_requested':
# remove certificate from SI
if instance.getSslKey() is not None or instance.getSslCertificate() is not None:
instance.edit(
ssl_key=None,
ssl_certificate=None,
)
instance.revokeCertificate()
if instance.getValidationState() == 'validated':
instance.invalidate()
# XXX Integrate with REST API
# Code duplication will be needed until SlapTool is removed
# revoke certificate
portal = self.getPortalObject()
try:
portal.portal_certificate_authority\
.revokeCertificate(instance.getDestinationReference())
except ValueError:
# Ignore already revoked certificates, as OpenSSL backend is
# non transactional, so it is ok to allow multiple tries to destruction
# even if certificate was already revoked
pass
@convertToREST
def _setComputePartitionConnectionXml(self, compute_node_id,
compute_partition_id,
......
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