@@ -71,6 +71,12 @@ def parameters_argument(name): # type: (str) -> Dict[str, Any]
71
71
OPERATORS = ['<' , '<=' , '=' , '>' , '>=' , '¬=' , '==' , '!=' , 'EQ' , 'NE' , 'LT' ,
72
72
'LE' , 'GE' , 'GT' , 'IS' ]
73
73
74
+ ATTRIBUTE = 'attribute'
75
+ AND = 'and'
76
+ OR = 'or'
77
+ OPERATOR = 'operator'
78
+ VALUE = 'value'
79
+
74
80
RESOURCES_ARGUMENT = {
75
81
RESOURCES : {
76
82
'type' : 'dict' ,
@@ -84,37 +90,37 @@ def parameters_argument(name): # type: (str) -> Dict[str, Any]
84
90
'type' : 'dict' ,
85
91
'required' : False ,
86
92
'required_together' : [
87
- ('attribute' , 'value' )
93
+ (ATTRIBUTE , VALUE )
88
94
],
89
95
'required_one_of' : [
90
- ('attribute' , 'and' , 'or' )
96
+ (ATTRIBUTE , AND , OR )
91
97
],
92
98
'required_by' : {
93
- 'operator' : 'attribute'
99
+ OPERATOR : ATTRIBUTE
94
100
},
95
101
'mutually_exclusive' : [
96
- ('attribute' , 'and' , 'or' )
102
+ (ATTRIBUTE , AND , OR )
97
103
],
98
104
'options' : {
99
- 'attribute' : {
105
+ ATTRIBUTE : {
100
106
'type' : 'str' ,
101
107
'required' : False
102
108
},
103
- 'operator' : {
109
+ OPERATOR : {
104
110
'type' : 'str' ,
105
111
'required' : False ,
106
112
'choices' : OPERATORS
107
113
},
108
- 'value' : {
114
+ VALUE : {
109
115
'type' : 'str' ,
110
116
'required' : False
111
117
},
112
- 'and' : {
118
+ AND : {
113
119
'type' : 'list' ,
114
120
'elements' : 'dict' ,
115
121
'required' : False
116
122
},
117
- 'or' : {
123
+ OR : {
118
124
'type' : 'list' ,
119
125
'elements' : 'dict' ,
120
126
'required' : False
@@ -408,32 +414,32 @@ def get_resources_request_params(self): # type: () -> Dict[str, str]
408
414
if not request_params :
409
415
request_params = OrderedDict ({})
410
416
411
- and_item = complex_filter ['and' ]
412
- or_item = complex_filter ['or' ]
413
- attribute_item = complex_filter ['attribute' ]
417
+ and_item = complex_filter [AND ]
418
+ or_item = complex_filter [OR ]
419
+ attribute_item = complex_filter [ATTRIBUTE ]
414
420
415
421
if and_item is not None :
416
422
complex_filter_string = self ._get_filter (
417
423
and_item ,
418
424
complex_filter_string ,
419
425
' AND ' ,
420
- ' -> and'
426
+ ' -> ' + AND
421
427
)
422
428
423
429
if or_item is not None :
424
430
complex_filter_string = self ._get_filter (
425
431
or_item ,
426
432
complex_filter_string ,
427
433
' OR ' ,
428
- ' -> or'
434
+ ' -> ' + OR
429
435
)
430
436
431
437
if attribute_item is not None :
432
438
operator = self ._convert_filter_operator (
433
- complex_filter ['operator' ],
439
+ complex_filter [OPERATOR ],
434
440
""
435
441
)
436
- value = complex_filter ['value' ]
442
+ value = complex_filter [VALUE ]
437
443
438
444
if operator == '¬=' :
439
445
# Provides a filter string in the format NOT(FOO=='BAR')
@@ -597,12 +603,7 @@ def _get_filter(self, list_of_filters, complex_filter_string, joiner, path):
597
603
"resources -> complex_filter%s" % (type (i ), path )
598
604
)
599
605
600
- and_item = i .get ('and' )
601
- or_item = i .get ('or' )
602
- attribute = i .get ('attribute' )
603
- op = i .get ('operator' )
604
-
605
- valid_keys = ['and' , 'attribute' , 'operator' , 'or' , 'value' ]
606
+ valid_keys = [AND , ATTRIBUTE , OPERATOR , OR , VALUE ]
606
607
diff = set (i .keys ()) - set (valid_keys )
607
608
if len (diff ) != 0 :
608
609
self ._fail (
@@ -612,25 +613,41 @@ def _get_filter(self, list_of_filters, complex_filter_string, joiner, path):
612
613
% (", " .join (diff ), path , ", " .join (valid_keys ))
613
614
)
614
615
616
+ # Validate required_one_of
617
+ and_item = i .get (AND )
618
+ or_item = i .get (OR )
619
+ attribute = i .get (ATTRIBUTE )
620
+
621
+ if not and_item and not or_item and not attribute :
622
+ self ._fail (
623
+ "one of the following is required: %s found"
624
+ " in resources -> complex_filter%s"
625
+ % (", " .join ([ATTRIBUTE , AND , OR ]), path )
626
+ )
627
+
628
+ # Validate required_by
629
+ op = i .get (OPERATOR )
630
+
615
631
if op and not attribute :
616
632
self ._fail (
617
- "missing parameter(s) required by 'operator': attribute"
633
+ "missing parameter(s) required by '%s': %s"
634
+ % (OPERATOR , ATTRIBUTE )
618
635
)
619
636
620
637
# Validate mutually exclusive parameters
621
638
if (and_item and or_item ) or (and_item and attribute ) or \
622
639
(or_item and attribute ):
623
640
self ._fail (
624
- 'parameters are mutually exclusive: attribute|and|or found '
625
- 'in resources -> complex_filter%s' % path
641
+ 'parameters are mutually exclusive: %s|%s|%s found in '
642
+ 'resources -> complex_filter%s' % ( ATTRIBUTE , AND , OR , path )
626
643
)
627
644
628
645
if and_item is not None :
629
646
and_filter_string = self ._get_filter (
630
647
and_item ,
631
648
'' ,
632
649
' AND ' ,
633
- path + ' -> and'
650
+ '%s -> %s' % ( path , AND )
634
651
)
635
652
complex_filter_string = _append_filter_string (
636
653
complex_filter_string ,
@@ -641,20 +658,39 @@ def _get_filter(self, list_of_filters, complex_filter_string, joiner, path):
641
658
or_item ,
642
659
'' ,
643
660
' OR ' ,
644
- path + ' -> or'
661
+ '%s -> %s' % ( path , OR )
645
662
)
646
663
complex_filter_string = _append_filter_string (
647
664
complex_filter_string ,
648
665
or_filter_string , joiner
649
666
)
650
667
if attribute is not None :
651
668
operator = self ._convert_filter_operator (op , path )
652
- value = i .get ('value' )
669
+
670
+ # Validate attribute type
671
+ if not isinstance (attribute , str ):
672
+ self ._fail (
673
+ "%s must be of type str, was: %s found in "
674
+ "resources -> complex_filter%s"
675
+ % (ATTRIBUTE , type (attribute ), path )
676
+ )
677
+
678
+ value = i .get (VALUE )
653
679
654
680
if value is None :
655
681
self ._fail (
656
- 'parameters are required together: attribute, value '
657
- 'found in resources -> complex_filter%s' % path )
682
+ 'parameters are required together: %s, %s found in '
683
+ 'resources -> complex_filter%s'
684
+ % (ATTRIBUTE , VALUE , path )
685
+ )
686
+
687
+ # Validate value type
688
+ if not isinstance (value , str ):
689
+ self ._fail (
690
+ "%s must be of type str, was: %s found in "
691
+ "resources -> complex_filter%s"
692
+ % (VALUE , type (value ), path )
693
+ )
658
694
659
695
if operator == '¬=' :
660
696
# Provides a filter string in the format NOT(FOO=='BAR')
0 commit comments