Browse Source

Add support for External Access model

Heat resources for:

External Policies
External Segments
Nat Pools

Also, 'shared' attribute added to applicable resources.
Partially Implements: blueprint external-connectivity

Change-Id: I39b11c973565673313de21aa38a540173fc34628
Susaant 4 years ago
parent
commit
56716b487c

+ 352
- 17
gbpautomation/heat/engine/resources/neutron/grouppolicy.py View File

@@ -111,11 +111,11 @@ class PolicyTargetGroup(gbpresource.GBPResource):
111 111
 
112 112
     PROPERTIES = (
113 113
         TENANT_ID, NAME, DESCRIPTION, L2_POLICY_ID, PROVIDED_POLICY_RULE_SETS,
114
-        CONSUMED_POLICY_RULE_SETS, NETWORK_SERVICE_POLICY_ID
114
+        CONSUMED_POLICY_RULE_SETS, NETWORK_SERVICE_POLICY_ID, SHARED
115 115
     ) = (
116 116
         'tenant_id', 'name', 'description', 'l2_policy_id',
117 117
         'provided_policy_rule_sets', 'consumed_policy_rule_sets',
118
-        'network_service_policy_id'
118
+        'network_service_policy_id', 'shared'
119 119
     )
120 120
 
121 121
     properties_schema = {
@@ -152,7 +152,13 @@ class PolicyTargetGroup(gbpresource.GBPResource):
152 152
             properties.Schema.STRING,
153 153
             _('Network service policy id of the policy target group.'),
154 154
             update_allowed=True, default=None
155
+        ),
156
+        SHARED: properties.Schema(
157
+            properties.Schema.BOOLEAN,
158
+            _('Shared.'),
159
+            update_allowed=True, required=True
155 160
         )
161
+
156 162
     }
157 163
 
158 164
     def _show_resource(self):
@@ -222,9 +228,9 @@ class PolicyTargetGroup(gbpresource.GBPResource):
222 228
 class L2Policy(gbpresource.GBPResource):
223 229
 
224 230
     PROPERTIES = (
225
-        TENANT_ID, NAME, DESCRIPTION, L3_POLICY_ID
231
+        TENANT_ID, NAME, DESCRIPTION, L3_POLICY_ID, SHARED
226 232
     ) = (
227
-        'tenant_id', 'name', 'description', 'l3_policy_id'
233
+        'tenant_id', 'name', 'description', 'l3_policy_id', 'shared'
228 234
     )
229 235
 
230 236
     properties_schema = {
@@ -247,6 +253,11 @@ class L2Policy(gbpresource.GBPResource):
247 253
             _('L3 policy id associated with l2 policy.'),
248 254
             required=True,
249 255
             update_allowed=True
256
+        ),
257
+        SHARED: properties.Schema(
258
+            properties.Schema.BOOLEAN,
259
+            _('Shared.'),
260
+            update_allowed=True, required=True
250 261
         )
251 262
     }
252 263
 
@@ -290,10 +301,10 @@ class L3Policy(gbpresource.GBPResource):
290 301
 
291 302
     PROPERTIES = (
292 303
         TENANT_ID, NAME, DESCRIPTION, IP_VERSION, IP_POOL,
293
-        SUBNET_PREFIX_LENGTH
304
+        SUBNET_PREFIX_LENGTH, EXTERNAL_SEGMENTS, SHARED
294 305
     ) = (
295 306
         'tenant_id', 'name', 'description', 'ip_version', 'ip_pool',
296
-        'subnet_prefix_length'
307
+        'subnet_prefix_length', 'external_segments', 'shared'
297 308
     )
298 309
 
299 310
     properties_schema = {
@@ -325,6 +336,16 @@ class L3Policy(gbpresource.GBPResource):
325 336
             properties.Schema.INTEGER,
326 337
             _('Subnet prefix length of L3 policy.'),
327 338
             update_allowed=True
339
+        ),
340
+        EXTERNAL_SEGMENTS: properties.Schema(
341
+            properties.Schema.MAP,
342
+            _('External segments of L3 policy.'),
343
+            update_allowed=True
344
+        ),
345
+        SHARED: properties.Schema(
346
+            properties.Schema.BOOLEAN,
347
+            _('Shared.'),
348
+            update_allowed=True, required=True
328 349
         )
329 350
     }
330 351
 
@@ -368,10 +389,10 @@ class PolicyClassifier(gbpresource.GBPResource):
368 389
 
369 390
     PROPERTIES = (
370 391
         TENANT_ID, NAME, DESCRIPTION, PROTOCOL, PORT_RANGE,
371
-        DIRECTION
392
+        DIRECTION, SHARED
372 393
     ) = (
373 394
         'tenant_id', 'name', 'description', 'protocol', 'port_range',
374
-        'direction'
395
+        'direction', 'shared'
375 396
     )
376 397
 
377 398
     properties_schema = {
@@ -409,6 +430,11 @@ class PolicyClassifier(gbpresource.GBPResource):
409 430
                 constraints.AllowedValues(['in', 'out', 'bi', None])
410 431
             ],
411 432
             update_allowed=True
433
+        ),
434
+        SHARED: properties.Schema(
435
+            properties.Schema.BOOLEAN,
436
+            _('Shared.'),
437
+            update_allowed=True, required=True
412 438
         )
413 439
     }
414 440
 
@@ -451,9 +477,10 @@ class PolicyClassifier(gbpresource.GBPResource):
451 477
 class PolicyAction(gbpresource.GBPResource):
452 478
 
453 479
     PROPERTIES = (
454
-        TENANT_ID, NAME, DESCRIPTION, ACTION_TYPE, ACTION_VALUE
480
+        TENANT_ID, NAME, DESCRIPTION, ACTION_TYPE, ACTION_VALUE, SHARED
455 481
     ) = (
456
-        'tenant_id', 'name', 'description', 'action_type', 'action_value'
482
+        'tenant_id', 'name', 'description', 'action_type', 'action_value',
483
+        'shared'
457 484
     )
458 485
 
459 486
     properties_schema = {
@@ -483,6 +510,11 @@ class PolicyAction(gbpresource.GBPResource):
483 510
             properties.Schema.STRING,
484 511
             _('Value of the action.'),
485 512
             update_allowed=True
513
+        ),
514
+        SHARED: properties.Schema(
515
+            properties.Schema.BOOLEAN,
516
+            _('Shared.'),
517
+            update_allowed=True, required=True
486 518
         )
487 519
     }
488 520
 
@@ -526,10 +558,10 @@ class PolicyRule(gbpresource.GBPResource):
526 558
 
