Skip to content

Commit

Permalink
Dynamic polcies from form
Browse files Browse the repository at this point in the history
  • Loading branch information
JosepSampe committed Oct 20, 2017
1 parent 8f859ec commit 44c69a0
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 55 deletions.
20 changes: 11 additions & 9 deletions api/policies/actors/rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class Rule(object):
_ask = ['get_target']
_tell = ['update', 'start_rule', 'stop_actor']

def __init__(self, rule_parsed, action, target_id, target_name, controller_server):
def __init__(self, policy_data, controller_server):
"""
Initialize all the variables needed for the rule.
Expand Down Expand Up @@ -54,9 +54,11 @@ def __init__(self, rule_parsed, action, target_id, target_name, controller_serve
db=self.redis_db)

self.rule_parsed = rule_parsed
self.action_list = action
self.target_id = target_id
self.target_name = target_name
self.action = policy_data['action']
self.filter = policy_data['filter']
self.params = policy_data['parameters']
self.target_id = policy_data['target_id']
self.target_name = policy_data['target_name']
self.controller_server = controller_server

self.conditions = rule_parsed.condition_list.asList()
Expand Down Expand Up @@ -197,10 +199,10 @@ def _do_action(self):

headers = {"X-Auth-Token": self.token}

if self.action_list.action == "SET":
if self.action == "SET":
# TODO Review if this tenant has already deployed this filter. Not deploy the same filter more than one time.

url = os.path.join(self.controller_server, 'filters', self.target_id, "deploy", str(self.action_list.filter))
url = os.path.join(self.controller_server, 'filters', self.target_id, "deploy", str(self.filter))

data = dict()

Expand All @@ -214,7 +216,7 @@ def _do_action(self):
else:
data['object_size'] = ''

data['params'] = self.action_list.params
data['params'] = self.params

response = requests.put(url, json.dumps(data), headers=headers)

Expand All @@ -229,9 +231,9 @@ def _do_action(self):
else:
logger.error('Error setting policy')

elif self.action_list.action == "DELETE":
elif self.action == "DELETE":

url = os.path.join(self.controller_server, 'filters', self.target_id, "undeploy", str(self.action_list.filter))
url = os.path.join(self.controller_server, 'filters', self.target_id, "undeploy", str(self.filter))
response = requests.put(url, headers=headers)

if 200 <= response.status_code < 300:
Expand Down
15 changes: 7 additions & 8 deletions api/policies/actors/rule_transient.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class TransientRule(Rule):
_ask = ['get_target']
_async = ['update', 'start_rule', 'stop_actor']

def __init__(self, rule_parsed, action, target_id, target_name, controller_server):
def __init__(self, policy_data, controller_server):
"""
Initialize all the variables needed for the rule.
Expand All @@ -29,8 +29,7 @@ def __init__(self, rule_parsed, action, target_id, target_name, controller_serve
:param target_name: The target assigned to this rule.
:type target_name: **any** String type
"""
super(TransientRule, self).__init__(rule_parsed, action, target_id,
target_name, controller_server)
super(TransientRule, self).__init__(policy_data, controller_server)
logger.info("Transient Rule")
self.execution_stat = False
self.static_policy_id = None
Expand Down Expand Up @@ -63,12 +62,12 @@ def do_action(self, condition_result):
The do_action method is called after the conditions are satisfied. So
this method is responsible to execute the action defined in the policy.
"""
if not condition_result and self.action_list.action == "SET":
if not condition_result and self.action == "SET":
action = "DELETE"
elif not condition_result and self.action_list.action == "DELETE":
elif not condition_result and self.action == "DELETE":
action = "SET"
else:
action = self.action_list.action
action = self.action

if not self.token:
self._get_admin_token()
Expand All @@ -79,7 +78,7 @@ def do_action(self, condition_result):
# TODO Review if this tenant has already deployed this filter. Don't deploy the same filter more than one time.
logger.info("Setting static policy")
data = dict()
url = os.path.join(self.controller_server, 'filters', self.target_id, "deploy", str(self.action_list.filter))
url = os.path.join(self.controller_server, 'filters', self.target_id, "deploy", str(self.filter))

if hasattr(self.rule_parsed.object_list, "object_type"):
data['object_type'] = self.rule_parsed.object_list.object_type.object_value
Expand All @@ -91,7 +90,7 @@ def do_action(self, condition_result):
else:
data['object_size'] = ''

data['params'] = self.action_list.params
data['params'] = self.params

response = requests.put(url, json.dumps(data), headers=headers)

Expand Down
111 changes: 73 additions & 38 deletions api/policies/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def policy_list(request):
'reverse': policy['reverse'],
'execution_order': policy['execution_order'],
'params': policy['params'],
'put': filter['put'],
'put': filter['put'],
'get': filter['get'],
'post': filter['post'],
'head': filter['head'],
Expand Down Expand Up @@ -111,22 +111,57 @@ def policy_list(request):
'metric before creating a new policy', status=status.HTTP_401_UNAUTHORIZED)

