From b39c88710043228110a4b0623991a343e491c430 Mon Sep 17 00:00:00 2001 From: uday bhaskar Date: Mon, 24 Nov 2014 21:15:08 +0530 Subject: [PATCH] GBP UI - added policy targets UI Change-Id: Ib2074e794db2f1a6e7ab02225ad9173d1c77cf06 --- ....py => _50_gbp_project_add_panel_group.py} | 3 - ..._panel.py => _60_gbp_project_add_panel.py} | 3 - ..._panel.py => _61_gbp_project_add_panel.py} | 3 - ..._panel.py => _62_gbp_project_add_panel.py} | 3 - ..._panel.py => _63_gbp_project_add_panel.py} | 3 - gbpui/client.py | 61 +++- gbpui/column_filters.py | 63 +++- gbpui/fields.py | 8 +- gbpui/panel_group.py | 3 - gbpui/panels/application_policy/forms.py | 63 ++-- gbpui/panels/application_policy/tables.py | 28 +- gbpui/panels/application_policy/tabs.py | 57 +-- .../_policy_rule_set_details.html | 12 +- .../_policyrules_details.html | 9 +- gbpui/panels/application_policy/views.py | 22 +- gbpui/panels/application_policy/workflows.py | 6 +- gbpui/panels/network_policy/forms.py | 67 +++- gbpui/panels/network_policy/panel.py | 2 - gbpui/panels/network_policy/tables.py | 15 +- gbpui/panels/network_policy/tabs.py | 35 +- .../_create_network_service_param.html | 24 ++ .../network_policy/_l2_policy_details.html | 12 + .../_service_policy_details.html | 19 + .../_update_service_policy.html | 2 +- gbpui/panels/network_policy/urls.py | 8 +- gbpui/panels/network_policy/views.py | 53 ++- gbpui/panels/network_services/forms.py | 33 +- gbpui/panels/network_services/panel.py | 2 - gbpui/panels/network_services/tables.py | 28 +- gbpui/panels/network_services/tabs.py | 15 +- .../network_services/_scnode_details.html | 8 + .../network_services/_scspec_details.html | 37 +- gbpui/panels/network_services/urls.py | 2 - gbpui/panels/network_services/views.py | 45 ++- .../new.py => policytargets/__init__.py} | 0 gbpui/panels/policytargets/forms.py | 305 ++++++++++++++++ gbpui/panels/policytargets/panel.py | 20 ++ gbpui/panels/policytargets/tables.py | 224 ++++++++++++ gbpui/panels/policytargets/tabs.py | 176 ++++++++++ .../policytargets/_add_consumed.html | 25 ++ .../policytargets/_add_consumed_prs.html | 25 ++ .../policytargets/_add_contract.html | 25 ++ .../policytargets/_add_l3policy.html | 25 ++ .../policytargets/_add_policy_rule_set.html | 25 ++ .../policytargets/_add_provided_prs.html | 25 ++ .../templates/policytargets/_add_vm.html | 25 ++ .../templates/policytargets/_del_vm.html | 25 ++ .../policytargets/_l3_policy_details.html | 17 + .../policytargets/_policy_target_details.html | 45 +++ .../policytargets/_remove_consumed.html | 25 ++ .../policytargets/_remove_consumed_prs.html | 25 ++ .../policytargets/_remove_contract.html | 25 ++ .../policytargets/_remove_provided_prs.html | 25 ++ .../policytargets/_update_l3policy.html | 25 ++ .../policytargets/_update_policy_target.html | 25 ++ .../templates/policytargets/_updateepg.html | 25 ++ .../templates/policytargets/addepg.html | 11 + .../templates/policytargets/details_tabs.html | 15 + .../policytargets/group_details.html | 15 + .../templates/policytargets/updateepg.html | 11 + gbpui/panels/policytargets/urls.py | 49 +++ gbpui/panels/policytargets/views.py | 166 +++++++++ gbpui/panels/policytargets/workflows.py | 332 ++++++++++++++++++ 63 files changed, 2299 insertions(+), 216 deletions(-) rename gbpui/{_50_project_add_panel_group.py => _50_gbp_project_add_panel_group.py} (86%) rename gbpui/{_60_project_add_panel.py => _60_gbp_project_add_panel.py} (86%) rename gbpui/{_61_project_add_panel.py => _61_gbp_project_add_panel.py} (87%) rename gbpui/{_62_project_add_panel.py => _62_gbp_project_add_panel.py} (86%) rename gbpui/{_63_project_add_panel.py => _63_gbp_project_add_panel.py} (86%) create mode 100644 gbpui/panels/network_policy/templates/network_policy/_create_network_service_param.html create mode 100644 gbpui/panels/network_policy/templates/network_policy/_service_policy_details.html rename gbpui/panels/{network_services/new.py => policytargets/__init__.py} (100%) create mode 100644 gbpui/panels/policytargets/forms.py create mode 100644 gbpui/panels/policytargets/panel.py create mode 100644 gbpui/panels/policytargets/tables.py create mode 100644 gbpui/panels/policytargets/tabs.py create mode 100644 gbpui/panels/policytargets/templates/policytargets/_add_consumed.html create mode 100644 gbpui/panels/policytargets/templates/policytargets/_add_consumed_prs.html create mode 100644 gbpui/panels/policytargets/templates/policytargets/_add_contract.html create mode 100644 gbpui/panels/policytargets/templates/policytargets/_add_l3policy.html create mode 100644 gbpui/panels/policytargets/templates/policytargets/_add_policy_rule_set.html create mode 100644 gbpui/panels/policytargets/templates/policytargets/_add_provided_prs.html create mode 100644 gbpui/panels/policytargets/templates/policytargets/_add_vm.html create mode 100644 gbpui/panels/policytargets/templates/policytargets/_del_vm.html create mode 100644 gbpui/panels/policytargets/templates/policytargets/_l3_policy_details.html create mode 100644 gbpui/panels/policytargets/templates/policytargets/_policy_target_details.html create mode 100644 gbpui/panels/policytargets/templates/policytargets/_remove_consumed.html create mode 100644 gbpui/panels/policytargets/templates/policytargets/_remove_consumed_prs.html create mode 100644 gbpui/panels/policytargets/templates/policytargets/_remove_contract.html create mode 100644 gbpui/panels/policytargets/templates/policytargets/_remove_provided_prs.html create mode 100644 gbpui/panels/policytargets/templates/policytargets/_update_l3policy.html create mode 100644 gbpui/panels/policytargets/templates/policytargets/_update_policy_target.html create mode 100644 gbpui/panels/policytargets/templates/policytargets/_updateepg.html create mode 100644 gbpui/panels/policytargets/templates/policytargets/addepg.html create mode 100644 gbpui/panels/policytargets/templates/policytargets/details_tabs.html create mode 100644 gbpui/panels/policytargets/templates/policytargets/group_details.html create mode 100644 gbpui/panels/policytargets/templates/policytargets/updateepg.html create mode 100644 gbpui/panels/policytargets/urls.py create mode 100644 gbpui/panels/policytargets/views.py create mode 100644 gbpui/panels/policytargets/workflows.py diff --git a/gbpui/_50_project_add_panel_group.py b/gbpui/_50_gbp_project_add_panel_group.py similarity index 86% rename from gbpui/_50_project_add_panel_group.py rename to gbpui/_50_gbp_project_add_panel_group.py index 0ad6a6a..5ebe3a6 100644 --- a/gbpui/_50_project_add_panel_group.py +++ b/gbpui/_50_gbp_project_add_panel_group.py @@ -1,6 +1,3 @@ -# Copyright 2010-2011 OpenStack Foundation -# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. -# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at diff --git a/gbpui/_60_project_add_panel.py b/gbpui/_60_gbp_project_add_panel.py similarity index 86% rename from gbpui/_60_project_add_panel.py rename to gbpui/_60_gbp_project_add_panel.py index a2ad991..1ff8bf7 100644 --- a/gbpui/_60_project_add_panel.py +++ b/gbpui/_60_gbp_project_add_panel.py @@ -1,6 +1,3 @@ -# Copyright 2010-2011 OpenStack Foundation -# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. -# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at diff --git a/gbpui/_61_project_add_panel.py b/gbpui/_61_gbp_project_add_panel.py similarity index 87% rename from gbpui/_61_project_add_panel.py rename to gbpui/_61_gbp_project_add_panel.py index 87d2ff6..bc31abf 100644 --- a/gbpui/_61_project_add_panel.py +++ b/gbpui/_61_gbp_project_add_panel.py @@ -1,6 +1,3 @@ -# Copyright 2010-2011 OpenStack Foundation -# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. -# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at diff --git a/gbpui/_62_project_add_panel.py b/gbpui/_62_gbp_project_add_panel.py similarity index 86% rename from gbpui/_62_project_add_panel.py rename to gbpui/_62_gbp_project_add_panel.py index 8ff6278..a1761a4 100644 --- a/gbpui/_62_project_add_panel.py +++ b/gbpui/_62_gbp_project_add_panel.py @@ -1,6 +1,3 @@ -# Copyright 2010-2011 OpenStack Foundation -# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. -# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at diff --git a/gbpui/_63_project_add_panel.py b/gbpui/_63_gbp_project_add_panel.py similarity index 86% rename from gbpui/_63_project_add_panel.py rename to gbpui/_63_gbp_project_add_panel.py index 719b882..b0347a8 100644 --- a/gbpui/_63_project_add_panel.py +++ b/gbpui/_63_gbp_project_add_panel.py @@ -1,6 +1,3 @@ -# Copyright 2010-2011 OpenStack Foundation -# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. -# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at diff --git a/gbpui/client.py b/gbpui/client.py index 396b977..1ea5b0f 100644 --- a/gbpui/client.py +++ b/gbpui/client.py @@ -1,6 +1,3 @@ -# Copyright 2010-2011 OpenStack Foundation -# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. -# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at @@ -226,6 +223,13 @@ def policyrule_create(request, **kwargs): return PolicyRule(policy_rule) +def policyrule_update(request, prid, **kwargs): + body = {'policy_rule': kwargs} + policy_rule = gbpclient(request).update_policy_rule(prid, + body).get('policy_rule') + return PolicyRule(policy_rule) + + def policyrule_list(request, **kwargs): policyrules = gbpclient(request).list_policy_rules( **kwargs).get('policy_rules') @@ -268,6 +272,13 @@ def policyaction_get(request, pa_id): return PolicyAction(policyaction) +def policyaction_update(request, pc_id, **kwargs): + body = {'policy_action': kwargs} + classifier = gbpclient(request).update_policy_action(pc_id, + body).get('policy_action') + return PolicyClassifier(classifier) + + def policyrule_get(request, pr_id): policyrule = gbpclient(request).show_policy_rule( pr_id).get('policy_rule') @@ -278,10 +289,6 @@ def policyrule_delete(request, pr_id): return gbpclient(request).delete_policy_rule(pr_id) -def policyrule_update(request, pr_id, **kwargs): - return gbpclient(request).update_policy_rule(pr_id, kwargs) - - def policyclassifier_get(request, pc_id): policyclassifier = gbpclient(request).show_policy_classifier( pc_id).get('policy_classifier') @@ -295,7 +302,7 @@ def policyclassifier_delete(request, pc_id): def policyclassifier_update(request, pc_id, **kwargs): body = {'policy_classifier': kwargs} classifier = gbpclient(request).update_policy_classifier(pc_id, - body).get('policy_classifier') + body).get('policy_classifier') return PolicyClassifier(classifier) @@ -324,15 +331,34 @@ def create_networkservice_policy(request, **kwargs): def update_networkservice_policy(request, policy_id, **kwargs): body = {'network_service_policy': kwargs} - spolicy = gbpclient.update_network_service_policy( + spolicy = gbpclient(request).update_network_service_policy( policy_id, body).get('network_service_policy') return NetworkServicePolicy(spolicy) +def delete_networkservice_policy(request, policy_id, **kwargs): + gbpclient(request).delete_network_service_policy(policy_id) + + +def get_networkservice_policy(request, policy_id): + spolicy = gbpclient(request).show_network_service_policy( + policy_id).get('network_service_policy') + return NetworkServicePolicy(spolicy) + + def l3policy_get(request, pc_id, **kwargs): return gbpclient(request).show_l3_policy(pc_id).get('l3_policy') +def l3policy_create(request, **kwargs): + body = {'l3_policy': kwargs} + return gbpclient(request).create_l3_policy(body).get('l3_policy') + + +def l3policy_delete(request, policy_id): + gbpclient(request).delete_l3_policy(policy_id) + + def l2policy_get(request, pc_id, **kwargs): return L2Policy(gbpclient(request).show_l2_policy(pc_id).get('l2_policy')) @@ -349,9 +375,8 @@ def l2policy_update(request, pc_id, **kwargs): return L2Policy(policy) -def l3policy_create(request, **kwargs): - body = {'l3_policy': kwargs} - return gbpclient(request).create_l3_policy(body).get('l3_policy') +def l2policy_delete(request, policy_id): + gbpclient(request).delete_l2_policy(policy_id) def servicechainnode_list(request, **kwargs): @@ -392,6 +417,10 @@ def update_servicechain_node(request, scnode_id, **kwargs): return ServiceChainNode(sc_node) +def delete_servicechain_node(request, scnode_id): + gbpclient(request).delete_servicechain_node(scnode_id) + + def get_servicechain_spec(request, scspec_id): sc_spec = gbpclient(request).show_servicechain_spec( scspec_id).get('servicechain_spec') @@ -412,6 +441,10 @@ def update_servicechain_spec(request, scspec_id, **kwargs): return ServiceChainSpec(sc_spec) +def delete_servicechain_spec(request, scspec_id): + gbpclient(request).delete_servicechain_spec(scspec_id) + + def get_servicechain_instance(request, scinstance_id): sc_instance = gbpclient(request).show_servicechain_instance( scinstance_id).get('servicechain_instance') @@ -430,3 +463,7 @@ def update_servicechain_instance(request, scinstance_id, **kwargs): sc_instance = gbpclient(request).update_servicechain_instance( scinstance_id, body).get('servicechain_instance') return ServiceChainInstance(sc_instance) + + +def delete_servicechain_instance(request, scinstance_id): + gbpclient(request).delete_servicechain_instance(scinstance_id) diff --git a/gbpui/column_filters.py b/gbpui/column_filters.py index a617d68..26def66 100644 --- a/gbpui/column_filters.py +++ b/gbpui/column_filters.py @@ -1,6 +1,3 @@ -# Copyright 2010-2011 OpenStack Foundation -# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. -# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at @@ -45,6 +42,22 @@ def update_pruleset_attributes(request, prset): return prset +def update_service_policy_attributes(policy): + np = policy.network_service_params + params = "" + if len(np) > 0: + tags = [] + for item in np: + dl = ["
"] + dl.extend(["
%s
%s
" % + (k, v) for k, v in item.items()]) + dl.append("
") + tags.append("".join(dl)) + params = mark_safe("".join(tags)) + setattr(policy, 'network_service_params', params) + return policy + + def update_policy_target_attributes(request, pt): url = "horizon:project:application_policy:policy_rule_set_details" provided = pt.provided_policy_rule_sets @@ -70,7 +83,7 @@ def update_policy_target_attributes(request, pt): l2url = "horizon:project:network_policy:l2policy_details" if pt.l2_policy_id is not None: policy = client.l2policy_get(request, pt.l2_policy_id) - u = reverse(l2url, {'l2policy_id': policy.id}) + u = reverse(l2url, kwargs={'l2policy_id': policy.id}) atag = mark_safe( "" + policy.name + "") setattr(pt, 'l2_policy_id', atag) @@ -80,24 +93,52 @@ def update_policy_target_attributes(request, pt): def update_policyrule_attributes(request, prule): url = "horizon:project:application_policy:policyclassifierdetails" classifier_id = prule.policy_classifier_id - classifier = client. policyclassifier_get(request, classifier_id) + classifier = client.policyclassifier_get(request, classifier_id) u = reverse(url, kwargs={'policyclassifier_id': classifier.id}) tag = mark_safe("" + classifier.name + "") setattr(prule, 'policy_classifier_id', tag) + actions = prule.policy_actions + action_url = "horizon:project:application_policy:policyactiondetails" + ul = ["") + ultag = "".join(ul) + setattr(prule, 'policy_actions', mark_safe(ultag)) return prule +def update_policyaction_attributes(request, paction): + if paction.action_type == 'redirect': + spec = client.get_servicechain_spec(request, + paction.action_value) + url = "horizon:project:network_services:sc_spec_details" + url = reverse(url, kwargs={'scspec_id': spec.id}) + tag_content = (url, spec.name + ":" + spec.id) + tag = "%s" % tag_content + setattr(paction, 'action_value', mark_safe(tag)) + return paction + + def update_sc_spec_attributes(request, scspec): nodes = scspec.nodes nodes = [client.get_servicechain_node(request, item) for item in nodes] - value = [" \ - "] + t = "
< /span>
"] for n in nodes: - value.append( + val.append( "") - value.append("") - value.append("
" + val = [t + "" + n.name + "(" + n.service_type + ")
") - setattr(scspec, 'nodes', mark_safe("".join(value))) + val.append("" + n.name + "(" + n.service_type + ")") + val.append("") + setattr(scspec, 'nodes', mark_safe("".join(val))) return scspec diff --git a/gbpui/fields.py b/gbpui/fields.py index b197b5f..9bed2f4 100644 --- a/gbpui/fields.py +++ b/gbpui/fields.py @@ -1,6 +1,3 @@ -# Copyright 2010-2011 OpenStack Foundation -# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. -# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at @@ -63,3 +60,8 @@ class DynamicMultiChoiceField(fields.MultipleChoiceField): super(DynamicMultiChoiceField, self).__init__(*args, **kwargs) self.widget.add_item_link = add_item_link self.widget.add_item_link_args = add_item_link_args + + +class CustomMultiChoiceField(DynamicMultiChoiceField): + def validate(self, *args, **kwargs): + return True diff --git a/gbpui/panel_group.py b/gbpui/panel_group.py index f1b0f0e..3832aff 100644 --- a/gbpui/panel_group.py +++ b/gbpui/panel_group.py @@ -1,6 +1,3 @@ -# Copyright 2010-2011 OpenStack Foundation -# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. -# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at diff --git a/gbpui/panels/application_policy/forms.py b/gbpui/panels/application_policy/forms.py index 09445d9..f283d40 100644 --- a/gbpui/panels/application_policy/forms.py +++ b/gbpui/panels/application_policy/forms.py @@ -1,6 +1,3 @@ -# Copyright 2010-2011 OpenStack Foundation -# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. -# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at @@ -98,14 +95,14 @@ class AddPolicyActionForm(forms.SelfHandlingForm): 'class': 'switchable', 'data-slug': 'source' })) - action_value = forms.ChoiceField(label=_("Action Value"), + action_value = forms.ChoiceField(label=_("Service Chain Spec"), required=False, choices=[], widget=forms.Select(attrs={ 'class': 'switched', 'data-switch-on': 'source', 'data-source-redirect': - _('Action Value') + _('Service Chain Spec') })) def __init__(self, request, *args, **kwargs): @@ -137,9 +134,8 @@ class AddPolicyActionForm(forms.SelfHandlingForm): class UpdatePolicyActionForm(forms.SelfHandlingForm): name = forms.CharField(label=_("Name")) - description = forms.CharField(label=_("Description"), required=False) - action_type = forms.ChoiceField(label=_("Action")) - action_value = forms.CharField(label=_("Action Value"), required=False) + description = forms.CharField(label=_("Description"), + required=False) def __init__(self, request, *args, **kwargs): super(UpdatePolicyActionForm, self).__init__(request, *args, **kwargs) @@ -148,16 +144,15 @@ class UpdatePolicyActionForm(forms.SelfHandlingForm): policyaction_id = self.initial['policyaction_id'] pa = client.policyaction_get(request, policyaction_id) self.fields['name'].initial = pa.name - self.fields['action_value'].initial = pa.action_value - self.fields['action_type'].initial = pa.action_type + self.fields['description'].initial = pa.description except Exception: pass - self.fields['action_type'].choices = POLICY_ACTION_TYPES def handle(self, request, context): url = reverse('horizon:project:application_policy:index') try: - # policyaction_id = self.initial['policyaction_id'] + policyaction_id = self.initial['policyaction_id'] + client.policyaction_update(request, policyaction_id, **context) messages.success(request, _('Policy Action successfully updated.')) return http.HttpResponseRedirect(url) except Exception: @@ -167,15 +162,22 @@ class UpdatePolicyActionForm(forms.SelfHandlingForm): class AddPolicyClassifierForm(forms.SelfHandlingForm): name = forms.CharField(max_length=80, label=_("Name"), required=False) - protocol = forms.ChoiceField( - label=_("Protocol"), - choices=PROTOCOLS) - port_range = forms.CharField( - max_length=80, - label=_("Port/Range(min:max)"), - required=False) - direction = forms.ChoiceField( - label=_("Direction"), + protocol = forms.ChoiceField(label=_("Protocol"), choices=PROTOCOLS, + widget=forms.Select(attrs={'class': 'switchable', + 'data-slug': 'source'})) + port_range = forms.CharField(max_length=80, label=_("Port/Range(min:max)"), + required=False, + widget=forms.TextInput(attrs={'class': 'switched', + 'data-switch-on': 'source', + 'data-source-tcp': _("Port/Range(min:max)"), + 'data-source-udp': _("Port/Range(min:max)"), + 'data-source-http': _("Port/Range(min:max)"), + 'data-source-https': _("Port/Range(min:max)"), + 'data-source-smtp': _("Port/Range(min:max)"), + 'data-source-dns': _("Port/Range(min:max)"), + 'data-source-ftp': _("Port/Range(min:max)"), + 'data-source-any': _("Port/Range(min:max)")})) + direction = forms.ChoiceField(label=_("Direction"), choices=[('in', _('IN')), ('out', _('OUT')), ('bi', _('BI'))]) @@ -186,6 +188,8 @@ class AddPolicyClassifierForm(forms.SelfHandlingForm): def handle(self, request, context): url = reverse('horizon:project:application_policy:index') try: + if not bool(context['port_range']): + context['port_range'] = None classifier = client.policyclassifier_create(request, **context) messages.success( request, _('Policy Classifier successfully created.')) @@ -200,8 +204,8 @@ class UpdatePolicyClassifierForm(forms.SelfHandlingForm): name = forms.CharField(max_length=80, label=_("Name"), required=False) description = forms.CharField(label=_("Description"), required=False) protocol = forms.ChoiceField(label=_("Protocol"), choices=PROTOCOLS) - port_range = forms.CharField( - max_length=80, label=_("Port/Range(min:max)"), required=False) + port_range = forms.CharField(max_length=80, label=_("Port/Range(min:max)"), + required=False) direction = forms.ChoiceField(label=_("Direction"), choices=DIRECTIONS) def __init__(self, request, *args, **kwargs): @@ -222,8 +226,10 @@ class UpdatePolicyClassifierForm(forms.SelfHandlingForm): url = reverse('horizon:project:application_policy:index') try: policyclassifier_id = self.initial['policyclassifier_id'] + if not bool(context['port_range']): + context['port_range'] = None client.policyclassifier_update(self.request, - policyclassifier_id, context) + policyclassifier_id, **context) messages.success( request, _('Policy classifier successfully updated.')) return http.HttpResponseRedirect(url) @@ -266,9 +272,10 @@ class UpdatePolicyRuleForm(forms.SelfHandlingForm): def handle(self, request, context): url = reverse('horizon:project:application_policy:index') try: - self.initial['policyrule_id'] + prid = self.initial['policyrule_id'] + client.policyrule_update(request, prid, **context) messages.success(request, _('Policy rule successfully updated.')) return http.HttpResponseRedirect(url) - except Exception: - exceptions.handle( - request, _("Unable to update policy rule."), redirect=url) + except Exception as e: + msg = _("Unable to update policy rule. %s") % (str(e)) + exceptions.handle(request, msg, redirect=url) diff --git a/gbpui/panels/application_policy/tables.py b/gbpui/panels/application_policy/tables.py index 4a78fa3..959bbde 100644 --- a/gbpui/panels/application_policy/tables.py +++ b/gbpui/panels/application_policy/tables.py @@ -36,23 +36,23 @@ class UpdateAppPolicyLink(tables.LinkAction): class DeleteAppPolicyLink(tables.DeleteAction): - name = "deletepolicy_rule_set" + name = "deletepolicyruleset" action_present = _("Delete") action_past = _("Scheduled deletion of %(data_type)s") data_type_singular = _("Policy Rule Set") - data_type_plural = _("Policy Rule Set") + data_type_plural = _("Policy Rule Sets") class AddPolicyRuleLink(tables.LinkAction): name = "addpolicyrules" - verbose_name = _("Create Policy-Rule") + verbose_name = _("Create Policy Rule") url = "horizon:project:application_policy:addpolicyrule" classes = ("ajax-modal", "btn-addpolicyrule",) class UpdatePolicyRuleLink(tables.LinkAction): name = "updatepolicyrule" - verbose_name = _("Edit PolicyRule") + verbose_name = _("Edit") classes = ("ajax-modal", "btn-update",) def get_link_url(self, policy_rule): @@ -66,13 +66,13 @@ class DeletePolicyRuleLink(tables.DeleteAction): name = "deletepolicyrule" action_present = _("Delete") action_past = _("Scheduled deletion of %(data_type)s") - data_type_singular = _("PolicyRule") - data_type_plural = _("PolicyRules") + data_type_singular = _("Policy Rule") + data_type_plural = _("Policy Rules") class AddPolicyClassifierLink(tables.LinkAction): name = "addpolicyclassifiers" - verbose_name = _("Create Policy-Classifier") + verbose_name = _("Create Policy Classifier") url = "horizon:project:application_policy:addpolicyclassifier" classes = ("ajax-modal", "btn-addpolicyclassifier",) @@ -93,20 +93,20 @@ class DeletePolicyClassifierLink(tables.DeleteAction): name = "deletepolicyclassifier" action_present = _("Delete") action_past = _("Scheduled deletion of %(data_type)s") - data_type_singular = _("PolicyClassifier") - data_type_plural = _("PolicyClassifiers") + data_type_singular = _("Policy Classifier") + data_type_plural = _("Policy Classifiers") class AddPolicyActionLink(tables.LinkAction): name = "addpolicyactions" - verbose_name = _("Create Policy-Action") + verbose_name = _("Create Policy Action") url = "horizon:project:application_policy:addpolicyaction" classes = ("ajax-modal", "btn-addpolicyaction",) class UpdatePolicyActionLink(tables.LinkAction): name = "updatepolicyaction" - verbose_name = _("Edit PolicyAction") + verbose_name = _("Edit") classes = ("ajax-modal", "btn-update",) def get_link_url(self, policy_action): @@ -120,8 +120,8 @@ class DeletePolicyActionLink(tables.DeleteAction): name = "deletepolicyaction" action_present = _("Delete") action_past = _("Scheduled deletion of %(data_type)s") - data_type_singular = _("PolicyAction") - data_type_plural = _("PolicyActions") + data_type_singular = _("Policy Action") + data_type_plural = _("Policy Actions") class ApplicationPoliciesTable(tables.DataTable): @@ -151,6 +151,8 @@ class PolicyRulesTable(tables.DataTable): verbose_name=_("Enabled")) policy_classifier = tables.Column("policy_classifier_id", verbose_name=_("Policy Classifier")) + policy_actions = tables.Column("policy_actions", + verbose_name=_("Policy Actions")) class Meta: name = "policyrulestable" diff --git a/gbpui/panels/application_policy/tabs.py b/gbpui/panels/application_policy/tabs.py index 8e457be..7fad372 100644 --- a/gbpui/panels/application_policy/tabs.py +++ b/gbpui/panels/application_policy/tabs.py @@ -28,30 +28,28 @@ PolicyActionsTable = tables.PolicyActionsTable class PolicyActionsTab(tabs.TableTab): table_classes = (PolicyActionsTable,) - name = _("Policy-Actions") + name = _("Policy Actions") slug = "policyactions" template_name = "horizon/common/_detail_table.html" def get_policyactionstable_data(self): + actions = [] try: tenant_id = self.request.user.tenant_id actions = client.policyaction_list( self.tab_group.request, tenant_id=tenant_id) - except Exception: - actions = [] - exceptions.handle(self.tab_group.request, - _('Unable to retrieve actions list.')) - - for action in actions: - action.set_id_as_name_if_empty() - + a = lambda x, y: gfilters.update_policyaction_attributes(x, y) + actions = [a(self.request, item) for item in actions] + except Exception as e: + msg = _('Unable to retrieve actions list. %s') % (str(e)) + exceptions.handle(self.tab_group.request, msg) return actions class PolicyClassifiersTab(tabs.TableTab): table_classes = (PolicyClassifiersTable,) - name = _("Policy-Classifiers") + name = _("Policy Classifiers") slug = "policyclassifiers" template_name = "horizon/common/_detail_table.html" @@ -74,7 +72,7 @@ class PolicyClassifiersTab(tabs.TableTab): class PolicyRulesTab(tabs.TableTab): table_classes = (PolicyRulesTable,) - name = _("Policy-Rules") + name = _("Policy Rules") slug = "policyrules" template_name = "horizon/common/_detail_table.html" @@ -130,7 +128,7 @@ class ApplicationPoliciesTabs(tabs.TabGroup): sticky = True -class ContractDetailsTab(tabs.Tab): +class PolicyRuleSetDetailsTab(tabs.Tab): name = _("Policy Rule Set Details") slug = "policy_rule_setdetails" template_name = "project/application_policy/_policy_rule_set_details.html" @@ -153,31 +151,38 @@ class ContractDetailsTab(tabs.Tab): action_list = [] for aid in rule.policy_actions: action = client.policyaction_get(request, aid) + a = {'id': action.id} if action.action_value: - action_list.append( - str(action.action_type) + ":" - + str(action.action_value)) + if action.action_type == 'redirect': + scspec = client.get_servicechain_spec(request, + action.action_value) + a['name'] = "Redirect:%s" % scspec.name + else: + values = (str(action.action_type), + str(action.action_value)) + name = "%s:%s" % values + a['name'] = name else: - action_list.append(str(action.action_type)) + a['name'] = str(action.action_type) + action_list.append(a) r['actions'] = action_list r['classifier'] = client.policyclassifier_get( request, rule.policy_classifier_id) rules_with_details.append(r) - except Exception: - exceptions.handle(request, - _('Unable to retrieve policy_rule_set details.'), - redirect=self.failure_url) + except Exception as e: + msg = _('Unable to retrieve policy_rule_set details.') % (str(e)) + exceptions.handle(request, msg, redirect=self.failure_url) return {'policy_rule_set': policy_rule_set, 'rules_with_details': rules_with_details} -class ContractDetailsTabs(tabs.TabGroup): +class PolicyRuleSetDetailsTabs(tabs.TabGroup): slug = "policy_rule_settabs" - tabs = (ContractDetailsTab,) + tabs = (PolicyRuleSetDetailsTab,) class PolicyRulesDetailsTab(tabs.Tab): - name = _("PolicyRule Details") + name = _("Policy Rule Details") slug = "policyruledetails" template_name = "project/application_policy/_policyrules_details.html" failure_url = reverse_lazy('horizon:project:policyrule:index') @@ -212,7 +217,7 @@ class PolicyRuleDetailsTabs(tabs.TabGroup): class PolicyClassifierDetailsTab(tabs.Tab): - name = _("Policyclassifier Details") + name = _("Policy Classifier Details") slug = "policyclassifierdetails" template_name = "project/application_policy/_policyclassifier_details.html" failure_url = reverse_lazy('horizon:project:policy_rule_set:index') @@ -234,7 +239,7 @@ class PolicyClassifierDetailsTabs(tabs.TabGroup): class PolicyActionDetailsTab(tabs.Tab): - name = _("PolicyAction Details") + name = _("Policy Action Details") slug = "policyactiondetails" template_name = "project/application_policy/_policyaction_details.html" failure_url = reverse_lazy('horizon:project:policy_rule_set:index') @@ -243,6 +248,8 @@ class PolicyActionDetailsTab(tabs.Tab): paid = self.tab_group.kwargs['policyaction_id'] try: policyaction = client.policyaction_get(request, paid) + policyaction = gfilters.update_policyaction_attributes(request, + policyaction) except Exception: exceptions.handle(request, _('Unable to retrieve policyaction details.'), diff --git a/gbpui/panels/application_policy/templates/application_policy/_policy_rule_set_details.html b/gbpui/panels/application_policy/templates/application_policy/_policy_rule_set_details.html index 29147cb..3553cff 100644 --- a/gbpui/panels/application_policy/templates/application_policy/_policy_rule_set_details.html +++ b/gbpui/panels/application_policy/templates/application_policy/_policy_rule_set_details.html @@ -4,19 +4,19 @@
{% trans "Name" %}
-
{{ contract.name|default:_("-") }}
+
{{ policy_rule_set.name|default:_("-") }}
{% trans "Description" %}
-
{{ contract.description|default:_("-") }}
+
{{ ppolicy_rule_set.description|default:_("-") }}
{% trans "ID" %}
-
{{ contract.id }}
+
{{ policy_rule_set.id }}
{% trans "Project ID" %}
-
{{ contract.tenant_id }}
+
{{ policy_rule_set.tenant_id }}
-{% if contract.policy_rules %} +{% if rules_with_details %}
{% trans "Policy Rules" %}
@@ -39,7 +39,7 @@ {{rule.classifier.direction}}   {% for a in rule.actions %} - {{a}}
+ {{a.name}} {% endfor %} diff --git a/gbpui/panels/application_policy/templates/application_policy/_policyrules_details.html b/gbpui/panels/application_policy/templates/application_policy/_policyrules_details.html index f24e791..aab3aca 100644 --- a/gbpui/panels/application_policy/templates/application_policy/_policyrules_details.html +++ b/gbpui/panels/application_policy/templates/application_policy/_policyrules_details.html @@ -22,17 +22,16 @@
{% trans "Policy Actions" %}
{% for action in actions%} - {{action.name}} - {% url 'horizon:project:application_policy:policyactiondetails' action as action_url %} - {{ action.position }} : {{ action.id }}
+ {% url 'horizon:project:application_policy:policyactiondetails' action.id as action_url %} + {{action.name}}:{{ action.id }}
{% endfor %}
{% trans "Policy Classifier" %}
{% for classifier in classifiers %} - {{classifier.name}}: + {% url 'horizon:project:application_policy:policyclassifierdetails' classifier.id as classifier_url %} - {{ classifier.id }}
+ {{classifier.name}}:{{ classifier.id }}
{% endfor %}
diff --git a/gbpui/panels/application_policy/views.py b/gbpui/panels/application_policy/views.py index 1795b0e..83e0160 100644 --- a/gbpui/panels/application_policy/views.py +++ b/gbpui/panels/application_policy/views.py @@ -28,7 +28,7 @@ import tabs as policy_rule_set_tabs import workflows as policy_rule_set_workflows PolicyRuleSetTabs = policy_rule_set_tabs.ApplicationPoliciesTabs -PolicyRuleSetDetailsTabs = policy_rule_set_tabs.ContractDetailsTabs +PolicyRuleSetDetailsTabs = policy_rule_set_tabs.PolicyRuleSetDetailsTabs PolicyRuleDetailsTabs = policy_rule_set_tabs.PolicyRuleDetailsTabs PolicyClassifierDetailsTabs = policy_rule_set_tabs.PolicyClassifierDetailsTabs PolicyActionDetailsTabs = policy_rule_set_tabs.PolicyActionDetailsTabs @@ -44,7 +44,7 @@ class IndexView(tabs.TabView): def post(self, request, *args, **kwargs): obj_ids = request.POST.getlist('object_ids') action = request.POST['action'] - obj_type = re.search('.delete([a-z]+)', action).group(1) + obj_type = re.search('delete([a-z]+)', action).group(1) if not obj_ids: obj_ids.append(re.search('([0-9a-z-]+)$', action).group(1)) if obj_type == 'policyaction': @@ -53,8 +53,8 @@ class IndexView(tabs.TabView): client.policyaction_delete(request, obj_id) messages.success(request, _('Deleted action %s') % obj_id) except Exception as e: - exceptions.handle(request, - _('Unable to delete action. %s') % e) + msg = _('Unable to delete action. %s') % (str(e)) + exceptions.handle(request, msg) if obj_type == 'policyclassifier': for obj_id in obj_ids: try: @@ -62,8 +62,8 @@ class IndexView(tabs.TabView): messages.success( request, _('Deleted classifer %s') % obj_id) except Exception as e: - exceptions.handle(request, - _('Unable to delete classifier. %s') % e) + msg = _('Unable to delete action. %s') % (str(e)) + exceptions.handle(request, msg) if obj_type == 'policyrule': for obj_id in obj_ids: try: @@ -71,17 +71,17 @@ class IndexView(tabs.TabView): messages.success(request, _('Deleted rule %s') % obj_id) except Exception as e: - exceptions.handle(request, - _('Unable to delete rule. %s') % e) - if obj_type == 'policy_rule_set': + msg = _('Unable to delete action. %s') % (str(e)) + exceptions.handle(request, msg) + if obj_type == 'policyruleset': for obj_id in obj_ids: try: client.policy_rule_set_delete(request, obj_id) messages.success(request, _('Deleted rule %s') % obj_id) except Exception as e: - exceptions.handle(request, - _('Unabled to delete policy_rule_set. %s') % e) + msg = _('Unable to delete action. %s') % (str(e)) + exceptions.handle(request, msg) return self.get(request, *args, **kwargs) diff --git a/gbpui/panels/application_policy/workflows.py b/gbpui/panels/application_policy/workflows.py index 78779e8..365637a 100644 --- a/gbpui/panels/application_policy/workflows.py +++ b/gbpui/panels/application_policy/workflows.py @@ -21,8 +21,8 @@ from gbpui import client from gbpui import fields ADD_POLICY_ACTION_URL = "horizon:project:application_policy:addpolicyaction" -ADD_POLICY_CLASSIFIER_URL = "horizon:project:application_policy:\ - addpolicyclassifier" +ADD_POLICY_CLASSIFIER_URL = "horizon:project:application_policy:" +ADD_POLICY_CLASSIFIER_URL = ADD_POLICY_CLASSIFIER_URL + "addpolicyclassifier" ADD_POLICY_RULE_URL = "horizon:project:application_policy:addpolicyrule" @@ -174,6 +174,8 @@ class SelectPolicyActionAction(workflows.Action): actions = sorted(actions, key=lambda action: action.name) action_list = [(a.id, a.name) for a in actions] + if len(action_list) > 0: + self.fields['actions'].initial = action_list[0] except Exception as e: action_list = [] exceptions.handle(request, diff --git a/gbpui/panels/network_policy/forms.py b/gbpui/panels/network_policy/forms.py index c7c14b8..10bec7b 100644 --- a/gbpui/panels/network_policy/forms.py +++ b/gbpui/panels/network_policy/forms.py @@ -9,8 +9,6 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -# -# @author: Ronak Shah import logging @@ -23,9 +21,12 @@ from horizon import exceptions from horizon import forms from gbpui import client +from gbpui import fields LOG = logging.getLogger(__name__) +NETWORK_PARAM_URL = "horizon:project:network_policy:add_network_service_param" + class AddL3PolicyForm(forms.SelfHandlingForm): name = forms.CharField(max_length=80, label=_("Name")) @@ -96,7 +97,7 @@ class UpdateL3PolicyForm(forms.SelfHandlingForm): subnet_prefix_length = forms.CharField(max_length=80, label=_("Subnet Prefix Length"), help_text=_("Between 2-30 for IP4" - "and 2-127 for IP6."),) + "and 2-127 for IP6."),) def __init__(self, request, *args, **kwargs): super(UpdateL3PolicyForm, self).__init__(request, *args, **kwargs) @@ -204,18 +205,59 @@ class CreateServicePolicyForm(forms.SelfHandlingForm): name = forms.CharField(max_length=80, label=_("Name")) description = forms.CharField( max_length=80, label=_("Description"), required=False) + network_service_params = fields.CustomMultiChoiceField(label=_( + "Network Service Parameters"), add_item_link=NETWORK_PARAM_URL, + required=False) def handle(self, request, context): url = reverse("horizon:project:network_policy:index") try: + params = context['network_service_params'] + p = [] + if len(params) > 0: + for item in params: + values = [i.split(":")[1] for i in item.split(",")] + values = {'type': values[0], + 'name': values[1], + 'value': values[2]} + p.append(values) + context['network_service_params'] = p client.create_networkservice_policy(request, **context) msg = _("Service policy created successfully!") LOG.debug(msg) return http.HttpResponseRedirect(url) - except Exception: - msg = _("Failed to create service policy") + except Exception as e: + msg = _("Failed to create service policy. %s") % (str(e)) LOG.error(msg) - exceptions.handle(request, msg, redirect=shortcuts.redirect) + exceptions.handle(request, msg, redirect=url) + + +class NetworkServiceParam(object): + + def __init__(self, context): + self.ptype = context['param_type'] + self.pname = context['param_name'] + self.pvalue = context['param_value'] + self.name = "Type:%s,Name:%s,Value:%s" % ( + self.ptype, self.pname, self.pvalue) + self.id = self.name + + +class CreateNetworkServiceParamForm(forms.SelfHandlingForm): + param_type = forms.ChoiceField(label=_("Type"), + choices=[('ip_single', 'ip_single'), + ('ip_pool', 'ip_pool'), + ('string', 'string')]) + param_name = forms.CharField(max_length=80, label=_("Name")) + param_value = forms.CharField(max_length=80, label=_("Value"), + help_text=_("Enter a string. For Types 'ip_single' or 'ip_pool'," + "the Value is 'self_subnet' or 'external_subnet'." + "For Type 'string' the Value is a user-specified" + "string that matches the requirements published" + "by a Service Chain Spec.")) + + def handle(self, request, context): + return NetworkServiceParam(context) class UpdateServicePolicyForm(forms.SelfHandlingForm): @@ -224,14 +266,15 @@ class UpdateServicePolicyForm(forms.SelfHandlingForm): max_length=80, label=_("Description"), required=False) def __init__(self, request, *args, **kwargs): - super(UpdateL3PolicyForm, self).__init__(request, *args, **kwargs) + super(UpdateServicePolicyForm, self).__init__(request, *args, **kwargs) try: policy_id = self.initial['service_policy_id'] - policy = client.get_service_policy(request, policy_id) + policy = client.get_networkservice_policy(request, policy_id) self.fields['name'].initial = policy.name self.fields['description'].initial = policy.description - except Exception: - pass + except Exception as e: + msg = _("Failed to retrive service policy details. %s") % (str(e)) + LOG.debug(msg) def handle(self, request, context): url = reverse("horizon:project:network_policy:index") @@ -239,10 +282,10 @@ class UpdateServicePolicyForm(forms.SelfHandlingForm): policy_id = self.initial['service_policy_id'] client.update_networkservice_policy( request, policy_id, **context) - msg = _("Service policy created successfully!") + msg = _("Service policy updatedsuccessfully!") LOG.debug(msg) return http.HttpResponseRedirect(url) except Exception: - msg = _("Failed to create service policy") + msg = _("Failed to update service policy") LOG.error(msg) exceptions.handle(request, msg, redirect=shortcuts.redirect) diff --git a/gbpui/panels/network_policy/panel.py b/gbpui/panels/network_policy/panel.py index 8da9a2c..b5c5a55 100644 --- a/gbpui/panels/network_policy/panel.py +++ b/gbpui/panels/network_policy/panel.py @@ -9,8 +9,6 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -# -# @author: Ronak Shah from django.utils.translation import ugettext_lazy as _ diff --git a/gbpui/panels/network_policy/tables.py b/gbpui/panels/network_policy/tables.py index efe359d..5ca08aa 100644 --- a/gbpui/panels/network_policy/tables.py +++ b/gbpui/panels/network_policy/tables.py @@ -35,7 +35,7 @@ class EditL2PolicyLink(tables.LinkAction): class DeleteL2PolicyLink(tables.DeleteAction): - name = "delete_l2policy" + name = "deletel2policy" action_present = _("Delete") action_past = _("Scheduled deletion of %(data_type)s") data_type_singular = _("L2Policy") @@ -77,11 +77,11 @@ class EditL3PolicyLink(tables.LinkAction): class DeleteL3PolicyLink(tables.DeleteAction): - name = "delete_l3policy" + name = "deletel3policy" action_present = _("Delete") action_past = _("Scheduled deletion of %(data_type)s") - data_type_singular = _("L3Policy") - data_type_plural = _("L3Policies") + data_type_singular = _("L3 Policy") + data_type_plural = _("L3 Policies") class L3PolicyTable(tables.DataTable): @@ -121,7 +121,7 @@ class EditServicePolicyLink(tables.LinkAction): class DeleteServicePolicyLink(tables.DeleteAction): - name = "delete_service_policy" + name = "deletespolicy" action_present = _("Delete") action_past = _("Scheduled deletion of %(data_type)s") data_type_singular = _("ServicePolicy") @@ -129,8 +129,11 @@ class DeleteServicePolicyLink(tables.DeleteAction): class ServicePolicyTable(tables.DataTable): - name = tables.Column("name", verbose_name=_("Name")) + name = tables.Column("name", verbose_name=_("Name"), + link="horizon:project:network_policy:service_policy_details") description = tables.Column("description", verbose_name=_("Description")) + network_service_params = tables.Column('network_service_params', + verbose_name=_("Network Service Params")) class Meta: name = "service_policy_table" diff --git a/gbpui/panels/network_policy/tabs.py b/gbpui/panels/network_policy/tabs.py index c8331b1..1d3e5c6 100644 --- a/gbpui/panels/network_policy/tabs.py +++ b/gbpui/panels/network_policy/tabs.py @@ -9,8 +9,6 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -# -# @author: Ronak Shah from django.core.urlresolvers import reverse_lazy from django.utils.translation import ugettext_lazy as _ @@ -19,6 +17,7 @@ from horizon import exceptions from horizon import tabs from gbpui import client +from gbpui import column_filters as gfilters import tables @@ -27,7 +26,7 @@ class L3PolicyDetailsTab(tabs.Tab): name = _("L3 Policy Details") slug = "l3_policy_details" template_name = "project/endpoint_groups/_l3_policy_details.html" - failure_url = reverse_lazy('horizon:project:endpoint_group:index') + failure_url = reverse_lazy('horizon:project:network_policy:index') def get_context_data(self, request): l3policy_id = self.tab_group.kwargs['l3policy_id'] @@ -86,13 +85,37 @@ class ServicePolicyTab(tabs.TableTab): policies = [] try: policies = client.networkservicepolicy_list(self.request) + update = lambda x: gfilters.update_service_policy_attributes(x) + policies = [update(item) for item in policies] except Exception: - policies = [] exceptions.handle(self.tab_group.request, _('Unable to retrieve network service policy list.')) return policies +class ServicePolicyDetailsTab(tabs.Tab): + name = _("Service Policy Details") + slug = "service_policy_details" + template_name = "project/network_policy/_service_policy_details.html" + failure_url = reverse_lazy('horizon:project:network_policy:index') + + def get_context_data(self, request): + policy_id = self.tab_group.kwargs['service_policy_id'] + try: + policy = client.get_networkservice_policy(request, policy_id) + except Exception: + exceptions.handle( + request, _('Unable to retrieve service policy details.'), + redirect=self.failure_url) + return {'policy': policy} + + +class ServicePolicyDetailsTabs(tabs.TabGroup): + slug = "service_policy_details_tab" + tabs = (ServicePolicyDetailsTab,) + sticky = True + + class L3PolicyTabs(tabs.TabGroup): slug = "l3policy_tab" tabs = (L3PolicyTab, ServicePolicyTab,) @@ -109,6 +132,10 @@ class L2PolicyDetailsTab(tabs.Tab): l2policy_id = self.tab_group.kwargs['l2policy_id'] try: l2policy = client.l2policy_get(request, l2policy_id) + ptgs = [] + for item in l2policy.policy_target_groups: + ptgs.append(client.policy_target_get(request, item)) + setattr(l2policy, 'ptgs', ptgs) except Exception: exceptions.handle( request, _('Unable to retrieve l2 policy details.'), diff --git a/gbpui/panels/network_policy/templates/network_policy/_create_network_service_param.html b/gbpui/panels/network_policy/templates/network_policy/_create_network_service_param.html new file mode 100644 index 0000000..72b0af7 --- /dev/null +++ b/gbpui/panels/network_policy/templates/network_policy/_create_network_service_param.html @@ -0,0 +1,24 @@ +{% extends "horizon/common/_modal_form.html" %} +{% load i18n %} +{% load url from future %} + +{% block form_id %}add_network_service_param_form{% endblock %} +{% block form_action %}{% url 'horizon:project:network_policy:add_network_service_param' %}{% endblock %} + +{% block modal-header %}{% trans "Add Network Service Parameter" %}{% endblock %} + +{% block modal-body %} +
+
+ {% include "horizon/common/_form_fields.html" %} +
+
+
+

{% trans "Description:" %}

+
+{% endblock %} + +{% block modal-footer %} + + {% trans "Cancel" %} +{% endblock %} diff --git a/gbpui/panels/network_policy/templates/network_policy/_l2_policy_details.html b/gbpui/panels/network_policy/templates/network_policy/_l2_policy_details.html index 0581501..d1c337e 100644 --- a/gbpui/panels/network_policy/templates/network_policy/_l2_policy_details.html +++ b/gbpui/panels/network_policy/templates/network_policy/_l2_policy_details.html @@ -13,5 +13,17 @@
{% trans "ID" %}
{{ l2policy.id }}
+ {% if l2policy.ptgs %} +
+
Policy Target Groups
+
+ +
+
+ {% endif %}
diff --git a/gbpui/panels/network_policy/templates/network_policy/_service_policy_details.html b/gbpui/panels/network_policy/templates/network_policy/_service_policy_details.html new file mode 100644 index 0000000..447cb84 --- /dev/null +++ b/gbpui/panels/network_policy/templates/network_policy/_service_policy_details.html @@ -0,0 +1,19 @@ +{% load i18n sizeformat parse_date %} +{% load url from future %} + +
+
+
+
{% trans "Name" %}
+
{{ policy.name|default:_("-") }}
+ +
{% trans "Description" %}
+
{{ policy.description|default:_("-") }}
+ +
{% trans "ID" %}
+
{{ policy.id }}
+
{% trans "Network Service Params" %}
+
{{ policy.network_service_params }}
+
+
+ diff --git a/gbpui/panels/network_policy/templates/network_policy/_update_service_policy.html b/gbpui/panels/network_policy/templates/network_policy/_update_service_policy.html index 38ebe33..1156b27 100644 --- a/gbpui/panels/network_policy/templates/network_policy/_update_service_policy.html +++ b/gbpui/panels/network_policy/templates/network_policy/_update_service_policy.html @@ -20,6 +20,6 @@ {% endblock %} {% block modal-footer %} - + {% trans "Cancel" %} {% endblock %} diff --git a/gbpui/panels/network_policy/urls.py b/gbpui/panels/network_policy/urls.py index 5b0f25d..e1233a8 100644 --- a/gbpui/panels/network_policy/urls.py +++ b/gbpui/panels/network_policy/urls.py @@ -9,8 +9,6 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -# -# @author: Ronak Shah from django.conf.urls import patterns # noqa @@ -26,9 +24,15 @@ urlpatterns = patterns('', url(r'^addserviceolicy$', views.CreateServicePolicyView.as_view(), name='create_servicepolicy'), + url(r'^addnetworkserviceparam$', + views.AddNetworkServiceParamView.as_view(), + name='add_network_service_param'), url(r'^update_servicepolicy/(?P[^/]+)/$', views.UpdateServicePolicyView.as_view(), name='update_service_policy'), + url(r'^servicepolicy/(?P[^/]+)/$', + views.ServicePolicyDetailsView.as_view(), + name='service_policy_details'), url(r'^addl2policy$', views.AddL2policyView.as_view(), name='addl2policy'), diff --git a/gbpui/panels/network_policy/views.py b/gbpui/panels/network_policy/views.py index 4e5b7e7..2ef5bb4 100644 --- a/gbpui/panels/network_policy/views.py +++ b/gbpui/panels/network_policy/views.py @@ -9,8 +9,6 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -# -# @author: Ronak Shah import re @@ -36,16 +34,36 @@ class IndexView(tabs.TabView): def post(self, request, *args, **kwargs): obj_ids = request.POST.getlist('object_ids') action = request.POST['action'] + obj_type = re.search('delete([0-9a-z]+)', action).group(1) if not obj_ids: obj_ids.append(re.search('([0-9a-z-]+)$', action).group(1)) - for obj_id in obj_ids: - try: - client.epg_delete(request, obj_id) - messages.success(request, - _('Deleted EPG %s') % obj_id) - except Exception as e: - exceptions.handle(request, - _('Unable to delete EPG. %s') % e) + if obj_type == 'spolicy': + for obj_id in obj_ids: + try: + client.delete_networkservice_policy(request, obj_id) + messages.success(request, + _('Deleted service policy %s') % obj_id) + except Exception as e: + msg = _('Unable to delete action. %s') % (str(e)) + exceptions.handle(request, msg) + if obj_type == 'l3policy': + for obj_id in obj_ids: + try: + client.l3policy_delete(request, obj_id) + messages.success(request, + _('Deleted L3 policy %s') % obj_id) + except Exception as e: + msg = _('Unable to delete action. %s') % (str(e)) + exceptions.handle(request, msg) + if obj_type == 'l2policy': + for obj_id in obj_ids: + try: + client.l2policy_delete(request, obj_id) + messages.success(request, + _('Deleted L2 policy %s') % obj_id) + except Exception as e: + msg = _('Unable to delete action. %s') % (str(e)) + exceptions.handle(request, msg) return self.get(request, *args, **kwargs) @@ -136,15 +154,28 @@ class CreateServicePolicyView(forms.ModalFormView): return context +class AddNetworkServiceParamView(forms.ModalFormView): + form_class = np_forms.CreateNetworkServiceParamForm + template_name = "project/network_policy/create_network_service_param.html" + + def get_object_id(self, params): + return params.name + + class UpdateServicePolicyView(forms.ModalFormView): form_class = np_forms.UpdateServicePolicyForm template_name = "project/network_policy/update_service_policy.html" def get_context_data(self, **kwargs): context = super( - CreateServicePolicyView, self).get_context_data(**kwargs) + UpdateServicePolicyView, self).get_context_data(**kwargs) context['service_policy_id'] = self.kwargs['service_policy_id'] return context def get_initial(self): return self.kwargs + + +class ServicePolicyDetailsView(tabs.TabView): + tab_group_class = (np_tabs.ServicePolicyDetailsTabs) + template_name = 'project/network_policy/details_tabs.html' diff --git a/gbpui/panels/network_services/forms.py b/gbpui/panels/network_services/forms.py index a5913a0..814b5d2 100644 --- a/gbpui/panels/network_services/forms.py +++ b/gbpui/panels/network_services/forms.py @@ -1,6 +1,3 @@ -# Copyright 2010-2011 OpenStack Foundation -# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. -# # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at @@ -40,12 +37,25 @@ class CreateServiceChainNodeForm(forms.SelfHandlingForm): max_length=80, label=_("Description"), required=False) service_type = forms.ChoiceField( label=_("Service Type"), choices=SERVICE_TYPES) - template_file = forms.FileField(label=_('Template File'), - help_text=_( - 'A local template file to upload.'), - required=False) - template_string = forms.CharField(label=_("Template String"), - widget=forms.Textarea, required=False) + config_type = forms.ChoiceField(label=_("Config Type"), + choices=[('file', 'Heat Template'), + ('string', 'Config String')], + widget=forms.Select(attrs={'class': + 'switchable', + 'data-slug': 'source'})) + template_file = forms.FileField(label=_('Configuration File'), + help_text=_('A local Heat template file to upload.'), + required=False, + widget=forms.FileInput(attrs={'class': 'switched', + 'data-switch-on': 'source', + 'data-source-file': _("Configuration File")})) + template_string = forms.CharField(label=_("Configuration String"), + help_text=_('A local Heat template string.'), + widget=forms.Textarea(attrs={'class': 'switched', + 'data-switch-on': 'source', + 'data-source-string': + _("Configuration String")}), + required=False) def clean(self): cleaned_data = super(CreateServiceChainNodeForm, self).clean() @@ -79,6 +89,7 @@ class CreateServiceChainNodeForm(forms.SelfHandlingForm): try: del context['template_string'] del context['template_file'] + del context['config_type'] except KeyError: pass context['config'] = json.dumps(context['config']) @@ -121,7 +132,7 @@ class UpdateServiceChainNodeForm(forms.SelfHandlingForm): except Exception as e: msg = _("Failed to create Service Chain Node. %s") % (str(e)) LOG.error(msg) - exceptions.handle(request, msg, redirect=shortcuts.redirect) + exceptions.handle(request, msg, redirect=url) class CreateServiceChainSpecForm(forms.SelfHandlingForm): @@ -153,7 +164,7 @@ class CreateServiceChainSpecForm(forms.SelfHandlingForm): except Exception as e: msg = _("Failed to create Service Chain Spec. %s") % (str(e)) LOG.error(msg) - exceptions.handle(request, msg, redirect=shortcuts.redirect) + exceptions.handle(request, msg, redirect=url) class UpdateServiceChainSpecForm(CreateServiceChainSpecForm): diff --git a/gbpui/panels/network_services/panel.py b/gbpui/panels/network_services/panel.py index 04e126f..903ba90 100644 --- a/gbpui/panels/network_services/panel.py +++ b/gbpui/panels/network_services/panel.py @@ -9,8 +9,6 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -# -# @author: Ronak Shah from django.utils.translation import ugettext_lazy as _ diff --git a/gbpui/panels/network_services/tables.py b/gbpui/panels/network_services/tables.py index f3a2e16..cc97fe1 100644 --- a/gbpui/panels/network_services/tables.py +++ b/gbpui/panels/network_services/tables.py @@ -9,8 +9,6 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -# -# @author: Ronak Shah from django.core.urlresolvers import reverse from django.utils.translation import ugettext_lazy as _ @@ -37,11 +35,11 @@ class EditServiceChainSpecLink(tables.LinkAction): class DeleteServiceChainSpecLink(tables.DeleteAction): - name = "delete_servicechain_spec" + name = "deletescspec" action_present = _("Delete") action_past = _("Scheduled deletion of %(data_type)s") - data_type_singular = _("ServiceChainSpec") - data_type_plural = _("ServiceChainSpecs") + data_type_singular = _("Service Chain Spec") + data_type_plural = _("Service Chain Specs") class ServiceChainSpecTable(tables.DataTable): @@ -55,8 +53,10 @@ class ServiceChainSpecTable(tables.DataTable): class Meta: name = "service_chain_spec_table" verbose_name = _("Service Chain Specs") - table_actions = (CreateServiceChainSpecLink,) - row_actions = (EditServiceChainSpecLink, DeleteServiceChainSpecLink,) + table_actions = (CreateServiceChainSpecLink, + DeleteServiceChainSpecLink,) + row_actions = (EditServiceChainSpecLink, + DeleteServiceChainSpecLink,) class CreateServiceChainNodeLink(tables.LinkAction): @@ -78,11 +78,11 @@ class EditServiceChainNodeLink(tables.LinkAction): class DeleteServiceChainNodeLink(tables.DeleteAction): - name = "delete_servicechain_node" + name = "deletescnode" action_present = _("Delete") action_past = _("Scheduled deletion of %(data_type)s") - data_type_singular = _("ServiceChainNode") - data_type_plural = _("ServiceChainNodes") + data_type_singular = _("Service Chain Node") + data_type_plural = _("Service Chain Nodes") class ServiceChainNodeTable(tables.DataTable): @@ -97,8 +97,10 @@ class ServiceChainNodeTable(tables.DataTable): class Meta: name = "service_chain_node_table" verbose_name = _("Service Chain Node") - table_actions = (CreateServiceChainNodeLink,) - row_actions = (EditServiceChainNodeLink, DeleteServiceChainNodeLink,) + table_actions = (CreateServiceChainNodeLink, + DeleteServiceChainNodeLink,) + row_actions = (EditServiceChainNodeLink, + DeleteServiceChainNodeLink,) class CreateServiceChainInstanceLink(tables.LinkAction): @@ -120,7 +122,7 @@ class EditServiceChainInstanceLink(tables.LinkAction): class DeleteServiceChainInstanceLink(tables.DeleteAction): - name = "delete_servicechain_instance" + name = "deletescinstance" action_present = _("Delete") action_past = _("Scheduled deletion of %(data_type)s") data_type_singular = _("ServiceChainInstance") diff --git a/gbpui/panels/network_services/tabs.py b/gbpui/panels/network_services/tabs.py index 0ee89b6..01fcd44 100644 --- a/gbpui/panels/network_services/tabs.py +++ b/gbpui/panels/network_services/tabs.py @@ -9,8 +9,8 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -# -# @author: Ronak Shah + +import json from django.core.urlresolvers import reverse_lazy from django.utils.translation import ugettext_lazy as _ @@ -76,9 +76,7 @@ class ServiceChainInstanceTab(tabs.TableTab): class ServiceChainTabs(tabs.TabGroup): slug = "service_chain_spec_tabs" - tabs = (ServiceChainSpecTab, - ServiceChainNodeTab, - ServiceChainInstanceTab,) + tabs = (ServiceChainSpecTab, ServiceChainNodeTab,) sticky = True @@ -114,6 +112,13 @@ class ServiceChainSpecDetailsTab(tabs.Tab): scspec_id = self.tab_group.kwargs['scspec_id'] try: scspec = client.get_servicechain_spec(request, scspec_id) + nodes = [] + gn = lambda x, y: client.get_servicechain_node(x, y) + for node in scspec.nodes: + n = gn(self.request, node) + setattr(n, 'config', json.loads(n.config)) + nodes.append(n) + setattr(scspec, 'nodes', nodes) except Exception: exceptions.handle(request, _( 'Unable to retrieve service chain spec details.'), diff --git a/gbpui/panels/network_services/templates/network_services/_scnode_details.html b/gbpui/panels/network_services/templates/network_services/_scnode_details.html index d237c55..3a9fa12 100644 --- a/gbpui/panels/network_services/templates/network_services/_scnode_details.html +++ b/gbpui/panels/network_services/templates/network_services/_scnode_details.html @@ -12,5 +12,13 @@
{% trans "ID" %}
{{ scnode.id }}
+ +
{% trans "Service Type" %}
+
{{ scnode.service_type }}
+ +
{% trans "Config" %}
+
+ {{ scnode.config }} +
diff --git a/gbpui/panels/network_services/templates/network_services/_scspec_details.html b/gbpui/panels/network_services/templates/network_services/_scspec_details.html index 444733c..3d8839f 100644 --- a/gbpui/panels/network_services/templates/network_services/_scspec_details.html +++ b/gbpui/panels/network_services/templates/network_services/_scspec_details.html @@ -12,14 +12,33 @@
{% trans "ID" %}
{{ scspec.id }}
- -
{% trans "Nodes" %}
-
- -
+ {% if scspec.nodes %} +
+
Nodes
+
+ + + + + + + + + {% for node in scspec.nodes %} + + + + + + {% endfor %} +
NameService TypeConfig
+ + {{node.name}}:{{node.id}} + {{node.service_type}} + {{node.config}} +
+
+
+ {% endif %} diff --git a/gbpui/panels/network_services/urls.py b/gbpui/panels/network_services/urls.py index 00c041b..3d7ebb1 100644 --- a/gbpui/panels/network_services/urls.py +++ b/gbpui/panels/network_services/urls.py @@ -9,8 +9,6 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -# -# @author: Ronak Shah from django.conf.urls import patterns # noqa diff --git a/gbpui/panels/network_services/views.py b/gbpui/panels/network_services/views.py index 0a9fb1e..9de110a 100644 --- a/gbpui/panels/network_services/views.py +++ b/gbpui/panels/network_services/views.py @@ -9,18 +9,59 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. +import re +from django.utils.translation import ugettext_lazy as _ + +from horizon import exceptions from horizon import forms +from horizon import messages from horizon import tabs import forms as ns_forms import tabs as ns_tabs +from gbpui import client + class IndexView(tabs.TabView): tab_group_class = (ns_tabs.ServiceChainTabs) template_name = 'project/network_services/details_tabs.html' + def post(self, request, *args, **kwargs): + obj_ids = request.POST.getlist('object_ids') + action = request.POST['action'] + obj_type = re.search('delete([a-z]+)', action).group(1) + if not obj_ids: + obj_ids.append(re.search('([0-9a-z-]+)$', action).group(1)) + if obj_type == 'scnode': + for obj_id in obj_ids: + try: + client.delete_servicechain_node(request, obj_id) + messages.success(request, _('Deleted %s') % obj_id) + except Exception as e: + exceptions.handle(request, + _('Unable to delete . %s') % e) + if obj_type == 'scinstance': + for obj_id in obj_ids: + try: + client.delete_servicechain_instance(request, obj_id) + messages.success( + request, _('Deleted %s') % obj_id) + except Exception as e: + exceptions.handle(request, + _('Unable to delete . %s') % e) + if obj_type == 'scspec': + for obj_id in obj_ids: + try: + client.delete_servicechain_spec(request, obj_id) + messages.success(request, + _('Deleted %s') % obj_id) + except Exception as e: + exceptions.handle(request, + _('Unable to delete . %s') % e) + return self.get(request, *args, **kwargs) + class CreateServiceChainNodeView(forms.ModalFormView): form_class = ns_forms.CreateServiceChainNodeForm @@ -82,8 +123,8 @@ class ServiceChainSpecDetailsView(tabs.TabView): class CreateServiceChainInstanceView(forms.ModalFormView): form_class = ns_forms.CreateServiceChainInstanceForm - template_name = "project / network_services/"\ - "ceate_service_chain_instance.html" + template_name = "project/network_services/"\ + "create_service_chain_instance.html" def get_context_data(self, **kwargs): context = super( diff --git a/gbpui/panels/network_services/new.py b/gbpui/panels/policytargets/__init__.py similarity index 100% rename from gbpui/panels/network_services/new.py rename to gbpui/panels/policytargets/__init__.py diff --git a/gbpui/panels/policytargets/forms.py b/gbpui/panels/policytargets/forms.py new file mode 100644 index 0000000..bb92a6b --- /dev/null +++ b/gbpui/panels/policytargets/forms.py @@ -0,0 +1,305 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import logging + +from django.core.urlresolvers import reverse +from django import http +from django.utils.translation import ugettext_lazy as _ + +from horizon import exceptions +from horizon import forms +from horizon import messages + +from gbpui import client + +LOG = logging.getLogger(__name__) + + +class UpdatePolicyTargetForm(forms.SelfHandlingForm): + name = forms.CharField(max_length=80, + label=_("Name"), required=False) + description = forms.CharField(max_length=80, + label=_("Description"), required=False) + provided_policy_rule_sets = forms.MultipleChoiceField( + label=_("Provided Policy Rule Set"), required=False) + consumed_policy_rule_sets = forms.MultipleChoiceField( + label=_("Consumed Policy Rule Set"), required=False) + l2_policy_id = forms.ChoiceField( + label=_("Network Policy"), + required=False, + help_text=_("Select network policy for Group.")) + network_service_policy_id = forms.ChoiceField( + label=_("Network Services Policy"), + required=False, + help_text=_("Select network services policy for Group.")) + failure_url = 'horizon:project:policytargets:index' + + def __init__(self, request, *args, **kwargs): + super(UpdatePolicyTargetForm, self).__init__(request, *args, **kwargs) + try: + policy_target_id = self.initial['policy_target_id'] + policy_target = client.policy_target_get(request, policy_target_id) + tenant_id = self.request.user.tenant_id + policy_rule_sets = client.policy_rule_set_list( + request, tenant_id=tenant_id) + for c in policy_rule_sets: + c.set_id_as_name_if_empty() + policy_rule_sets = sorted( + policy_rule_sets, key=lambda rule: rule.name) + policy_rule_set_list = [(c.id, c.name) for c in policy_rule_sets] + self.fields[ + 'provided_policy_rule_sets'].choices = policy_rule_set_list + self.fields[ + 'consumed_policy_rule_sets'].choices = policy_rule_set_list + provided_init = [] + consumed_init = [] + for item in policy_rule_set_list: + if item[0] in policy_target.provided_policy_rule_sets: + provided_init.append(item[0]) + if item[0] in policy_target.consumed_policy_rule_sets: + consumed_init.append(item[0]) + self.fields['provided_policy_rule_sets'].initial = provided_init + self.fields['consumed_policy_rule_sets'].initial = consumed_init + n_policies = client.l2policy_list(request) + ns_policies = client.networkservicepolicy_list( + request, tenant_id=request.user.tenant_id) + n_policies = [(item.id, item.name) for item in n_policies] + ns_policies = [(item.id, item.name) for item in ns_policies] + ns_policies.insert(0, ('None', 'None')) + self.fields['l2_policy_id'].choices = n_policies + self.fields['network_service_policy_id'].choices = ns_policies + for i in ['name', + 'description', + 'l2_policy_id', + 'network_service_policy_id']: + self.fields[i].initial = getattr(policy_target, i) + except Exception as e: + msg = _('Unable to retrieve policy_rule_set details. %s') % ( + str(e)) + exceptions.handle(request, msg) + pass + + def handle(self, request, context): + policy_target_id = self.initial['policy_target_id'] + name_or_id = context.get('name') or policy_target_id + try: + context['provided_policy_rule_sets'] = dict( + [(i, 'string') for i in context['provided_policy_rule_sets']]) + context['consumed_policy_rule_sets'] = dict( + [(i, 'string') for i in context['consumed_policy_rule_sets']]) + if context['network_service_policy_id'] == 'None': + context['network_service_policy_id'] = None + policy_target = client.policy_target_update( + request, policy_target_id, **context) + msg = _('Group %s was successfully updated.') % name_or_id + LOG.debug(msg) + messages.success(request, msg) + return policy_target + except Exception as e: + msg = _('Failed to update Group %(name)s. %(reason)s') % {'name': + name_or_id, 'reason': str(e)} + LOG.error(msg) + redirect = reverse(self.failure_url) + exceptions.handle(request, msg, redirect=redirect) + + +class AddProvidedPRSForm(forms.SelfHandlingForm): + policy_rule_set = forms.MultipleChoiceField( + label=_("Provided Policy Rule Sets"),) + + def __init__(self, request, *args, **kwargs): + super(AddProvidedPRSForm, self).__init__(request, *args, **kwargs) + policy_rule_sets = [] + try: + tenant_id = self.request.user.tenant_id + policy_target_id = kwargs['initial']['policy_target_id'] + policy_target = client.policy_target_get(request, policy_target_id) + providedpolicy_rule_sets = policy_target.get( + "provided_policy_rule_sets") + items = client.policy_rule_set_list(request, tenant_id=tenant_id) + policy_rule_sets = [ + (p.id, p.name) for p in items + if p.id not in providedpolicy_rule_sets] + except Exception as e: + msg = _('Unable to retrieve policy rule set list.') % (str(e)) + LOG.debug(msg) + self.fields['policy_rule_set'].choices = policy_rule_sets + + def handle(self, request, context): + policy_target_id = self.initial['policy_target_id'] + policy_target = client.policy_target_get(request, policy_target_id) + url = reverse("horizon:project:policytargets:policy_targetdetails", + kwargs={'policy_target_id': policy_target_id}) + try: + for policy_rule_set in policy_target.get( + "provided_policy_rule_sets"): + context['policy_rule_set'].append(policy_rule_set) + policy_rule_sets = dict([(item, 'string') + for item in context['policy_rule_set']]) + client.policy_target_update( + request, policy_target_id, + provided_policy_rule_sets=policy_rule_sets) + msg = _('Policy Rule Set added successfully!') + messages.success(request, msg) + LOG.debug(msg) + return http.HttpResponseRedirect(url) + except Exception: + u = "horizon:project:policytargets:policy_targetdetails" + msg = _('Failed to add policy_rule_set!') + redirect = reverse(u, kwargs={'policy_target_id': + policy_target_id}) + LOG.error(msg) + exceptions.handle(request, msg, redirect=redirect) + + +class RemoveProvidedPRSForm(forms.SelfHandlingForm): + policy_rule_set = forms.MultipleChoiceField( + label=_("Provided Policy Rule Sets"),) + + def __init__(self, request, *args, **kwargs): + super(RemoveProvidedPRSForm, self).__init__(request, *args, **kwargs) + policy_rule_sets = [] + try: + tenant_id = self.request.user.tenant_id + policy_target_id = kwargs['initial']['policy_target_id'] + policy_target = client.policy_target_get(request, policy_target_id) + providedpolicy_rule_sets = policy_target.get( + "provided_policy_rule_sets") + items = client.policy_rule_set_list(request, tenant_id=tenant_id) + policy_rule_sets = [(p.id, p.name) + for p in items if p.id in + providedpolicy_rule_sets] + except Exception as e: + msg = _('Unable to retrieve policy rule set list.') % (str(e)) + LOG.debug(msg) + self.fields['policy_rule_set'].choices = policy_rule_sets + + def handle(self, request, context): + policy_target_id = self.initial['policy_target_id'] + url = reverse("horizon:project:policytargets:policy_targetdetails", + kwargs={'policy_target_id': policy_target_id}) + try: + policy_target = client.policy_target_get(request, policy_target_id) + old_policy_rule_sets = policy_target.get( + "provided_policy_rule_sets") + for policy_rule_set in context['policy_rule_set']: + old_policy_rule_sets.remove(policy_rule_set) + policy_rule_sets = dict([(item, 'string') + for item in old_policy_rule_sets]) + client.policy_target_update( + request, policy_target_id, + provided_policy_rule_sets=policy_rule_sets) + msg = _('Policy Rule Set removed successfully!') + messages.success(request, msg) + LOG.debug(msg) + return http.HttpResponseRedirect(url) + except Exception: + msg = _('Failed to remove policy_rule_set!') + u = "horizon:project:policytargets:policy_targetdetails" + redirect = reverse(u, + kwargs={'policy_target_id': policy_target_id}) + LOG.error(msg) + exceptions.handle(request, msg, redirect=redirect) + + +class AddConsumedPRSForm(forms.SelfHandlingForm): + policy_rule_set = forms.MultipleChoiceField( + label=_("Consumed Policy Rule Sets"),) + + def __init__(self, request, *args, **kwargs): + super(AddConsumedPRSForm, self).__init__(request, *args, **kwargs) + policy_rule_sets = [] + try: + tenant_id = self.request.user.tenant_id + policy_target_id = kwargs['initial']['policy_target_id'] + policy_target = client.policy_target_get(request, policy_target_id) + consumedpolicy_rule_sets = policy_target.get( + "consumed_policy_rule_sets") + items = client.policy_rule_set_list(request, tenant_id=tenant_id) + policy_rule_sets = [ + (p.id, p.name) for p in items + if p.id not in consumedpolicy_rule_sets] + except Exception: + pass + self.fields['policy_rule_set'].choices = policy_rule_sets + + def handle(self, request, context): + policy_target_id = self.initial['policy_target_id'] + url = reverse("horizon:project:policytargets:policy_targetdetails", + kwargs={'policy_target_id': policy_target_id}) + try: + policy_target = client.policy_target_get(request, policy_target_id) + for policy_rule_set in policy_target.get( + "consumed_policy_rule_sets"): + context['policy_rule_set'].append(policy_rule_set) + consumed = dict([(item, 'string') + for item in context['policy_rule_set']]) + client.policy_target_update( + request, policy_target_id, consumed_policy_rule_sets=consumed) + msg = _('Policy Rule Set Added successfully!') + messages.success(request, msg) + LOG.debug(msg) + return http.HttpResponseRedirect(url) + except Exception: + msg = _('Failed to add policy_rule_set!') + u = "horizon:project:policytargets:policy_targetdetails" + redirect = reverse(u, + kwargs={'policy_target_id': policy_target_id}) + LOG.error(msg) + exceptions.handle(request, msg, redirect=redirect) + + +class RemoveConsumedPRSForm(forms.SelfHandlingForm): + policy_rule_set = forms.MultipleChoiceField( + label=_("Consumed Policy Rule Sets"),) + + def __init__(self, request, *args, **kwargs): + super(RemoveConsumedPRSForm, self).__init__(request, *args, **kwargs) + policy_rule_sets = [] + try: + tenant_id = self.request.user.tenant_id + policy_target_id = kwargs['initial']['policy_target_id'] + policy_target = client.policy_target_get(request, policy_target_id) + consumedpolicy_rule_sets = policy_target.get( + "consumed_policy_rule_sets") + items = client.policy_rule_set_list(request, tenant_id=tenant_id) + policy_rule_sets = [(p.id, p.name) + for p in items if p.id + in consumedpolicy_rule_sets] + except Exception: + pass + self.fields['policy_rule_set'].choices = policy_rule_sets + + def handle(self, request, context): + policy_target_id = self.initial['policy_target_id'] + url = reverse("horizon:project:policytargets:policy_targetdetails", + kwargs={'policy_target_id': policy_target_id}) + try: + policy_target = client.policy_target_get(request, policy_target_id) + old_policy_rule_sets = policy_target.get( + "consumed_policy_rule_sets") + for policy_rule_set in context['policy_rule_set']: + old_policy_rule_sets.remove(policy_rule_set) + consumed = dict([(item, 'string') + for item in old_policy_rule_sets]) + client.policy_target_update( + request, policy_target_id, consumed_policy_rule_sets=consumed) + msg = _('Policy Rule Set removed successfully!') + messages.success(request, msg) + LOG.debug(msg) + return http.HttpResponseRedirect(url) + except Exception: + msg = _('Failed to remove policy_rule_set!') + redirect = url + LOG.error(msg) + exceptions.handle(request, msg, redirect=redirect) diff --git a/gbpui/panels/policytargets/panel.py b/gbpui/panels/policytargets/panel.py new file mode 100644 index 0000000..e8ca397 --- /dev/null +++ b/gbpui/panels/policytargets/panel.py @@ -0,0 +1,20 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from django.utils.translation import ugettext_lazy as _ + +import horizon + + +class PolicyTargetGroup(horizon.Panel): + name = _("Groups") + slug = "policytargets" diff --git a/gbpui/panels/policytargets/tables.py b/gbpui/panels/policytargets/tables.py new file mode 100644 index 0000000..fb55e6d --- /dev/null +++ b/gbpui/panels/policytargets/tables.py @@ -0,0 +1,224 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +import logging + +from django.core.urlresolvers import reverse +from django import http +from django import shortcuts +from django.utils.translation import ugettext_lazy as _ + +from horizon import exceptions +from horizon import tables + +from openstack_dashboard import api +from openstack_dashboard.dashboards.project.instances import tables as itables +from openstack_dashboard.dashboards.project.instances import tabs + +LOG = logging.getLogger(__name__) + + +class UpdatePTGLink(tables.LinkAction): + name = "updatepolicy_target" + verbose_name = _("Edit") + classes = ("ajax-modal", "btn-update",) + + def get_link_url(self, policy_target): + u = "horizon:project:policytargets:updatepolicy_target" + base_url = reverse(u, kwargs={'policy_target_id': policy_target.id}) + return base_url + + +class DeletePTGLink(tables.DeleteAction): + name = "deletepolicy_target" + action_present = _("Delete") + action_past = _("Scheduled deletion of %(data_type)s") + data_type_singular = _("Group") + data_type_plural = _("Groups") + + +class AddPTGLink(tables.LinkAction): + name = "addpolicy_target" + verbose_name = _("Create Group") + url = "horizon:project:policytargets:addpolicy_target" + classes = ("ajax-modal", "btn-addpolicy_target",) + + +class PTGsTable(tables.DataTable): + name = tables.Column("name", + verbose_name=_("Name"), + link="horizon:project:policytargets:policy_targetdetails") + description = tables.Column("description", verbose_name=_("Description")) + provided_policy_rule_sets = tables.Column("provided_policy_rule_sets", + sortable=False, + verbose_name=_("Provided Rule Sets")) + consumed_policy_rule_sets = tables.Column("consumed_policy_rule_sets", + sortable=False, + verbose_name=_("Consumed Rule Sets")) + l2_policy_id = tables.Column("l2_policy_id", + verbose_name=_("L2 Policy")) + + class Meta: + name = "policy_targetstable" + verbose_name = _("Groups") + table_actions = (AddPTGLink, DeletePTGLink) + row_actions = (UpdatePTGLink, DeletePTGLink) + + +class LaunchVMLink(tables.LinkAction): + name = "launch_vm" + verbose_name = _("Create Member") + classes = ("ajax-modal", "btn-addvm",) + + def get_link_url(self): + return reverse("horizon:project:policytargets:addvm", + kwargs={'policy_target_id': + self.table.kwargs['policy_target_id']}) + + +class RemoveVMLink(tables.DeleteAction): + data_type_singular = _("Instance") + data_type_plural = _("Instances") + + def delete(self, request, instance_id): + url = reverse("horizon:project:policytargets:policy_targetdetails", + kwargs={'policy_target_id': + self.table.kwargs['policy_target_id']}) + try: + api.nova.server_delete(request, instance_id) + LOG.debug('Deleted instance %s successfully' % instance_id) + return http.HttpResponseRedirect(url) + except Exception: + msg = _('Failed to delete instance %s') % instance_id + LOG.info(msg) + exceptions.handle(request, msg, redirect=shortcuts.redirect) + + +class ConsoleLink(tables.LinkAction): + name = "console" + verbose_name = _("Console") + url = "horizon:project:instances:detail" + classes = ("btn-console",) + policy_rules = (("compute", "compute_extension:consoles"),) + + def get_policy_target(self, request, datum=None): + project_id = None + if datum: + project_id = getattr(datum, 'tenant_id', None) + return {"project_id": project_id} + + def allowed(self, request, instance=None): + # We check if ConsoleLink is allowed only if settings.CONSOLE_TYPE is + # not set at all, or if it's set to any value other than None or False. + # return bool(getattr(settings, 'CONSOLE_TYPE', True)) and + # instance.status in ACTIVE_STATES and not is_deleting(instance) + return True + + def get_link_url(self, datum): + base_url = super(ConsoleLink, self).get_link_url(datum) + tab_query_string = tabs.ConsoleTab( + tabs.InstanceDetailTabs).get_query_string() + return "?".join([base_url, tab_query_string]) + + +class InstancesTable(tables.DataTable): + name = tables.Column("name", + link="horizon:project:instances:detail", + verbose_name=_("Instance Name")) + image_name = tables.Column("image_name", verbose_name=_("Image Name")) + status = tables.Column("status", verbose_name=_("Status")) + ip = tables.Column( + itables.get_ips, verbose_name=_("IP Address"), + attrs={'data-type': "ip"}) + + def get_empty_message(self, *args, **kwargs): + return "No members in this group, create one" + + class Meta: + name = "instances" + verbose_name = _("Members") + table_actions = (LaunchVMLink,) + row_actions = (ConsoleLink, RemoveVMLink,) + + +class AddProvidedLink(tables.LinkAction): + name = "add_policy_rule_set" + verbose_name = _("Add Policy Rule Set") + classes = ("ajax-modal", "btn-addvm",) + + def get_link_url(self): + return reverse("horizon:project:policytargets:add_provided_prs", + kwargs={'policy_target_id': + self.table.kwargs['policy_target_id']}) + + +class RemoveProvidedLink(tables.LinkAction): + name = "remove_policy_rule_set" + verbose_name = _("Remove Policy Rule Set") + classes = ("ajax-modal", "btn-addvm",) + + def get_link_url(self): + return reverse("horizon:project:policytargets:remove_provided_prs", + kwargs={'policy_target_id': + self.table.kwargs['policy_target_id']}) + + +class ProvidedContractsTable(tables.DataTable): + name = tables.Column("name", + link="horizon:project:application_policy:policy_rule_set_details", + verbose_name=_("Name")) + description = tables.Column("description", verbose_name=_("Description")) + policy_rules = tables.Column("policy_rules", + sortable=False, + verbose_name=_("Policy Rules")) + + class Meta: + name = 'provided_policy_rule_sets' + verbose_name = _("Provided Policy Rule Set") + table_actions = (AddProvidedLink, RemoveProvidedLink,) + + +class AddConsumedLink(tables.LinkAction): + name = "add_consumed" + verbose_name = _("Add Consumed Policy Rule Set") + classes = ("ajax-modal", "btn-addvm",) + + def get_link_url(self): + return reverse("horizon:project:policytargets:add_consumed_prs", + kwargs={'policy_target_id': + self.table.kwargs['policy_target_id']}) + + +class RemoveConsumedLink(tables.LinkAction): + name = "remove_consumed" + verbose_name = _("Remove Consumed Policy Rule Set") + classes = ("ajax-modal", "btn-addvm",) + + def get_link_url(self): + return reverse("horizon:project:policytargets:remove_consumed_prs", + kwargs={'policy_target_id': + self.table.kwargs['policy_target_id']}) + + +class ConsumedContractsTable(tables.DataTable): + name = tables.Column("name", + link="horizon:project:application_policy:policy_rule_set_details", + verbose_name=_("Name")) + description = tables.Column("description", + verbose_name=_("Description")) + policy_rules = tables.Column("policy_rules", + sortable=False, + verbose_name=_("Policy Rules")) + + class Meta: + name = 'consumed_policy_rule_sets' + verbose_name = _("Consumed Policy Rule Set") + table_actions = (AddConsumedLink, RemoveConsumedLink,) diff --git a/gbpui/panels/policytargets/tabs.py b/gbpui/panels/policytargets/tabs.py new file mode 100644 index 0000000..dfbe151 --- /dev/null +++ b/gbpui/panels/policytargets/tabs.py @@ -0,0 +1,176 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from django.core.urlresolvers import reverse_lazy +from django.utils.translation import ugettext_lazy as _ + +from horizon import exceptions +from horizon import tabs + +from openstack_dashboard import api +from openstack_dashboard.dashboards.project.instances import tables as itables + +from gbpui import client +from gbpui import column_filters as gfilters + +import tables + +PTGsTable = tables.PTGsTable + + +class PTGsTab(tabs.TableTab): + table_classes = (PTGsTable,) + name = _("Groups") + slug = "policytargets" + template_name = "horizon/common/_detail_table.html" + + def get_policy_targetstable_data(self): + policy_targets = [] + try: + tenant_id = self.request.user.tenant_id + policy_targets = client.policy_target_list(self.tab_group.request, + tenant_id=tenant_id) + a = lambda x, y: gfilters.update_policy_target_attributes(x, y) + policy_targets = [a(self.request, item) for item in policy_targets] + except Exception as e: + msg = _('Unable to retrieve policy_target list. %s') % (str(e)) + exceptions.handle(self.tab_group.request, msg) + for policy_target in policy_targets: + policy_target.set_id_as_name_if_empty() + return policy_targets + + +class PTGTabs(tabs.TabGroup): + slug = "policy_targettabs" + tabs = (PTGsTab,) + sticky = True + + +class PTGDetailsTab(tabs.Tab): + name = _("Group Details") + slug = "policy_targetdetails" + template_name = "project/policytargets/_policy_target_details.html" + failure_url = reverse_lazy('horizon:project:policy_target_group:index') + + def get_context_data(self, request): + policy_targetid = self.tab_group.kwargs['policy_target_id'] + try: + policy_target = client.policy_target_get(request, policy_targetid) + l3list = client.l3policy_list(request) + l2list = client.l2policy_list(request) + l2list = [ + item for item in l2list + if item.id == policy_target.l2_policy_id] + except Exception: + exceptions.handle( + request, _('Unable to retrieve group details.'), + redirect=self.failure_url) + return {'policy_target': policy_target, + 'l3list': l3list, + 'l2list': l2list} + + +class PTGDetailsTabs(tabs.TabGroup): + slug = "policy_targettabs" + tabs = (PTGDetailsTab,) + + +class InstancesTab(tabs.TableTab): + name = _("Members") + slug = "members_tab" + table_classes = (tables.InstancesTable,) + template_name = ("horizon/common/_detail_table.html") + preload = True + + def get_instances_data(self): + policy_targetid = self.tab_group.kwargs['policy_target_id'] + filtered_instances = [] + try: + policytargets = client.pt_list(self.request, + policy_target_group_id=policy_targetid) + policy_target_ports = [x.port_id for x in policytargets] + marker = self.request.GET.get( + tables.InstancesTable._meta.pagination_param, None) + instances, self._has_more = api.nova.server_list( + self.request, search_opts={'marker': marker, 'paginate': True}) + instances = [item for item in instances + if not itables.is_deleting(item)] + for item in instances: + for port in api.neutron.port_list(self.request, + device_id=item.id): + if port.id in policy_target_ports: + filtered_instances.append(item) + break + except Exception: + self._has_more = False + error_message = _('Unable to get instances') + exceptions.handle(self.request, error_message) + filtered_instances = [] + return filtered_instances + + +class ConsumedTab(tabs.TableTab): + name = _('Consumed Policy Rule Set') + slug = 'consumed_policy_rule_sets_tab' + table_classes = (tables.ConsumedContractsTable,) + template_name = ("horizon/common/_detail_table.html") + + def get_consumed_policy_rule_sets_data(self): + try: + policy_targetid = self.tab_group.kwargs['policy_target_id'] + policy_target = client.policy_target_get( + self.request, policy_targetid) + consumed_policy_rule_set_ids = policy_target.get( + 'consumed_policy_rule_sets') + consumed_policy_rule_sets = [] + for _id in consumed_policy_rule_set_ids: + consumed_policy_rule_sets.append( + client.policy_rule_set_get(self.request, _id)) + consumed_policy_rule_sets = [gfilters.update_pruleset_attributes( + self.request, item) for item in consumed_policy_rule_sets] + return consumed_policy_rule_sets + except Exception: + error_message = _('Unable to get consumed rule sets') + exceptions.handle(self.request, error_message) + return [] + + +class ProvidedTab(tabs.TableTab): + name = _('Provided Policy Rule Set') + slug = 'provided_policy_rule_sets_tab' + table_classes = (tables.ProvidedContractsTable,) + template_name = ("horizon/common/_detail_table.html") + + def get_provided_policy_rule_sets_data(self): + try: + policy_targetid = self.tab_group.kwargs['policy_target_id'] + policy_target = client.policy_target_get( + self.request, policy_targetid) + provided_policy_rule_set_ids = policy_target.get( + 'provided_policy_rule_sets') + provided_policy_rule_sets = [] + for _id in provided_policy_rule_set_ids: + provided_policy_rule_sets.append( + client.policy_rule_set_get(self.request, _id)) + provided_policy_rule_sets = [gfilters.update_pruleset_attributes( + self.request, item) for item in provided_policy_rule_sets] + return provided_policy_rule_sets + except Exception: + error_message = _('Unable to get provided rule sets') + exceptions.handle(self.request, error_message) + return [] + + +class PTGMemberTabs(tabs.TabGroup): + slug = 'member_tabs' + tabs = (InstancesTab, ProvidedTab, ConsumedTab, PTGDetailsTab,) + stiky = True diff --git a/gbpui/panels/policytargets/templates/policytargets/_add_consumed.html b/gbpui/panels/policytargets/templates/policytargets/_add_consumed.html new file mode 100644 index 0000000..1e793ae --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/_add_consumed.html @@ -0,0 +1,25 @@ +{% extends "horizon/common/_modal_form.html" %} +{% load i18n %} +{% load url from future %} + +{% block form_id %}add_consumed_form{% endblock %} +{% block form_action %}{% url 'horizon:project:policytargets:add_consumed' policy_target_id %}{% endblock %} + +{% block modal-header %}{% trans "Add " %}{% endblock %} + +{% block modal-body %} +
+
+ {% include "horizon/common/_form_fields.html" %} +
+
+
+

{% trans "Description:" %}

+

{% trans "Add Consumed Policy Rule Set. Press Ctrl to select multiple items." %}

+
+{% endblock %} + +{% block modal-footer %} + + {% trans "Cancel" %} +{% endblock %} diff --git a/gbpui/panels/policytargets/templates/policytargets/_add_consumed_prs.html b/gbpui/panels/policytargets/templates/policytargets/_add_consumed_prs.html new file mode 100644 index 0000000..9728072 --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/_add_consumed_prs.html @@ -0,0 +1,25 @@ +{% extends "horizon/common/_modal_form.html" %} +{% load i18n %} +{% load url from future %} + +{% block form_id %}add_consumed_form{% endblock %} +{% block form_action %}{% url 'horizon:project:policytargets:add_consumed_prs' policy_target_id %}{% endblock %} + +{% block modal-header %}{% trans "Add " %}{% endblock %} + +{% block modal-body %} +
+
+ {% include "horizon/common/_form_fields.html" %} +
+
+
+

{% trans "Description:" %}

+

{% trans "Add Consumed Policy Rule Set. Press Ctrl to select multiple items." %}

+
+{% endblock %} + +{% block modal-footer %} + + {% trans "Cancel" %} +{% endblock %} diff --git a/gbpui/panels/policytargets/templates/policytargets/_add_contract.html b/gbpui/panels/policytargets/templates/policytargets/_add_contract.html new file mode 100644 index 0000000..b8cfd15 --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/_add_contract.html @@ -0,0 +1,25 @@ +{% extends "horizon/common/_modal_form.html" %} +{% load i18n %} +{% load url from future %} + +{% block form_id %}add_contract_form{% endblock %} +{% block form_action %}{% url 'horizon:project:policytargets:add_contract' policy_target_id %}{% endblock %} + +{% block modal-header %}{% trans "Add Policy Rule Set" %}{% endblock %} + +{% block modal-body %} +
+
+ {% include "horizon/common/_form_fields.html" %} +
+
+
+

{% trans "Description:" %}

+

{% trans "Add Policy Rule Set. Press Ctrl to select multiple items." %}

+
+{% endblock %} + +{% block modal-footer %} + + {% trans "Cancel" %} +{% endblock %} diff --git a/gbpui/panels/policytargets/templates/policytargets/_add_l3policy.html b/gbpui/panels/policytargets/templates/policytargets/_add_l3policy.html new file mode 100644 index 0000000..163e822 --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/_add_l3policy.html @@ -0,0 +1,25 @@ +{% extends "horizon/common/_modal_form.html" %} +{% load i18n %} +{% load url from future %} + +{% block form_id %}add_l3policy_form{% endblock %} +{% block form_action %}{% url 'horizon:project:policytargets:addl3policy' %}{% endblock %} + +{% block modal-header %}{% trans "Add L3Policy" %}{% endblock %} + +{% block modal-body %} +
+
+ {% include "horizon/common/_form_fields.html" %} +
+
+
+

{% trans "Description:" %}

+

{% trans "Add L3 Policy." %}

+
+{% endblock %} + +{% block modal-footer %} + + {% trans "Cancel" %} +{% endblock %} diff --git a/gbpui/panels/policytargets/templates/policytargets/_add_policy_rule_set.html b/gbpui/panels/policytargets/templates/policytargets/_add_policy_rule_set.html new file mode 100644 index 0000000..a656f07 --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/_add_policy_rule_set.html @@ -0,0 +1,25 @@ +{% extends "horizon/common/_modal_form.html" %} +{% load i18n %} +{% load url from future %} + +{% block form_id %}add_contract_form{% endblock %} +{% block form_action %}{% url 'horizon:project:policytargets:add_policy_rule_set' policy_target_id %}{% endblock %} + +{% block modal-header %}{% trans "Add Policy Rule Set" %}{% endblock %} + +{% block modal-body %} +
+
+ {% include "horizon/common/_form_fields.html" %} +
+
+
+

{% trans "Description:" %}

+

{% trans "Add Policy Rule Set. Press Ctrl to select multiple items." %}

+
+{% endblock %} + +{% block modal-footer %} + + {% trans "Cancel" %} +{% endblock %} diff --git a/gbpui/panels/policytargets/templates/policytargets/_add_provided_prs.html b/gbpui/panels/policytargets/templates/policytargets/_add_provided_prs.html new file mode 100644 index 0000000..4643c41 --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/_add_provided_prs.html @@ -0,0 +1,25 @@ +{% extends "horizon/common/_modal_form.html" %} +{% load i18n %} +{% load url from future %} + +{% block form_id %}add_consumed_form{% endblock %} +{% block form_action %}{% url 'horizon:project:policytargets:add_provided_prs' policy_target_id %}{% endblock %} + +{% block modal-header %}{% trans "Add Provided PRS" %}{% endblock %} + +{% block modal-body %} +
+
+ {% include "horizon/common/_form_fields.html" %} +
+
+
+

{% trans "Description:" %}

+

{% trans "Add Consumed Policy Rule Set. Press Ctrl to select multiple items." %}

+
+{% endblock %} + +{% block modal-footer %} + + {% trans "Cancel" %} +{% endblock %} diff --git a/gbpui/panels/policytargets/templates/policytargets/_add_vm.html b/gbpui/panels/policytargets/templates/policytargets/_add_vm.html new file mode 100644 index 0000000..fa5cbb0 --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/_add_vm.html @@ -0,0 +1,25 @@ +{% extends "horizon/common/_modal_form.html" %} +{% load i18n %} +{% load url from future %} + +{% block form_id %}add_vm_form{% endblock %} +{% block form_action %}{% url 'horizon:project:policytargets:addvm' policy_target_id %}{% endblock %} + +{% block modal-header %}{% trans "Launch Instance" %}{% endblock %} + +{% block modal-body %} +
+
+ {% include "horizon/common/_form_fields.html" %} +
+
+
+

{% trans "Description:" %}

+

{% trans "Launch instance here." %}

+
+{% endblock %} + +{% block modal-footer %} + + {% trans "Cancel" %} +{% endblock %} diff --git a/gbpui/panels/policytargets/templates/policytargets/_del_vm.html b/gbpui/panels/policytargets/templates/policytargets/_del_vm.html new file mode 100644 index 0000000..fa5cbb0 --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/_del_vm.html @@ -0,0 +1,25 @@ +{% extends "horizon/common/_modal_form.html" %} +{% load i18n %} +{% load url from future %} + +{% block form_id %}add_vm_form{% endblock %} +{% block form_action %}{% url 'horizon:project:policytargets:addvm' policy_target_id %}{% endblock %} + +{% block modal-header %}{% trans "Launch Instance" %}{% endblock %} + +{% block modal-body %} +
+
+ {% include "horizon/common/_form_fields.html" %} +
+
+
+

{% trans "Description:" %}

+

{% trans "Launch instance here." %}

+
+{% endblock %} + +{% block modal-footer %} + + {% trans "Cancel" %} +{% endblock %} diff --git a/gbpui/panels/policytargets/templates/policytargets/_l3_policy_details.html b/gbpui/panels/policytargets/templates/policytargets/_l3_policy_details.html new file mode 100644 index 0000000..2d122d7 --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/_l3_policy_details.html @@ -0,0 +1,17 @@ +{% load i18n sizeformat parse_date %} +{% load url from future %} + +
+
+
+
{% trans "Name" %}
+
{{ l3policy.name|default:_("-") }}
+ +
{% trans "Description" %}
+
{{ l3policy.description|default:_("-") }}
+ +
{% trans "ID" %}
+
{{ l3policy.id }}
+
+
+ diff --git a/gbpui/panels/policytargets/templates/policytargets/_policy_target_details.html b/gbpui/panels/policytargets/templates/policytargets/_policy_target_details.html new file mode 100644 index 0000000..7adda46 --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/_policy_target_details.html @@ -0,0 +1,45 @@ +{% load i18n sizeformat parse_date %} +{% load url from future %} + +
+
+
+
{% trans "Name" %}
+
{{ policy_target.name|default:_("-") }}
+ +
{% trans "Description" %}
+
{{ policy_target.description|default:_("-") }}
+ +
{% trans "ID" %}
+
{{ policy_target.id }}
+ +
{% trans "Project ID" %}
+
{{ policy_target.tenant_id }}
+
+ {% if l3list %} +
+
{% trans "L3 Policies" %}
+
+ +
+
+ {% endif %} + {% if l2list %} +
+
{% trans "L2 Policies" %}
+
+ +
+
+ {% endif %} +
+ diff --git a/gbpui/panels/policytargets/templates/policytargets/_remove_consumed.html b/gbpui/panels/policytargets/templates/policytargets/_remove_consumed.html new file mode 100644 index 0000000..65a074e --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/_remove_consumed.html @@ -0,0 +1,25 @@ +{% extends "horizon/common/_modal_form.html" %} +{% load i18n %} +{% load url from future %} + +{% block form_id %}remove_contract_form{% endblock %} +{% block form_action %}{% url 'horizon:project:policytargets:remove_consumed' policy_target_id %}{% endblock %} + +{% block modal-header %}{% trans "Remove Policy Rule Set" %}{% endblock %} + +{% block modal-body %} +
+
+ {% include "horizon/common/_form_fields.html" %} +
+
+
+

{% trans "Description:" %}

+

{% trans "Remove Consumed Policy Rule Set. Press Ctrl to select multiple items." %}

+
+{% endblock %} + +{% block modal-footer %} + + {% trans "Cancel" %} +{% endblock %} diff --git a/gbpui/panels/policytargets/templates/policytargets/_remove_consumed_prs.html b/gbpui/panels/policytargets/templates/policytargets/_remove_consumed_prs.html new file mode 100644 index 0000000..f62d1bd --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/_remove_consumed_prs.html @@ -0,0 +1,25 @@ +{% extends "horizon/common/_modal_form.html" %} +{% load i18n %} +{% load url from future %} + +{% block form_id %}remove_contract_form{% endblock %} +{% block form_action %}{% url 'horizon:project:policytargets:remove_consumed_prs' policy_target_id %}{% endblock %} + +{% block modal-header %}{% trans "Remove Policy Rule Set" %}{% endblock %} + +{% block modal-body %} +
+
+ {% include "horizon/common/_form_fields.html" %} +
+
+
+

{% trans "Description:" %}

+

{% trans "Remove Consumed Policy Rule Set. Press Ctrl to select multiple items." %}

+
+{% endblock %} + +{% block modal-footer %} + + {% trans "Cancel" %} +{% endblock %} diff --git a/gbpui/panels/policytargets/templates/policytargets/_remove_contract.html b/gbpui/panels/policytargets/templates/policytargets/_remove_contract.html new file mode 100644 index 0000000..ebb29fb --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/_remove_contract.html @@ -0,0 +1,25 @@ +{% extends "horizon/common/_modal_form.html" %} +{% load i18n %} +{% load url from future %} + +{% block form_id %}remove_contract_form{% endblock %} +{% block form_action %}{% url 'horizon:project:policytargets:remove_contract' policy_target_id %}{% endblock %} + +{% block modal-header %}{% trans "Remove Policy Rule Set" %}{% endblock %} + +{% block modal-body %} +
+
+ {% include "horizon/common/_form_fields.html" %} +
+
+
+

{% trans "Description:" %}

+

{% trans "Remove Policy Rule Set. Press Ctrl to select multiple items." %}

+
+{% endblock %} + +{% block modal-footer %} + + {% trans "Cancel" %} +{% endblock %} diff --git a/gbpui/panels/policytargets/templates/policytargets/_remove_provided_prs.html b/gbpui/panels/policytargets/templates/policytargets/_remove_provided_prs.html new file mode 100644 index 0000000..01bbe70 --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/_remove_provided_prs.html @@ -0,0 +1,25 @@ +{% extends "horizon/common/_modal_form.html" %} +{% load i18n %} +{% load url from future %} + +{% block form_id %}add_consumed_form{% endblock %} +{% block form_action %}{% url 'horizon:project:policytargets:remove_provided_prs' policy_target_id %}{% endblock %} + +{% block modal-header %}{% trans "Remove Provided PRS" %}{% endblock %} + +{% block modal-body %} +
+
+ {% include "horizon/common/_form_fields.html" %} +
+
+
+

{% trans "Description:" %}

+

{% trans "Remove Consumed Policy Rule Set. Press Ctrl to select multiple items." %}

+
+{% endblock %} + +{% block modal-footer %} + + {% trans "Cancel" %} +{% endblock %} diff --git a/gbpui/panels/policytargets/templates/policytargets/_update_l3policy.html b/gbpui/panels/policytargets/templates/policytargets/_update_l3policy.html new file mode 100644 index 0000000..4e79dd1 --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/_update_l3policy.html @@ -0,0 +1,25 @@ +{% extends "horizon/common/_modal_form.html" %} +{% load i18n %} +{% load url from future %} + +{% block form_id %}update_l3policy_form{% endblock %} +{% block form_action %}{% url 'horizon:project:policytargets:update_l3policy' l3policy_id %}{% endblock %} + +{% block modal-header %}{% trans "Update L3Policy" %}{% endblock %} + +{% block modal-body %} +
+
+ {% include "horizon/common/_form_fields.html" %} +
+
+
+

{% trans "Description:" %}

+

{% trans "Update L3 Policy." %}

+
+{% endblock %} + +{% block modal-footer %} + + {% trans "Cancel" %} +{% endblock %} diff --git a/gbpui/panels/policytargets/templates/policytargets/_update_policy_target.html b/gbpui/panels/policytargets/templates/policytargets/_update_policy_target.html new file mode 100644 index 0000000..e17cf3c --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/_update_policy_target.html @@ -0,0 +1,25 @@ +{% extends "horizon/common/_modal_form.html" %} +{% load i18n %} +{% load url from future %} + +{% block form_id %}update_policy_target_form{% endblock %} +{% block form_action %}{% url 'horizon:project:policytargets:updatepolicy_target' policy_target_id %}{% endblock %} + +{% block modal-header %}{% trans "Edit Group" %}{% endblock %} + +{% block modal-body %} +
+
+ {% include "horizon/common/_form_fields.html" %} +
+
+
+

{% trans "Description:" %}

+

{% trans "You may update policy_target details here." %}

+
+{% endblock %} + +{% block modal-footer %} + + {% trans "Cancel" %} +{% endblock %} diff --git a/gbpui/panels/policytargets/templates/policytargets/_updateepg.html b/gbpui/panels/policytargets/templates/policytargets/_updateepg.html new file mode 100644 index 0000000..e17cf3c --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/_updateepg.html @@ -0,0 +1,25 @@ +{% extends "horizon/common/_modal_form.html" %} +{% load i18n %} +{% load url from future %} + +{% block form_id %}update_policy_target_form{% endblock %} +{% block form_action %}{% url 'horizon:project:policytargets:updatepolicy_target' policy_target_id %}{% endblock %} + +{% block modal-header %}{% trans "Edit Group" %}{% endblock %} + +{% block modal-body %} +
+
+ {% include "horizon/common/_form_fields.html" %} +
+
+
+

{% trans "Description:" %}

+

{% trans "You may update policy_target details here." %}

+
+{% endblock %} + +{% block modal-footer %} + + {% trans "Cancel" %} +{% endblock %} diff --git a/gbpui/panels/policytargets/templates/policytargets/addepg.html b/gbpui/panels/policytargets/templates/policytargets/addepg.html new file mode 100644 index 0000000..c7d705f --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/addepg.html @@ -0,0 +1,11 @@ +{% extends 'base.html' %} +{% load i18n %} +{% block title %}{% trans "Create New Group" %}{% endblock %} + +{% block page_header %} + {% include "horizon/common/_page_header.html" with title=_("Create New Group") %} +{% endblock page_header %} + +{% block main %} + {% include 'horizon/common/_workflow.html' %} +{% endblock %} diff --git a/gbpui/panels/policytargets/templates/policytargets/details_tabs.html b/gbpui/panels/policytargets/templates/policytargets/details_tabs.html new file mode 100644 index 0000000..5a1011d --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/details_tabs.html @@ -0,0 +1,15 @@ +{% extends 'base.html' %} +{% load i18n %} +{% block title %}{% trans "Groups" %}{% endblock %} + +{% block page_header %} +{% include "horizon/common/_page_header.html" with title=_("Groups") %} +{% endblock page_header %} + +{% block main %} +
+
+ {{ tab_group.render }} +
+
+{% endblock %} diff --git a/gbpui/panels/policytargets/templates/policytargets/group_details.html b/gbpui/panels/policytargets/templates/policytargets/group_details.html new file mode 100644 index 0000000..bb0b140 --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/group_details.html @@ -0,0 +1,15 @@ +{% extends 'base.html' %} +{% load i18n %} +{% block title %}{% trans "Groups Details" %}{% endblock %} + +{% block page_header %} +{% include "horizon/common/_page_header.html" with title=_("Group : ")|add:policy_target.name %} +{% endblock page_header %} + +{% block main %} +
+
+ {{ tab_group.render }} +
+
+{% endblock %} diff --git a/gbpui/panels/policytargets/templates/policytargets/updateepg.html b/gbpui/panels/policytargets/templates/policytargets/updateepg.html new file mode 100644 index 0000000..b49e42f --- /dev/null +++ b/gbpui/panels/policytargets/templates/policytargets/updateepg.html @@ -0,0 +1,11 @@ +{% extends 'base.html' %} +{% load i18n %} +{% block title %}{% trans "Edit Endpoint Group" %}{% endblock %} + +{% block page_header %} + {% include "horizon/common/_page_header.html" with title=_("Edit Group ")|add:name %} +{% endblock page_header %} + +{% block main %} + {% include 'project/policy_target_groups/_updatepolicy_target.html' %} +{% endblock %} diff --git a/gbpui/panels/policytargets/urls.py b/gbpui/panels/policytargets/urls.py new file mode 100644 index 0000000..4f0693e --- /dev/null +++ b/gbpui/panels/policytargets/urls.py @@ -0,0 +1,49 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + + +from django.conf.urls import patterns # noqa +from django.conf.urls import url # noqa + +import views + +urlpatterns = patterns('', + url(r'^$', + views.IndexView.as_view(), + name='index'), + url(r'^addpolicy_target$', + views.AddPTGView.as_view(), + name='addpolicy_target'), + url(r'^updatepolicy_target/' + '(?P[^/]+)/$', + views.UpdatePTGView.as_view(), + name='updatepolicy_target'), + url(r'^policy_target/(?P[^/]+)/$', + views.PTGDetailsView.as_view(), + name='policy_targetdetails'), + url(r'^addvm/(?P[^/]+)/$', + views.LaunchVMView.as_view(), name='addvm'), + url(r'^add_policy_rule_set/' + '(?P[^/]+)/$', + views.AddProvidedPRSView.as_view(), + name='add_provided_prs'), + url(r'^remove_policy_rule_set/' + '(?P[^/]+)/$', + views.RemoveProvidedPRSView.as_view(), + name='remove_provided_prs'), + url(r'^add_consumed/(?P[^/]+)/$', + views.AddConsumedPRSView.as_view(), + name='add_consumed_prs'), + url(r'^remove_consumed/(?P[^/]+)/$', + views.RemoveConsumedPRSView.as_view(), + name='remove_consumed_prs'), + ) diff --git a/gbpui/panels/policytargets/views.py b/gbpui/panels/policytargets/views.py new file mode 100644 index 0000000..3bd02b4 --- /dev/null +++ b/gbpui/panels/policytargets/views.py @@ -0,0 +1,166 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import re + +from django.core.urlresolvers import reverse_lazy +from django.utils.translation import ugettext_lazy as _ + +from horizon import exceptions +from horizon import forms +from horizon import messages +from horizon import tabs +from horizon.utils import memoized +from horizon import workflows + +from gbpui import client + +import forms as policy_target_forms +import tabs as policy_target_tabs +import workflows as policy_target_workflows + +PTGTabs = policy_target_tabs.PTGTabs +PTGDetailsTabs = policy_target_tabs.PTGDetailsTabs + +AddPTG = policy_target_workflows.AddPTG +LaunchVM = policy_target_workflows.CreateVM + + +class IndexView(tabs.TabView): + tab_group_class = (PTGTabs) + template_name = 'project/policytargets/details_tabs.html' + + def post(self, request, *args, **kwargs): + obj_ids = request.POST.getlist('object_ids') + action = request.POST['action'] + if not obj_ids: + obj_ids.append(re.search('([0-9a-z-]+)$', action).group(1)) + for obj_id in obj_ids: + try: + client.policy_target_delete(request, obj_id) + messages.success(request, + _('Deleted Group %s') % obj_id) + except Exception as e: + exceptions.handle(request, + _('Unable to delete Group. %s') % e) + return self.get(request, *args, **kwargs) + + +class AddPTGView(workflows.WorkflowView): + workflow_class = AddPTG + template_name = "project/policytargets/addpolicy_target.html" + + +class PTGDetailsView(tabs.TabbedTableView): + tab_group_class = (policy_target_tabs.PTGMemberTabs) + template_name = 'project/policytargets/group_details.html' + + def get_context_data(self, **kwargs): + context = super(PTGDetailsView, self).get_context_data(**kwargs) + try: + policy_target = client.policy_target_get( + self.request, context['policy_target_id']) + context['policy_target'] = policy_target + except Exception: + pass + return context + + +class LaunchVMView(workflows.WorkflowView): + workflow_class = LaunchVM + template_name = "project/policytargets/add_vm.html" + + def get_initial(self): + return self.kwargs + + +class UpdatePTGView(forms.ModalFormView): + form_class = policy_target_forms.UpdatePolicyTargetForm + template_name = "project/policytargets/update_policy_target.html" + context_object_name = 'policy_target' + success_url = reverse_lazy("horizon:project:policytargets:index") + + def get_context_data(self, **kwargs): + context = super(UpdatePTGView, self).get_context_data(**kwargs) + context["policy_target_id"] = self.kwargs['policy_target_id'] + obj = self._get_object() + if obj: + context['name'] = obj.name + return context + + @memoized.memoized_method + def _get_object(self, *args, **kwargs): + policy_target_id = self.kwargs['policy_target_id'] + try: + policy_target = client.policy_target_get( + self.request, policy_target_id) + policy_target.set_id_as_name_if_empty() + return policy_target + except Exception: + redirect = self.success_url + msg = _('Unable to retrieve policy_target details.') + exceptions.handle(self.request, msg, redirect=redirect) + + def get_initial(self): + return self.kwargs + + +class AddProvidedPRSView(forms.ModalFormView): + form_class = policy_target_forms.AddProvidedPRSForm + template_name = "project/policytargets/add_provided_prs.html" + + def get_context_data(self, **kwargs): + context = super(AddProvidedPRSView, self).get_context_data(**kwargs) + context["policy_target_id"] = self.kwargs['policy_target_id'] + return context + + def get_initial(self): + return self.kwargs + + +class RemoveProvidedPRSView(forms.ModalFormView): + form_class = policy_target_forms.RemoveProvidedPRSForm + template_name = "project/policytargets/remove_provided_prs.html" + + def get_context_data(self, **kwargs): + context = super(RemoveProvidedPRSView, self).get_context_data(**kwargs) + context["policy_target_id"] = self.kwargs['policy_target_id'] + return context + + def get_initial(self): + return self.kwargs + + +class AddConsumedPRSView(forms.ModalFormView): + form_class = policy_target_forms.AddConsumedPRSForm + template_name = "project/policytargets/add_consumed_prs.html" + + def get_context_data(self, **kwargs): + context = super(AddConsumedPRSView, self).get_context_data(**kwargs) + context["policy_target_id"] = self.kwargs['policy_target_id'] + return context + + def get_initial(self): + return self.kwargs + + +class RemoveConsumedPRSView(forms.ModalFormView): + form_class = policy_target_forms.RemoveConsumedPRSForm + template_name = "project/policytargets/remove_consumed_prs.html" + + def get_context_data(self, **kwargs): + context = super(RemoveConsumedPRSView, self).get_context_data(**kwargs) + context["policy_target_id"] = self.kwargs['policy_target_id'] + return context + + def get_initial(self): + return self.kwargs diff --git a/gbpui/panels/policytargets/workflows.py b/gbpui/panels/policytargets/workflows.py new file mode 100644 index 0000000..fcf0c55 --- /dev/null +++ b/gbpui/panels/policytargets/workflows.py @@ -0,0 +1,332 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import logging + +from django.core.urlresolvers import reverse +from django.template.defaultfilters import filesizeformat # noqa +from django.utils.translation import ugettext_lazy as _ + +from horizon import exceptions +from horizon import forms +from horizon import messages +from horizon import workflows + +from openstack_dashboard import api +from openstack_dashboard.dashboards.project.images import utils as imageutils +from openstack_dashboard.dashboards.project.instances import utils + +from gbpui import client +from gbpui import fields + +LOG = logging.getLogger(__name__) + +POLICY_RULE_SET_URL = "horizon:project:application_policy:addpolicy_rule_set" + + +class SelectPolicyRuleSetAction(workflows.Action): + provided_policy_rule_set = fields.DynamicMultiChoiceField( + label=_("Provided Policy Rule Set"), + help_text=_("Choose a policy rule set for an Group."), + add_item_link=POLICY_RULE_SET_URL, + required=False) + consumed_policy_rule_set = fields.DynamicMultiChoiceField( + label=_("Consumed Policy Rule Set"), + help_text=_("Select consumed policy rule set for Group."), + add_item_link=POLICY_RULE_SET_URL, + required=False) + + class Meta: + name = _("Application Policy") + help_text = _("Select Policy Rule Set for Group.") + + def _policy_rule_set_list(self, request, tenant_id): + policy_rule_sets = client.policy_rule_set_list(request, + tenant_id=tenant_id) + for c in policy_rule_sets: + c.set_id_as_name_if_empty() + policy_rule_sets = sorted(policy_rule_sets, + key=lambda rule: rule.name) + return [(c.id, c.name) for c in policy_rule_sets] + + def populate_provided_policy_rule_set_choices(self, request, context): + policy_rule_set_list = [] + try: + tenant_id = self.request.user.tenant_id + rsets = self._policy_rule_set_list(request, tenant_id) + if len(rsets) == 0: + rsets.extend([('None', 'No Provided Policy Rule Sets')]) + policy_rule_set_list = rsets + except Exception as e: + policy_rule_set_list = [] + msg = _('Unable to retrieve policy rule set. %s.') % (str(e)) + exceptions.handle(request, msg) + return policy_rule_set_list + + def populate_consumed_policy_rule_set_choices(self, request, context): + policy_rule_set_list = [] + try: + tenant_id = self.request.user.tenant_id + policy_rule_set_list = [('None', 'No Consumed Policy Rule Sets')] + policy_rule_set_list =\ + self._policy_rule_set_list(request, tenant_id) + except Exception as e: + msg = _('Unable to retrieve policy rule set. %s.') % (str(e)) + exceptions.handle(request, msg) + return policy_rule_set_list + + +class SelectL2policyAction(workflows.Action): + l2policy_id = forms.ChoiceField( + label=_("Network Policy"), + help_text=_("Select network policy for Group.")) + network_service_policy_id = forms.ChoiceField( + label=_("Network Services Policy"), + help_text=_("Select network services policy for Group."), + required=False) + + class Meta: + name = _("Network Policy") + help_text = _( + "Select network policy for Group." + "Selecting default will create an Network Policy implicitly.") + + def populate_l2policy_id_choices(self, request, context): + policies = [] + try: + policies = client.l2policy_list(request) + for p in policies: + p.set_id_as_name_if_empty() + policies = sorted(policies, key=lambda rule: rule.name) + policies = [(p.id, p.name + ":" + p.id) for p in policies] + policies.insert(0, ('default', 'Default')) + except Exception as e: + exceptions.handle(request, + _("Unable to retrieve policies (%(error)s).") + % {'error': str(e)}) + return policies + + def populate_network_service_policy_id_choices(self, request, context): + policies = [] + try: + policies = client.networkservicepolicy_list( + request, tenant_id=request.user.tenant_id) + for p in policies: + p.set_id_as_name_if_empty() + policies = [(p.id, p.name + ":" + p.id) for p in policies] + policies.insert(0, ('None', 'No Network Service Policy')) + except Exception as e: + msg = _("Unable to retrieve service policies. %s).") % (str(e)) + exceptions.handle(request, msg) + return policies + + +class SelectL2policyStep(workflows.Step): + action_class = SelectL2policyAction + name = _("L2 Policy") + contributes = ("l2policy_id", "network_services_policy_id",) + + def contribute(self, data, context): + if data['l2policy_id'] != 'default': + context['l2_policy_id'] = data['l2policy_id'] + if data['network_service_policy_id'] != 'None': + context['network_service_policy_id'] = \ + data['network_service_policy_id'] + return context + + +class SelectPolicyRuleSetStep(workflows.Step): + action_class = SelectPolicyRuleSetAction + name = _("Provided Policy Rule Set") + contributes = ("provided_policy_rule_sets", "consumed_policy_rule_sets",) + + def contribute(self, data, context): + if data: + policy_rule_sets = self.workflow.request.POST.getlist( + "provided_policy_rule_set") + if policy_rule_sets: + policy_rule_set_dict = {} + for policy_rule_set in policy_rule_sets: + if policy_rule_set != 'None': + policy_rule_set_dict[policy_rule_set] = None + context['provided_policy_rule_sets'] = policy_rule_set_dict + policy_rule_sets = self.workflow.request.POST.getlist( + "consumed_policy_rule_set") + if policy_rule_sets: + policy_rule_set_dict = {} + for policy_rule_set in policy_rule_sets: + if policy_rule_set != 'None': + policy_rule_set_dict[policy_rule_set] = None + context['consumed_policy_rule_sets'] = policy_rule_set_dict + return context + + +class AddPTGAction(workflows.Action): + name = forms.CharField(max_length=80, + label=_("Name")) + description = forms.CharField(max_length=80, + label=_("Description"), + required=False) + + def __init__(self, request, *args, **kwargs): + super(AddPTGAction, self).__init__(request, *args, **kwargs) + + class Meta: + name = _("Create Group") + help_text = _("Create a new Group") + + +class AddPTGStep(workflows.Step): + action_class = AddPTGAction + contributes = ("name", "description") + + def contribute(self, data, context): + context = super(AddPTGStep, self).contribute(data, context) + return context + + +class AddPTG(workflows.Workflow): + slug = "addpolicy_target" + name = _("Create Group") + finalize_button_name = _("Create") + success_message = _('Create Group "%s".') + failure_message = _('Unable to create Group "%s".') + success_url = "horizon:project:policytargets:index" + default_steps = (AddPTGStep, + SelectPolicyRuleSetStep, + SelectL2policyStep,) + wizard = True + + def format_status_message(self, message): + return message % self.context.get('name') + + def handle(self, request, context): + try: + group = client.policy_target_create(request, **context) + return group + except Exception as e: + msg = self.format_status_message(self.failure_message) + str(e) + exceptions.handle(request, msg) + return False + + +def _image_choice_title(img): + gb = filesizeformat(img.size) + return '%s (%s)' % (img.name or img.id, gb) + + +class LaunchInstance(workflows.Action): + availability_zone = forms.ChoiceField( + label=_("Availability Zone"), required=False) + name = forms.CharField(label=_("Instance Name"), max_length=255) + flavor = forms.ChoiceField( + label=_("Flavor"), help_text=_("Size of image to launch.")) + count = forms.IntegerField(label=_( + "Instance Count"), + min_value=1, + initial=1, + help_text=_("Number of instances to launch.")) + image = forms.ChoiceField(label=_("Select Image"), + widget=forms.SelectWidget( + attrs={'class': 'image-selector'}, + data_attrs=('size', 'display-name'), + transform=_image_choice_title)) + + def __init__(self, request, *args, **kwargs): + super(LaunchInstance, self).__init__(request, *args, **kwargs) + images = imageutils.get_available_images( + request, request.user.tenant_id) + choices = [(image.id, image) for image in images] + if choices: + choices.insert(0, ("", _("Select Image"))) + else: + choices.insert(0, ("", _("No images available"))) + zones = self._availability_zone_choices(request) + self.fields['image'].choices = choices + self.fields['availability_zone'].choices = zones + self.fields['flavor'].choices = self._flavor_choices(request) + + def _flavor_choices(self, request): + flavors = utils.flavor_list(request) + if flavors: + return utils.sort_flavor_list(request, flavors) + return [] + + def _availability_zone_choices(self, request): + try: + zones = api.nova.availability_zone_list(request) + except Exception: + zones = [] + exceptions.handle( + request, _('Unable to retrieve availability zones.')) + zone_list = [(zone.zoneName, zone.zoneName) + for zone in zones if zone.zoneState['available']] + zone_list.sort() + if not zone_list: + zone_list.insert(0, ("", _("No availability zones found"))) + elif len(zone_list) > 1: + zone_list.insert(0, ("", _("Any Availability Zone"))) + return zone_list + + def handle(self, request, context): + policy_target_id = self.request.path.split("/")[-2] + try: + msg = _('Member was successfully created.') + ep = client.pt_create( + request, policy_target_group_id=policy_target_id) + api.nova.server_create(request, + context['name'], + context['image'], + context['flavor'], + key_name=None, + user_data=None, + security_groups=None, + instance_count=context['count'], + nics=[{'port-id': ep.port_id}]) + LOG.debug(msg) + messages.success(request, msg) + except Exception: + msg = _('Failed to launch VM') + LOG.error(msg) + u = "horizon:project:policytargets:policy_targetdetails" + redirect = reverse(u, kwargs={'policy_target_id': + policy_target_id}) + exceptions.handle(request, msg, redirect=redirect) + + +class LaunchVMStep(workflows.Step): + action_class = LaunchInstance + contributes = ("name", "availability_zone", "flavor", "count", "image") + + def contribute(self, data, context): + context = super(LaunchVMStep, self).contribute(data, context) + return context + + +class CreateVM(workflows.Workflow): + slug = "launch VM" + name = _("Create Member") + + finalize_button_name = _("Launch") + success_message = _('Create Member "%s".') + failure_message = _('Unable to create Member "%s".') + default_steps = (LaunchVMStep,) + wizard = True + + def format_status_message(self, message): + return message % self.context.get('name') + + def get_success_url(self): + policy_targetid = self.request.path.split("/")[-2] + u = "horizon:project:policytargets:policy_targetdetails" + success_url = reverse(u, kwargs={'policy_target_id': policy_targetid}) + return success_url