527 559
     PROPERTIES = (
528 560
         TENANT_ID, NAME, DESCRIPTION, ENABLED, POLICY_CLASSIFIER_ID,
529
-        POLICY_ACTIONS
561
+        POLICY_ACTIONS, SHARED
530 562
     ) = (
531 563
         'tenant_id', 'name', 'description', 'enabled', 'policy_classifier_id',
532
-        'policy_actions'
564
+        'policy_actions', 'shared'
533 565
     )
534 566
 
535 567
     properties_schema = {
@@ -561,6 +593,11 @@ class PolicyRule(gbpresource.GBPResource):
561 593
             properties.Schema.LIST,
562 594
             _('List of actions of the policy rule.'),
563 595
             default=None, update_allowed=True
596
+        ),
597
+        SHARED: properties.Schema(
598
+            properties.Schema.BOOLEAN,
599
+            _('Shared.'),
600
+            update_allowed=True, required=True
564 601
         )
565 602
     }
566 603
 
@@ -604,10 +641,10 @@ class PolicyRuleSet(gbpresource.GBPResource):
604 641
 
605 642
     PROPERTIES = (
606 643
         TENANT_ID, NAME, DESCRIPTION, PARENT_ID, CHILD_POLICY_RULE_SETS,
607
-        POLICY_RULES
644
+        POLICY_RULES, SHARED
608 645
     ) = (
609 646
         'tenant_id', 'name', 'description', 'parent_id',
610
-        'child_policy_rule_sets', 'policy_rules'
647
+        'child_policy_rule_sets', 'policy_rules', 'shared'
611 648
     )
612 649
 
613 650
     properties_schema = {
@@ -639,6 +676,11 @@ class PolicyRuleSet(gbpresource.GBPResource):
639 676
             properties.Schema.LIST,
640 677
             _('List of policy rules.'),
641 678
             default=None, update_allowed=True
679
+        ),
680
+        SHARED: properties.Schema(
681
+            properties.Schema.BOOLEAN,
682
+            _('Shared.'),
683
+            update_allowed=True, required=True
642 684
         )
643 685
     }
644 686
 
@@ -681,9 +723,9 @@ class PolicyRuleSet(gbpresource.GBPResource):
681 723
 class NetworkServicePolicy(gbpresource.GBPResource):
682 724
 
683 725
     PROPERTIES = (
684
-        TENANT_ID, NAME, DESCRIPTION, NETWORK_SERVICE_PARAMS
726
+        TENANT_ID, NAME, DESCRIPTION, NETWORK_SERVICE_PARAMS, SHARED
685 727
     ) = (
686
-        'tenant_id', 'name', 'description', 'network_service_params'
728
+        'tenant_id', 'name', 'description', 'network_service_params', 'shared'
687 729
     )
688 730
 
689 731
     properties_schema = {
@@ -705,6 +747,11 @@ class NetworkServicePolicy(gbpresource.GBPResource):
705 747
             properties.Schema.LIST,
706 748
             _('List of network service policy dicts.'),
707 749
             default=None, update_allowed=True
750
+        ),
751
+        SHARED: properties.Schema(
752
+            properties.Schema.BOOLEAN,
753
+            _('Shared.'),
754
+            update_allowed=True, required=True
708 755
         )
709 756
     }
710 757
 
@@ -745,6 +792,291 @@ class NetworkServicePolicy(gbpresource.GBPResource):
745 792
                 self.resource_id, {'network_service_policy': prop_diff})
746 793
 
747 794
 