return JSONResponse('Policies added successfully!', status=status.HTTP_201_CREATED)

if request.method == 'PUT':
key = "policy:" + str(r.incr('policies:id'))
# Dynamic Policy From form
host = create_local_host()
http_host = request.META['HTTP_HOST']
data = JSONParser().parse(request)

policy_id = r.incr("policies:id")
rule_id = 'policy:' + str(policy_id)

action = data['action']
project_id = data['project_id']
container = data['container_id']

project_list = get_project_list()
project_name = project_list[project_id]

target_id = os.path.join(project_id, container)
target_name = os.path.join(project_name, container)

if data['transient']:
location = settings.RULE_TRANSIENT_MODULE
else:
location = settings.RULE_MODULE
policy_location = os.path.join(settings.PYACTOR_URL, location, str(rule_id))

policy_data = {"id": policy_id,
"target_id": target_id,
"target_name": target_name,
"filter": data['filter_id'],
"parameters": data['params'],
"action": action,
"condition": data['workload_metric']+' '+data['condition'],
"object_type": data['object_type'],
"object_size": data['object_size'],
"object_tag": data['object_tag'],
"transient": data['transient'],
"policy_location": policy_location,
"alive": True}

if data['transient']:
rule_actors[policy_id] = host.spawn(rule_id,
settings.RULE_TRANSIENT_MODULE,
[policy_data, http_host])
else:
rule_actors[policy_id] = host.spawn(rule_id, settings.RULE_MODULE,
[policy_data, http_host])
rule_actors[policy_id].start_rule()

try:
r.hmset(key, {"id": key.split(':')[1],
"policy": '', # TOFIX Retrieve Policy. From where?
"target": data['target_id'],
"filter": data['filter_id'],
"condition": data['condition'],
"object_type": data['object_type'],
"object_size": data['object_size'],
"object_tag": data['object_tag'],
"transient": data['transient'],
"policy_location": '', # TOFIX Retrieve location. From where?
"alive": True})
r.hmset(key, policy_data)
return JSONResponse("Policy inserted correctly", status=status.HTTP_201_CREATED)
except RedisError:
return JSONResponse("Error inserting policy", status=status.HTTP_400_BAD_REQUEST)
Expand Down Expand Up @@ -393,48 +428,48 @@ def deploy_dynamic_policy(r, rule_string, parsed_rule, http_host):
rule_id = 'policy:' + str(policy_id)

if action_info.transient:
# print 'Transient rule:', parsed_rule
rule_actors[policy_id] = host.spawn(rule_id,
settings.RULE_TRANSIENT_MODULE,
[rules_to_parse[target], action_info,
target_id, target_name, http_host])
location = settings.RULE_TRANSIENT_MODULE
is_transient = True
else:
# print 'Rule:', parsed_rule
rule_actors[policy_id] = host.spawn(rule_id, settings.RULE_MODULE,
[rules_to_parse[target], action_info,
target_id, target_name, http_host])
location = settings.RULE_MODULE
is_transient = False

rule_actors[policy_id].start_rule()
policy_location = os.path.join(settings.PYACTOR_URL, location, str(rule_id))

# FIXME Should we recreate a static rule for each target and action??
condition_re = re.compile(r'.* (WHEN .*) DO .*', re.M | re.I)
condition_str = condition_re.match(rule_string).group(1)

object_type = ""
object_size = ""
object_tag = ""
if parsed_rule.object_list:
if parsed_rule.object_list.object_type:
object_type = parsed_rule.object_list.object_type.object_value
if parsed_rule.object_list.object_size:
object_size = [parsed_rule.object_list.object_size.operand,
parsed_rule.object_list.object_size.object_value]

policy_data = {"id": policy_id,
"target_id": target_id,
"target_name": target_name,
"filter": action_info.filter,
"parameters": action_info.params,
"action": action_info.action,
"condition": condition_str.replace('WHEN ', ''),
"object_type": object_type,
"object_size": object_size,
"object_tag": object_tag,
"transient": action_info.transient,
"policy_location": policy_location,
"alive": True}

if action_info.transient:
rule_actors[policy_id] = host.spawn(rule_id, settings.RULE_TRANSIENT_MODULE,
[policy_data, http_host])
else:
rule_actors[policy_id] = host.spawn(rule_id, settings.RULE_MODULE,
[policy_data, http_host])
rule_actors[policy_id].start_rule()
# Add policy into Redis
policy_location = os.path.join(settings.PYACTOR_URL, location, str(rule_id))
r.hmset('policy:' + str(policy_id), {"id": policy_id,
"policy": rule_string,
"target": target_name,
"filter": action_info[1],
"condition": condition_str.replace('WHEN ', ''),
"object_type": object_type,
"object_size": object_size,
"transient": is_transient,
"policy_location": policy_location,
"alive": True})
r.hmset('policy:' + str(policy_id), policy_data)


#
Expand Down

0 comments on commit 44c69a0

Please sign in to comment.