795
+class ExternalPolicy(gbpresource.GBPResource):
796
+
797
+    PROPERTIES = (
798
+        TENANT_ID, NAME, DESCRIPTION, EXTERNAL_SEGMENTS,
799
+        PROVIDED_POLICY_RULE_SETS, CONSUMED_POLICY_RULE_SETS, SHARED
800
+    ) = (
801
+        'tenant_id', 'name', 'description', 'external_segments',
802
+        'provided_policy_rule_sets', 'consumed_policy_rule_sets', 'shared'
803
+    )
804
+
805
+    properties_schema = {
806
+        TENANT_ID: properties.Schema(
807
+            properties.Schema.STRING,
808
+            _('Tenant id of the external policy.')
809
+        ),
810
+        NAME: properties.Schema(
811
+            properties.Schema.STRING,
812
+            _('Name of the external policy.'),
813
+            update_allowed=True
814
+        ),
815
+        DESCRIPTION: properties.Schema(
816
+            properties.Schema.STRING,
817
+            _('Description of the external policy.'),
818
+            update_allowed=True
819
+        ),
820
+        EXTERNAL_SEGMENTS: properties.Schema(
821
+            properties.Schema.LIST,
822
+            _('External segments of the policy.'),
823
+            update_allowed=True
824
+        ),
825
+        PROVIDED_POLICY_RULE_SETS: properties.Schema(
826
+            properties.Schema.LIST,
827
+            _('Provided policy rule sets.'),
828
+            default=None, update_allowed=True
829
+        ),
830
+        CONSUMED_POLICY_RULE_SETS: properties.Schema(
831
+            properties.Schema.LIST,
832
+            _('Consumed policy rule sets.'),
833
+            default=None, update_allowed=True
834
+        ),
835
+        SHARED: properties.Schema(
836
+            properties.Schema.BOOLEAN,
837
+            _('Shared.'),
838
+            update_allowed=True, required=True
839
+        )
840
+    }
841
+
842
+    def _show_resource(self):
843
+        client = self.grouppolicy()
844
+        ext_policy_id = self.resource_id
845
+        ext_policy = client.show_external_policy(ext_policy_id)
846
+        return ext_policy['external_policy']
847
+
848
+    def handle_create(self):
849
+        client = self.grouppolicy()
850
+
851
+        props = {}
852
+        for key in self.properties:
853
+            if self.properties.get(key) is not None:
854
+                props[key] = self.properties.get(key)
855
+
856
+        provided_policy_rule_set_list = {}
857
+        consumed_policy_rule_set_list = {}
858
+        props_provided_policy_rule_sets = props.get(
859
+            'provided_policy_rule_sets', [])
860
+        props_consumed_policy_rule_sets = props.get(
861
+            'consumed_policy_rule_sets', [])
862
+
863
+        for prop_prov_policy_rule_set in props_provided_policy_rule_sets:
864
+            policy_rule_set_id = (
865
+                prop_prov_policy_rule_set['policy_rule_set_id'])
866
+            policy_rule_set_scope = (
867
+                prop_prov_policy_rule_set['policy_rule_set_scope'])
868
+            provided_policy_rule_set_list.update({policy_rule_set_id:
869
+                                                  policy_rule_set_scope})
870
+
871
+        for prop_cons_policy_rule_set in props_consumed_policy_rule_sets:
872
+            policy_rule_set_id = (
873
+                prop_cons_policy_rule_set['policy_rule_set_id'])
874
+            policy_rule_set_scope = (
875
+                prop_cons_policy_rule_set['policy_rule_set_scope'])
876
+            consumed_policy_rule_set_list.update({policy_rule_set_id:
877
+                                                  policy_rule_set_scope})
878
+
879
+        if provided_policy_rule_set_list:
880
+            props['provided_policy_rule_sets'] = provided_policy_rule_set_list
881
+        if consumed_policy_rule_set_list:
882
+            props['consumed_policy_rule_sets'] = consumed_policy_rule_set_list
883
+
884
+        ext_policy = client.create_external_policy(
885
+            {'external_policy': props})['external_policy']
886
+
887
+        self.resource_id_set(ext_policy['id'])
888
+
889
+    def handle_delete(self):
890
+
891
+        client = self.grouppolicy()
892
+        ext_policy_id = self.resource_id
893
+
894
+        try:
895
+            client.delete_external_policy(ext_policy_id)
896
+        except NeutronClientException as ex:
897
+            self.client_plugin().ignore_not_found(ex)
898
+        else:
899
+            return self._delete_task()
900
+
901
+    def handle_update(self, json_snippet, tmpl_diff, prop_diff):
902
+        if prop_diff:
903
+            self.grouppolicy().update_external_policy(
904
+                self.resource_id, {'external_policy': prop_diff})
905
+
906
+
907
+class ExternalSegment(gbpresource.GBPResource):
908
+
909
+    PROPERTIES = (
910
+        TENANT_ID, NAME, DESCRIPTION, IP_VERSION, CIDR,
911
+        EXTERNAL_ROUTES, PORT_ADDRESS_TRANSLATION, SHARED
912
+    ) = (
913
+        'tenant_id', 'name', 'description', 'ip_version', 'cidr',
914
+        'external_routes', 'port_address_translation', 'shared'
915
+    )
916
+
917
+    properties_schema = {
918
+        TENANT_ID: properties.Schema(
919
+            properties.Schema.STRING,
920
+            _('Tenant id of the external segment.')
921
+        ),
922
+        NAME: properties.Schema(
923
+            properties.Schema.STRING,
924
+            _('Name of the external segment.'),
925
+            update_allowed=True
926
+        ),
927
+        DESCRIPTION: properties.Schema(
928
+            properties.Schema.STRING,
929
+            _('Description of the external segment.'),
930
+            update_allowed=True
931
+        ),
932
+        IP_VERSION: properties.Schema(
933
+            properties.Schema.STRING,
934
+            _('IP version of the external segment.'),
935
+            default='4', update_allowed=False
936
+        ),
937
+        CIDR: properties.Schema(
938
+            properties.Schema.STRING,
939
+            _('CIDR of the external segment.'),
940
+            default=None, update_allowed=False
941
+        ),
942
+        EXTERNAL_ROUTES: properties.Schema(
943
+            properties.Schema.LIST,
944
+            _('External routes of the external segment.'),
945
+            default=None, update_allowed=True
946
+        ),
947
+        PORT_ADDRESS_TRANSLATION: properties.Schema(
948
+            properties.Schema.BOOLEAN,
949
+            _('Port address translation required for the external segment.'),
950
+            update_allowed=True, required=True
951
+        ),
952
+        SHARED: properties.Schema(
953
+            properties.Schema.BOOLEAN,
954
+            _('Shared.'),
955
+            update_allowed=True, required=True
956
+        )
957
+    }
958
+
959
+    def _show_resource(self):
960
+        client = self.grouppolicy()
961
+        es_id = self.resource_id
962
+        es = client.show_external_segment(es_id)
963
+        return es['external_segment']
964
+
965
+    def handle_create(self):
966
+        client = self.grouppolicy()
967
+
968
+        props = {}
969
+        for key in self.properties:
970
+            if self.properties.get(key) is not None:
971
+                props[key] = self.properties.get(key)
972
+
973
+        es = client.create_external_segment(
974
+            {'external_segment': props})['external_segment']
975
+
976
+        self.resource_id_set(es['id'])
977
+
978
+    def handle_delete(self):
979
+
980
+        client = self.grouppolicy()
981
+        es_id = self.resource_id
982
+
983
+        try:
984
+            client.delete_external_segment(es_id)
985
+        except NeutronClientException as ex:
986
+            self.client_plugin().ignore_not_found(ex)
987
+        else:
988
+            return self._delete_task()
989
+
990
+    def handle_update(self, json_snippet, tmpl_diff, prop_diff):
991
+        if prop_diff:
992
+            self.grouppolicy().update_external_segment(
993
+                self.resource_id, {'external_segment': prop_diff})
994
+
995
+
996
+class NATPool(gbpresource.GBPResource):
997
+
998
+    PROPERTIES = (
999
+        TENANT_ID, NAME, DESCRIPTION, IP_VERSION, IP_POOL,
1000
+        EXTERNAL_SEGMENT_ID, SHARED
1001
+    ) = (
1002
+        'tenant_id', 'name', 'description', 'ip_version', 'ip_pool',
1003
+        'external_segment_id', 'shared'
1004
+    )
1005
+
1006
+    properties_schema = {
1007
+        TENANT_ID: properties.Schema(
1008
+            properties.Schema.STRING,
1009
+            _('Tenant id of the NAT pool.')
1010
+        ),
1011
+        NAME: properties.Schema(
1012
+            properties.Schema.STRING,
1013
+            _('Name of the NAT pool.'),
1014
+            update_allowed=True
1015
+        ),
1016
+        DESCRIPTION: properties.Schema(
1017
+            properties.Schema.STRING,
1018
+            _('Description of the NET pool.'),
1019
+            update_allowed=True
1020
+        ),
1021
+        IP_VERSION: properties.Schema(
1022
+            properties.Schema.STRING,
1023
+            _('IP version of the NAT pool.'),
1024
+            default='4', update_allowed=False
1025
+        ),
1026
+        IP_POOL: properties.Schema(
1027
+            properties.Schema.STRING,
1028
+            _('IP pool of the NAT pool.'),
1029
+            default=None, update_allowed=False
1030
+        ),
1031
+        EXTERNAL_SEGMENT_ID: properties.Schema(
1032
+            properties.Schema.STRING,
1033
+            _('External segment id of the NAT pool.'),
1034
+            update_allowed=True, required=True
1035
+        ),
1036
+        SHARED: properties.Schema(
1037
+            properties.Schema.BOOLEAN,
1038
+            _('Shared.'),
1039
+            update_allowed=True, required=True
1040
+        )
1041
+    }
1042
+
1043
+    def _show_resource(self):
1044
+        client = self.grouppolicy()
1045
+        nat_pool_id = self.resource_id
1046
+        nat_pool = client.show_nat_pool(nat_pool_id)
1047
+        return nat_pool['nat_pool']
1048
+
1049
+    def handle_create(self):
1050
+        client = self.grouppolicy()
1051
+
1052
+        props = {}
1053
+        for key in self.properties:
1054
+            if self.properties.get(key) is not None:
1055
+                props[key] = self.properties.get(key)
1056
+
1057
+        nat_pool = client.create_nat_pool(
1058
+            {'nat_pool': props})['nat_pool']
1059
+
1060
+        self.resource_id_set(nat_pool['id'])
1061
+
1062
+    def handle_delete(self):
1063
+
1064
+        client = self.grouppolicy()
1065
+        nat_pool_id = self.resource_id
1066
+
1067
+        try:
1068
+            client.delete_nat_pool(nat_pool_id)
1069
+        except NeutronClientException as ex:
1070
+            self.client_plugin().ignore_not_found(ex)
1071
+        else:
1072
+            return self._delete_task()
1073
+
1074
+    def handle_update(self, json_snippet, tmpl_diff, prop_diff):
1075
+        if prop_diff:
1076
+            self.grouppolicy().update_nat_pool(
1077
+                self.resource_id, {'nat_pool': prop_diff})
1078
+
1079
+
748 1080
 def resource_mapping():
749 1081
     return {
750 1082
         'OS::Neutron::PolicyTarget': PolicyTarget,
@@ -755,5 +1087,8 @@ def resource_mapping():
755 1087
         'OS::Neutron::PolicyAction': PolicyAction,
756 1088
         'OS::Neutron::PolicyRule': PolicyRule,
757 1089
         'OS::Neutron::PolicyRuleSet': PolicyRuleSet,
758
-        'OS::Neutron::NetworkServicePolicy': NetworkServicePolicy
1090
+        'OS::Neutron::NetworkServicePolicy': NetworkServicePolicy,
1091
+        'OS::Neutron::ExternalPolicy': ExternalPolicy,
1092
+        'OS::Neutron::ExternalSegment': ExternalSegment,
1093
+        'OS::Neutron::NATPool': NATPool
759 1094
     }

+ 514
- 24
gbpautomation/heat/tests/test_grouppolicy.py View File

@@ -64,7 +64,8 @@ policy_target_group_template = '''
64 64
              "policy_rule_set_scope": "scope3"},
65 65
             {"policy_rule_set_id": "policy_rule_set4",
66 66
              "policy_rule_set_scope": "scope4"}
67
-        ]
67
+        ],
68
+        "shared": True
68 69
       }
69 70
     }
70 71
   }
@@ -82,7 +83,8 @@ l2_policy_template = '''
82 83
       "Properties": {
83 84
         "name": "test-l2-policy",
84 85
         "description": "test L2 policy resource",
85
-        "l3_policy_id": "l3-policy-id"
86
+        "l3_policy_id": "l3-policy-id",
87
+        "shared": True
86 88
       }
87 89
     }
88 90
   }
@@ -102,7 +104,8 @@ l3_policy_template = '''
102 104
         "description": "test L3 policy resource",
103 105
         "ip_version": "4",
104 106
         "ip_pool": "10.20.20.0",
105
-        "subnet_prefix_length": 24
107
+        "subnet_prefix_length": 24,
108
+        "shared": True
106 109
       }
107 110
     }
108 111
   }
@@ -122,7 +125,8 @@ policy_classifier_template = '''
122 125
                 "description": "test policy classifier resource",
123 126
                 "protocol": "tcp",
124 127
                 "port_range": "8000-9000",
125
-                "direction": "bi"
128
+                "direction": "bi",
129
+                "shared": True
126 130
       }
127 131
     }
128 132
   }
@@ -141,7 +145,8 @@ policy_action_template = '''
141 145
                 "name": "test-policy-action",
142 146
                 "description": "test policy action resource",
143 147
                 "action_type": "redirect",
144
-                "action_value": "7890"
148
+                "action_value": "7890",
149
+                "shared": True
145 150
       }
146 151
     }
147 152
   }
@@ -161,7 +166,8 @@ policy_rule_template = '''
161 166
           "description": "test policy rule resource",
162 167
           "enabled": True,
163 168
           "policy_classifier_id": "7890",
164
-          "policy_actions": ['3456', '1234']
169
+          "policy_actions": ['3456', '1234'],
170
+          "shared": True
165 171
       }
166 172
     }
167 173
   }
@@ -181,7 +187,8 @@ policy_rule_set_template = '''
181 187
           "description": "test policy rule set resource",
182 188
           "parent_id": "3456",
183 189
           "child_policy_rule_sets": ["7890", "1234"],
184
-          "policy_rules": ["2345", "6789"]
190
+          "policy_rules": ["2345", "6789"],
191
+          "shared": True
185 192
       }
186 193
     }
187 194
   }
@@ -200,7 +207,90 @@ network_service_policy_template = '''
200 207
           "name": "test-nsp",
201 208
           "description": "test NSP resource",
202 209
           "network_service_params": [{'type': 'ip_single', 'name': 'vip',
203
-                                      'value': 'self_subnet'}]
210
+                                      'value': 'self_subnet'}],
211
+          "shared": True
212
+      }
213
+    }
214
+  }
215
+}
216
+'''
217
+
218
+external_policy_template = '''
219
+{
220
+ "AWSTemplateFormatVersion" : "2010-09-09",
221
+  "Description" : "Template to test external policy",
222
+  "Parameters" : {},
223
+  "Resources" : {
224
+  "external_policy": {
225
+      "Type": "OS::Neutron::ExternalPolicy",
226
+      "Properties": {
227
+          "name": "test-ep",
228
+          "description": "test EP resource",
229
+          "external_segments": ['1234'],
230
+          "provided_policy_rule_sets": [{
231
+              "policy_rule_set_id": '2345',
232
+              "policy_rule_set_scope": "scope1"
233
+          },
234
+          {
235
+              "policy_rule_set_id": '8901',
236
+              "policy_rule_set_scope": "scope2"
237
+          }],
238
+          "consumed_policy_rule_sets": [{
239
+              "policy_rule_set_id": '9012',
240
+              "policy_rule_set_scope": "scope3"
241
+          },
242
+          {
243
+              "policy_rule_set_id": '9210',
244
+              "policy_rule_set_scope": "scope4"
245
+          }],
246
+          "shared": True
247
+      }
248
+    }
249
+  }
250
+}
251
+'''
252
+
253
+external_segment_template = '''
254
+{
255
+ "AWSTemplateFormatVersion" : "2010-09-09",
256
+  "Description" : "Template to test external segment",
257
+  "Parameters" : {},
258
+  "Resources" : {
259
+  "external_segment": {
260
+      "Type": "OS::Neutron::ExternalSegment",
261
+      "Properties": {
262
+          "name": "test-es",
263
+          "description": "test ES resource",
264
+          "ip_version": '6',
265
+          "cidr": "192.168.0.0/24",
266
+          "external_routes": [{
267
+              "destination": "0.0.0.0/0",
268
+              "nexthop": "null"
269
+              }
270
+          ],
271
+          "port_address_translation": True,
272
+          "shared": True
273
+      }
274
+    }
275
+  }
276
+}
277
+'''
278
+
279
+nat_pool_template = '''
280
+{
281
+ "AWSTemplateFormatVersion" : "2010-09-09",
282
+  "Description" : "Template to test NAT pool",
283
+  "Parameters" : {},
284
+  "Resources" : {
285
+  "nat_pool": {
286
+      "Type": "OS::Neutron::NATPool",
287
+      "Properties": {
288
+          "name": "test-nat-pool",
289
+          "description": "test NP resource",
290
+          "ip_version": '6',
291
+          "ip_pool": "192.168.0.0/24",
292
+          "external_segment_id": '1234',
293
+          "shared": True
204 294
       }
205 295
     }
206 296
   }
@@ -362,7 +452,8 @@ class PolicyTargetGroupTest(HeatTestCase):
362 452
                 "consumed_policy_rule_sets": {
363 453
                     "policy_rule_set3": "scope3",
364 454
                     "policy_rule_set4": "scope4"
365
-                }
455
+                },
456
+                "shared": True
366 457
             }
367 458
         }).AndReturn({'policy_target_group': {'id': '5678'}})
368 459
 
@@ -393,7 +484,8 @@ class PolicyTargetGroupTest(HeatTestCase):
393 484
                 "consumed_policy_rule_sets": {
394 485
                     "policy_rule_set3": "scope3",
395 486
                     "policy_rule_set4": "scope4"
396
-                }
487
+                },
488
+                "shared": True
397 489
             }
398 490
         }).AndRaise(grouppolicy.NeutronClientException())
399 491
         self.m.ReplayAll()
@@ -480,7 +572,8 @@ class L2PolicyTest(HeatTestCase):
480 572
             'l2_policy': {
481 573
                 "name": "test-l2-policy",
482 574
                 "description": "test L2 policy resource",
483
-                "l3_policy_id": "l3-policy-id"
575
+                "l3_policy_id": "l3-policy-id",
576
+                "shared": True
484 577
             }
485 578
         }).AndReturn({'l2_policy': {'id': '5678'}})
486 579
 
@@ -502,7 +595,8 @@ class L2PolicyTest(HeatTestCase):
502 595
             'l2_policy': {
503 596
                 "name": "test-l2-policy",
504 597
                 "description": "test L2 policy resource",
505
-                "l3_policy_id": "l3-policy-id"
598
+                "l3_policy_id": "l3-policy-id",
599
+                "shared": True
506 600
             }
507 601
         }).AndRaise(grouppolicy.NeutronClientException())
508 602
         self.m.ReplayAll()
@@ -590,7 +684,8 @@ class L3PolicyTest(HeatTestCase):
590 684
                 "description": "test L3 policy resource",
591 685
                 "ip_version": "4",
592 686
                 "ip_pool": "10.20.20.0",
593
-                "subnet_prefix_length": 24
687
+                "subnet_prefix_length": 24,
688
+                "shared": True
594 689
             }
595 690
         }).AndReturn({'l3_policy': {'id': '5678'}})
596 691
 
@@ -614,7 +709,8 @@ class L3PolicyTest(HeatTestCase):
614 709
                 "description": "test L3 policy resource",
615 710
                 "ip_version": "4",
616 711
                 "ip_pool": "10.20.20.0",
617
-                "subnet_prefix_length": 24
712
+                "subnet_prefix_length": 24,
713
+                "shared": True
618 714
             }
619 715
         }).AndRaise(grouppolicy.NeutronClientException())
620 716
         self.m.ReplayAll()
@@ -706,7 +802,8 @@ class PolicyClassifierTest(HeatTestCase):
706 802
                 "description": "test policy classifier resource",
707 803
                 "protocol": "tcp",
708 804
                 "port_range": "8000-9000",
709
-                "direction": "bi"
805
+                "direction": "bi",
806
+                "shared": True
710 807
             }
711 808
         }).AndReturn({'policy_classifier': {'id': '5678'}})
712 809
 
@@ -730,7 +827,8 @@ class PolicyClassifierTest(HeatTestCase):
730 827
                 "description": "test policy classifier resource",
731 828
                 "protocol": "tcp",
732 829
                 "port_range": "8000-9000",
733
-                "direction": "bi"
830
+                "direction": "bi",
831
+                "shared": True
734 832
             }
735 833
         }).AndRaise(grouppolicy.NeutronClientException())
736 834
         self.m.ReplayAll()
@@ -817,7 +915,8 @@ class PolicyActionTest(HeatTestCase):
817 915
                 "name": "test-policy-action",
818 916
                 "description": "test policy action resource",
819 917
                 "action_type": "redirect",
820
-                "action_value": "7890"
918
+                "action_value": "7890",
919
+                "shared": True
821 920
             }
822 921
         }).AndReturn({'policy_action': {'id': '5678'}})
823 922
 
@@ -840,7 +939,8 @@ class PolicyActionTest(HeatTestCase):
840 939
                 "name": "test-policy-action",
841 940
                 "description": "test policy action resource",
842 941
                 "action_type": "redirect",
843
-                "action_value": "7890"
942
+                "action_value": "7890",
943
+                "shared": True
844 944
             }
845 945
         }).AndRaise(grouppolicy.NeutronClientException())
846 946
         self.m.ReplayAll()
@@ -928,7 +1028,8 @@ class PolicyRuleTest(HeatTestCase):
928 1028
                 "description": "test policy rule resource",
929 1029
                 "enabled": True,
930 1030
                 "policy_classifier_id": "7890",
931
-                "policy_actions": ['3456', '1234']
1031
+                "policy_actions": ['3456', '1234'],
1032
+                "shared": True
932 1033
             }
933 1034
         }).AndReturn({'policy_rule': {'id': '5678'}})
934 1035
 
@@ -952,7 +1053,8 @@ class PolicyRuleTest(HeatTestCase):
952 1053
                 "description": "test policy rule resource",
953 1054
                 "enabled": True,
954 1055
                 "policy_classifier_id": "7890",
955
-                "policy_actions": ['3456', '1234']
1056
+                "policy_actions": ['3456', '1234'],
1057
+                "shared": True
956 1058
             }
957 1059
         }).AndRaise(grouppolicy.NeutronClientException())
958 1060
         self.m.ReplayAll()
@@ -1040,7 +1142,8 @@ class PolicyRuleSetTest(HeatTestCase):
1040 1142
                 "description": "test policy rule set resource",
1041 1143
                 "parent_id": "3456",
1042 1144
                 "child_policy_rule_sets": ["7890", "1234"],
1043
-                "policy_rules": ["2345", "6789"]
1145
+                "policy_rules": ["2345", "6789"],
1146
+                "shared": True
1044 1147
             }
1045 1148
         }).AndReturn({'policy_rule_set': {'id': '5678'}})
1046 1149
 
@@ -1064,7 +1167,8 @@ class PolicyRuleSetTest(HeatTestCase):
1064 1167
                 "description": "test policy rule set resource",
1065 1168
                 "parent_id": "3456",
1066 1169
                 "child_policy_rule_sets": ["7890", "1234"],
1067
-                "policy_rules": ["2345", "6789"]
1170
+                "policy_rules": ["2345", "6789"],
1171
+                "shared": True
1068 1172
             }
1069 1173
         }).AndRaise(grouppolicy.NeutronClientException())
1070 1174
         self.m.ReplayAll()
@@ -1156,7 +1260,8 @@ class NetworkServicePolicyTest(HeatTestCase):
1156 1260
                 "description": "test NSP resource",
1157 1261
                 "network_service_params": [
1158 1262
                     {'type': 'ip_single', 'name': 'vip',
1159
-                     'value': 'self_subnet'}]
1263
+                     'value': 'self_subnet'}],
1264
+                "shared": True
1160 1265
             }
1161 1266
         }).AndReturn({'network_service_policy': {'id': '5678'}})
1162 1267
 
@@ -1181,7 +1286,8 @@ class NetworkServicePolicyTest(HeatTestCase):
1181 1286
                 "description": "test NSP resource",
1182 1287
                 "network_service_params": [
1183 1288
                     {'type': 'ip_single', 'name': 'vip',
1184
-                     'value': 'self_subnet'}]
1289
+                     'value': 'self_subnet'}],
1290
+                "shared": True
1185 1291
             }
1186 1292
         }).AndRaise(grouppolicy.NeutronClientException())
1187 1293
         self.m.ReplayAll()
@@ -1253,3 +1359,387 @@ class NetworkServicePolicyTest(HeatTestCase):
1253 1359
         scheduler.TaskRunner(rsrc.update, update_template)()
1254 1360
 
1255 1361
         self.m.VerifyAll()
1362
+
1363
+
1364
+class ExternalPolicyTest(HeatTestCase):
1365
+
1366
+    def setUp(self):
1367
+        super(ExternalPolicyTest, self).setUp()
1368
+        self.m.StubOutWithMock(gbpclient.Client,
1369
+                               'create_external_policy')
1370
+        self.m.StubOutWithMock(gbpclient.Client,
1371
+                               'delete_external_policy')
1372
+        self.m.StubOutWithMock(gbpclient.Client,
1373
+                               'show_external_policy')
1374
+        self.m.StubOutWithMock(gbpclient.Client,
1375
+                               'update_external_policy')
1376
+        self.stub_keystoneclient()
1377
+
1378
+    def create_external_policy(self):
1379
+        gbpclient.Client.create_external_policy({
1380
+            'external_policy': {
1381
+                "name": "test-ep",
1382
+                "description": "test EP resource",
1383
+                "external_segments": ['1234'],
1384
+                "provided_policy_rule_sets": {
1385
+                    '2345': "scope1",
1386
+                    '8901': "scope2"
1387
+                },
1388
+                "consumed_policy_rule_sets": {
1389
+                    '9012': "scope3",
1390
+                    '9210': "scope4"
1391
+                },
1392
+                "shared": True
1393
+            }
1394
+        }).AndReturn({'external_policy': {'id': '5678'}})
1395
+
1396
+        snippet = template_format.parse(external_policy_template)
1397
+        stack = utils.parse_stack(snippet)
1398
+        resource_defns = stack.t.resource_definitions(stack)
1399
+        return grouppolicy.ExternalPolicy(
1400
+            'external_policy',
1401
+            resource_defns['external_policy'], stack)
1402
+
1403
+    def test_create(self):
1404
+        rsrc = self.create_external_policy()
1405
+        self.m.ReplayAll()
1406
+        scheduler.TaskRunner(rsrc.create)()
1407
+        self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
1408
+        self.m.VerifyAll()
1409
+
1410
+    def test_create_failed(self):
1411
+        gbpclient.Client.create_external_policy({
1412
+            'external_policy': {
1413
+                "name": "test-ep",
1414
+                "description": "test EP resource",
1415
+                "external_segments": ['1234'],
1416
+                "provided_policy_rule_sets": {
1417
+                    '2345': "scope1",
1418
+                    '8901': "scope2"
1419
+                },
1420
+                "consumed_policy_rule_sets": {
1421
+                    '9012': "scope3",
1422
+                    '9210': "scope4"
1423
+                },
1424
+                "shared": True
1425
+            }
1426
+        }).AndRaise(grouppolicy.NeutronClientException())
1427
+        self.m.ReplayAll()
1428
+
1429
+        snippet = template_format.parse(external_policy_template)
1430
+        stack = utils.parse_stack(snippet)
1431
+        resource_defns = stack.t.resource_definitions(stack)
1432
+        rsrc = grouppolicy.ExternalPolicy(
1433
+            'external_policy',
1434
+            resource_defns['external_policy'], stack)
1435
+
1436
+        error = self.assertRaises(exception.ResourceFailure,
1437
+                                  scheduler.TaskRunner(rsrc.create))
1438
+        self.assertEqual(
1439
+            'NeutronClientException: An unknown exception occurred.',
1440
+            str(error))
1441
+        self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
1442
+        self.m.VerifyAll()
1443
+
1444
+    def test_delete(self):
1445
+        gbpclient.Client.delete_external_policy('5678')
1446
+        gbpclient.Client.show_external_policy('5678').AndRaise(
1447
+            grouppolicy.NeutronClientException(status_code=404))
1448
+
1449
+        rsrc = self.create_external_policy()
1450
+        self.m.ReplayAll()
1451
+        scheduler.TaskRunner(rsrc.create)()
1452
+        scheduler.TaskRunner(rsrc.delete)()
1453
+        self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
1454
+        self.m.VerifyAll()
1455
+
1456
+    def test_delete_already_gone(self):
1457
+        gbpclient.Client.delete_external_policy('5678').AndRaise(
1458
+            grouppolicy.NeutronClientException(status_code=404))
1459
+
1460
+        rsrc = self.create_external_policy()
1461
+        self.m.ReplayAll()
1462
+        scheduler.TaskRunner(rsrc.create)()
1463
+        scheduler.TaskRunner(rsrc.delete)()
1464
+        self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
1465
+        self.m.VerifyAll()
1466
+
1467
+    def test_delete_failed(self):
1468
+        gbpclient.Client.delete_external_policy('5678').AndRaise(
1469
+            grouppolicy.NeutronClientException(status_code=400))
1470
+
1471
+        rsrc = self.create_external_policy()
1472
+        self.m.ReplayAll()
1473
+        scheduler.TaskRunner(rsrc.create)()
1474
+        error = self.assertRaises(exception.ResourceFailure,
1475
+                                  scheduler.TaskRunner(rsrc.delete))
1476
+        self.assertEqual(
1477
+            'NeutronClientException: An unknown exception occurred.',
1478
+            str(error))
1479
+        self.assertEqual((rsrc.DELETE, rsrc.FAILED), rsrc.state)
1480
+        self.m.VerifyAll()
1481
+
1482
+    def test_update(self):
1483
+        rsrc = self.create_external_policy()
1484
+        gbpclient.Client.update_external_policy(
1485
+            '5678', {'external_policy':
1486
+                     {'external_segments': ['9876']}})
1487
+        self.m.ReplayAll()
1488
+        scheduler.TaskRunner(rsrc.create)()
1489
+
1490
+        update_template = copy.deepcopy(rsrc.t)
1491
+        update_template['Properties']['external_segments'] = [
1492
+            '9876']
1493
+        scheduler.TaskRunner(rsrc.update, update_template)()
1494
+
1495
+        self.m.VerifyAll()
1496
+
1497
+
1498
+class ExternalSegmentTest(HeatTestCase):
1499
+
1500
+    def setUp(self):
1501
+        super(ExternalSegmentTest, self).setUp()
1502
+        self.m.StubOutWithMock(gbpclient.Client,
1503
+                               'create_external_segment')
1504
+        self.m.StubOutWithMock(gbpclient.Client,
1505
+                               'delete_external_segment')
1506
+        self.m.StubOutWithMock(gbpclient.Client,
1507
+                               'show_external_segment')
1508
+        self.m.StubOutWithMock(gbpclient.Client,
1509
+                               'update_external_segment')
1510
+        self.stub_keystoneclient()
1511
+
1512
+    def create_external_segment(self):
1513
+        gbpclient.Client.create_external_segment({
1514
+            'external_segment': {
1515
+                "name": "test-es",
1516
+                "description": "test ES resource",
1517
+                "ip_version": '6',
1518
+                "cidr": "192.168.0.0/24",
1519
+                "external_routes": [{
1520
+                    "destination": "0.0.0.0/0",
1521
+                    "nexthop": "null"
1522
+                }],
1523
+                "port_address_translation": True,
1524
+                "shared": True
1525
+            }
1526
+        }).AndReturn({'external_segment': {'id': '5678'}})
1527
+
1528
+        snippet = template_format.parse(external_segment_template)
1529
+        stack = utils.parse_stack(snippet)
1530
+        resource_defns = stack.t.resource_definitions(stack)
1531
+        return grouppolicy.ExternalSegment(
1532
+            'external_segment',
1533
+            resource_defns['external_segment'], stack)
1534
+
1535
+    def test_create(self):
1536
+        rsrc = self.create_external_segment()
1537
+        self.m.ReplayAll()
1538
+        scheduler.TaskRunner(rsrc.create)()
1539
+        self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
1540
+        self.m.VerifyAll()
1541
+
1542
+    def test_create_failed(self):
1543
+        gbpclient.Client.create_external_segment({
1544
+            'external_segment': {
1545
+                "name": "test-es",
1546
+                "description": "test ES resource",
1547
+                "ip_version": '6',
1548
+                "cidr": "192.168.0.0/24",
1549
+                "external_routes": [{
1550
+                    "destination": "0.0.0.0/0",
1551
+                    "nexthop": "null"
1552
+                }],
1553
+                "port_address_translation": True,
1554
+                "shared": True
1555
+            }
1556
+        }).AndRaise(grouppolicy.NeutronClientException())
1557
+        self.m.ReplayAll()
1558
+
1559
+        snippet = template_format.parse(external_segment_template)
1560
+        stack = utils.parse_stack(snippet)
1561
+        resource_defns = stack.t.resource_definitions(stack)
1562
+        rsrc = grouppolicy.ExternalSegment(
1563
+            'external_segment',
1564
+            resource_defns['external_segment'], stack)
1565
+
1566
+        error = self.assertRaises(exception.ResourceFailure,
1567
+                                  scheduler.TaskRunner(rsrc.create))
1568
+        self.assertEqual(
1569
+            'NeutronClientException: An unknown exception occurred.',
1570
+            str(error))
1571
+        self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
1572
+        self.m.VerifyAll()
1573
+
1574
+    def test_delete(self):
1575
+        gbpclient.Client.delete_external_segment('5678')
1576
+        gbpclient.Client.show_external_segment('5678').AndRaise(
1577
+            grouppolicy.NeutronClientException(status_code=404))
1578
+
1579
+        rsrc = self.create_external_segment()
1580
+        self.m.ReplayAll()
1581
+        scheduler.TaskRunner(rsrc.create)()
1582
+        scheduler.TaskRunner(rsrc.delete)()
1583
+        self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
1584
+        self.m.VerifyAll()
1585
+
1586
+    def test_delete_already_gone(self):
1587
+        gbpclient.Client.delete_external_segment('5678').AndRaise(
1588
+            grouppolicy.NeutronClientException(status_code=404))
1589
+
1590
+        rsrc = self.create_external_segment()
1591
+        self.m.ReplayAll()
1592
+        scheduler.TaskRunner(rsrc.create)()
1593
+        scheduler.TaskRunner(rsrc.delete)()
1594
+        self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
1595
+        self.m.VerifyAll()
1596
+
1597
+    def test_delete_failed(self):
1598
+        gbpclient.Client.delete_external_segment('5678').AndRaise(
1599
+            grouppolicy.NeutronClientException(status_code=400))
1600
+
1601
+        rsrc = self.create_external_segment()
1602
+        self.m.ReplayAll()
1603
+        scheduler.TaskRunner(rsrc.create)()
1604
+        error = self.assertRaises(exception.ResourceFailure,
1605
+                                  scheduler.TaskRunner(rsrc.delete))
1606
+        self.assertEqual(
1607
+            'NeutronClientException: An unknown exception occurred.',
1608
+            str(error))
1609
+        self.assertEqual((rsrc.DELETE, rsrc.FAILED), rsrc.state)
1610
+        self.m.VerifyAll()
1611
+
1612
+    def test_update(self):
1613
+        rsrc = self.create_external_segment()
1614
+        gbpclient.Client.update_external_segment(
1615
+            '5678', {'external_segment':
1616
+                     {"port_address_translation": False}})
1617
+        self.m.ReplayAll()
1618
+        scheduler.TaskRunner(rsrc.create)()
1619
+
1620
+        update_template = copy.deepcopy(rsrc.t)
1621
+        update_template['Properties']['port_address_translation'] = False
1622
+        scheduler.TaskRunner(rsrc.update, update_template)()
1623
+
1624
+        self.m.VerifyAll()
1625
+
1626
+
1627
+class NATPoolTest(HeatTestCase):
1628
+
1629
+    def setUp(self):
1630
+        super(NATPoolTest, self).setUp()
1631
+        self.m.StubOutWithMock(gbpclient.Client,
1632
+                               'create_nat_pool')
1633
+        self.m.StubOutWithMock(gbpclient.Client,
1634
+                               'delete_nat_pool')
1635
+        self.m.StubOutWithMock(gbpclient.Client,
1636
+                               'show_nat_pool')
1637
+        self.m.StubOutWithMock(gbpclient.Client,
1638
+                               'update_nat_pool')
1639
+        self.stub_keystoneclient()
1640
+
1641
+    def create_nat_pool(self):
1642
+        gbpclient.Client.create_nat_pool({
1643
+            'nat_pool': {
1644
+                "name": "test-nat-pool",
1645
+                "description": "test NP resource",
1646
+                "ip_version": '6',
1647
+                "ip_pool": "192.168.0.0/24",
1648
+                "external_segment_id": '1234',
1649
+                "shared": True
1650
+            }
1651
+        }).AndReturn({'nat_pool': {'id': '5678'}})
1652
+
1653
+        snippet = template_format.parse(nat_pool_template)
1654
+        stack = utils.parse_stack(snippet)
1655
+        resource_defns = stack.t.resource_definitions(stack)
1656
+        return grouppolicy.NATPool(
1657
+            'nat_pool',
1658
+            resource_defns['nat_pool'], stack)
1659
+
1660
+    def test_create(self):
1661
+        rsrc = self.create_nat_pool()
1662
+        self.m.ReplayAll()
1663
+        scheduler.TaskRunner(rsrc.create)()
1664
+        self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
1665
+        self.m.VerifyAll()
1666
+
1667
+    def test_create_failed(self):
1668
+        gbpclient.Client.create_nat_pool({
1669
+            'nat_pool': {
1670
+                "name": "test-nat-pool",
1671
+                "description": "test NP resource",
1672
+                "ip_version": '6',
1673
+                "ip_pool": "192.168.0.0/24",
1674
+                "external_segment_id": '1234',
1675
+                "shared": True
1676
+            }
1677
+        }).AndRaise(grouppolicy.NeutronClientException())
1678
+        self.m.ReplayAll()
1679
+
1680
+        snippet = template_format.parse(nat_pool_template)
1681
+        stack = utils.parse_stack(snippet)
1682
+        resource_defns = stack.t.resource_definitions(stack)
1683
+        rsrc = grouppolicy.NATPool(
1684
+            'nat_pool',
1685
+            resource_defns['nat_pool'], stack)
1686
+
1687
+        error = self.assertRaises(exception.ResourceFailure,
1688
+                                  scheduler.TaskRunner(rsrc.create))
1689
+        self.assertEqual(
1690
+            'NeutronClientException: An unknown exception occurred.',
1691
+            str(error))
1692
+        self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state)
1693
+        self.m.VerifyAll()
1694
+
1695
+    def test_delete(self):
1696
+        gbpclient.Client.delete_nat_pool('5678')
1697
+        gbpclient.Client.show_nat_pool('5678').AndRaise(
1698
+            grouppolicy.NeutronClientException(status_code=404))
1699
+
1700
+        rsrc = self.create_nat_pool()
1701
+        self.m.ReplayAll()
1702
+        scheduler.TaskRunner(rsrc.create)()
1703
+        scheduler.TaskRunner(rsrc.delete)()
1704
+        self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
1705
+        self.m.VerifyAll()
1706
+
1707
+    def test_delete_already_gone(self):
1708
+        gbpclient.Client.delete_nat_pool('5678').AndRaise(
1709
+            grouppolicy.NeutronClientException(status_code=404))
1710
+
1711
+        rsrc = self.create_nat_pool()
1712
+        self.m.ReplayAll()
1713
+        scheduler.TaskRunner(rsrc.create)()
1714
+        scheduler.TaskRunner(rsrc.delete)()
1715
+        self.assertEqual((rsrc.DELETE, rsrc.COMPLETE), rsrc.state)
1716
+        self.m.VerifyAll()
1717
+
1718
+    def test_delete_failed(self):
1719
+        gbpclient.Client.delete_nat_pool('5678').AndRaise(
1720
+            grouppolicy.NeutronClientException(status_code=400))
1721
+
1722
+        rsrc = self.create_nat_pool()
1723
+        self.m.ReplayAll()
1724
+        scheduler.TaskRunner(rsrc.create)()
1725
+        error = self.assertRaises(exception.ResourceFailure,
1726
+                                  scheduler.TaskRunner(rsrc.delete))
1727
+        self.assertEqual(
1728
+            'NeutronClientException: An unknown exception occurred.',
1729
+            str(error))
1730
+        self.assertEqual((rsrc.DELETE, rsrc.FAILED), rsrc.state)
1731
+        self.m.VerifyAll()
1732
+
1733
+    def test_update(self):
1734
+        rsrc = self.create_nat_pool()
1735
+        gbpclient.Client.update_nat_pool(
1736
+            '5678', {'nat_pool':
1737
+                     {"external_segment_id": '9876'}})
1738
+        self.m.ReplayAll()
1739
+        scheduler.TaskRunner(rsrc.create)()
1740
+
1741
+        update_template = copy.deepcopy(rsrc.t)
1742
+        update_template['Properties']['external_segment_id'] = '9876'
1743
+        scheduler.TaskRunner(rsrc.update, update_template)()
1744
+
1745
+        self.m.VerifyAll()

+ 1
- 0
test-requirements.txt View File

@@ -10,6 +10,7 @@ coverage>=3.6
10 10
 discover
11 11
 lockfile>=0.8
12 12
 mock>=1.0
13
+python-neutronclient==2.3.9
13 14
 python-subunit>=0.0.18
14 15
 mox>=0.5.3
15 16
 MySQL-python

Loading…
Cancel
Save