48
48
GET_PARAMETERS = 'get_parameters'
49
49
50
50
51
- def _complex_filter ():
52
- return {
53
- 'type' : 'dict' ,
54
- 'required' : False ,
55
- 'required_together' : [
56
- ('attribute' , 'value' )
57
- ],
58
- 'required_one_of' : [
59
- ('attribute' , 'and' , 'or' )
60
- ],
61
- 'required_by' : {
62
- 'operator' : 'attribute'
63
- },
64
- 'mutually_exclusive' : [
65
- ('attribute' , 'and' , 'or' )
66
- ],
67
- 'options' : {
68
- 'attribute' : {
69
- 'type' : 'str' ,
70
- 'required' : False
71
- },
72
- 'operator' : {
73
- 'type' : 'str' ,
74
- 'required' : False ,
75
- 'choices' : ['<' , '<=' , '=' , '>' , '>=' , '¬=' , '==' , '!=' , 'EQ' ,
76
- 'NE' , 'LT' , 'LE' , 'GE' , 'GT' , 'IS' ]
77
- },
78
- 'value' : {
79
- 'type' : 'str' ,
80
- 'required' : False
81
- },
82
- 'and' : {
83
- 'type' : 'list' ,
84
- 'elements' : 'dict' ,
85
- 'required' : False
86
- },
87
- 'or' : {
88
- 'type' : 'list' ,
89
- 'elements' : 'dict' ,
90
- 'required' : False
91
- }
92
- }
93
- }
94
-
95
-
96
51
def parameters_argument (name ): # type: (str) -> Dict[str, Any]
97
52
return {
98
53
name : {
@@ -113,6 +68,9 @@ def parameters_argument(name): # type: (str) -> Dict[str, Any]
113
68
}
114
69
115
70
71
+ OPERATORS = ['<' , '<=' , '=' , '>' , '>=' , '¬=' , '==' , '!=' , 'EQ' , 'NE' , 'LT' ,
72
+ 'LE' , 'GE' , 'GT' , 'IS' ]
73
+
116
74
RESOURCES_ARGUMENT = {
117
75
RESOURCES : {
118
76
'type' : 'dict' ,
@@ -122,7 +80,47 @@ def parameters_argument(name): # type: (str) -> Dict[str, Any]
122
80
'type' : 'dict' ,
123
81
'required' : False
124
82
},
125
- COMPLEX_FILTER : _complex_filter (),
83
+ COMPLEX_FILTER : {
84
+ 'type' : 'dict' ,
85
+ 'required' : False ,
86
+ 'required_together' : [
87
+ ('attribute' , 'value' )
88
+ ],
89
+ 'required_one_of' : [
90
+ ('attribute' , 'and' , 'or' )
91
+ ],
92
+ 'required_by' : {
93
+ 'operator' : 'attribute'
94
+ },
95
+ 'mutually_exclusive' : [
96
+ ('attribute' , 'and' , 'or' )
97
+ ],
98
+ 'options' : {
99
+ 'attribute' : {
100
+ 'type' : 'str' ,
101
+ 'required' : False
102
+ },
103
+ 'operator' : {
104
+ 'type' : 'str' ,
105
+ 'required' : False ,
106
+ 'choices' : OPERATORS
107
+ },
108
+ 'value' : {
109
+ 'type' : 'str' ,
110
+ 'required' : False
111
+ },
112
+ 'and' : {
113
+ 'type' : 'list' ,
114
+ 'elements' : 'dict' ,
115
+ 'required' : False
116
+ },
117
+ 'or' : {
118
+ 'type' : 'list' ,
119
+ 'elements' : 'dict' ,
120
+ 'required' : False
121
+ }
122
+ }
123
+ },
126
124
GET_PARAMETERS :
127
125
parameters_argument (GET_PARAMETERS ).get (GET_PARAMETERS )
128
126
}
@@ -431,8 +429,9 @@ def get_resources_request_params(self): # type: () -> Dict[str, str]
431
429
)
432
430
433
431
if attribute_item is not None :
434
- operator = _convert_filter_operator (
435
- complex_filter ['operator' ]
432
+ operator = self ._convert_filter_operator (
433
+ complex_filter ['operator' ],
434
+ ""
436
435
)
437
436
value = complex_filter ['value' ]
438
437
@@ -584,12 +583,35 @@ def append_attributes(self, element):
584
583
585
584
def _get_filter (self , list_of_filters , complex_filter_string , joiner , path ):
586
585
# type: (List[Dict], str, str, str) -> str
586
+
587
+ if not isinstance (list_of_filters , list ):
588
+ self ._fail (
589
+ "nested filters must be a list, was: %s found in "
590
+ "resources -> complex_filter%s"
591
+ % (type (list_of_filters ), path )
592
+ )
587
593
for i in list_of_filters :
594
+ if not isinstance (i , dict ):
595
+ self ._fail (
596
+ "nested filter must be of type dict, was: %s found in "
597
+ "resources -> complex_filter%s" % (type (i ), path )
598
+ )
599
+
588
600
and_item = i .get ('and' )
589
601
or_item = i .get ('or' )
590
602
attribute = i .get ('attribute' )
591
603
op = i .get ('operator' )
592
604
605
+ valid_keys = ['and' , 'attribute' , 'operator' , 'or' , 'value' ]
606
+ diff = set (i .keys ()) - set (valid_keys )
607
+ if len (diff ) != 0 :
608
+ self ._fail (
609
+ "Unsupported parameters for (basic.py) module: %s found"
610
+ " in resources -> complex_filter%s. Supported parameters "
611
+ "include: %s"
612
+ % (", " .join (diff ), path , ", " .join (valid_keys ))
613
+ )
614
+
593
615
if op and not attribute :
594
616
self ._fail (
595
617
"missing parameter(s) required by 'operator': attribute"
@@ -600,7 +622,7 @@ def _get_filter(self, list_of_filters, complex_filter_string, joiner, path):
600
622
(or_item and attribute ):
601
623
self ._fail (
602
624
'parameters are mutually exclusive: attribute|and|or found '
603
- 'in resources -> complex_filter' + path
625
+ 'in resources -> complex_filter%s' % path
604
626
)
605
627
606
628
if and_item is not None :
@@ -626,13 +648,13 @@ def _get_filter(self, list_of_filters, complex_filter_string, joiner, path):
626
648
or_filter_string , joiner
627
649
)
628
650
if attribute is not None :
629
- operator = _convert_filter_operator (op )
651
+ operator = self . _convert_filter_operator (op , path )
630
652
value = i .get ('value' )
631
653
632
654
if value is None :
633
655
self ._fail (
634
656
'parameters are required together: attribute, value '
635
- 'found in resources -> complex_filter' + path )
657
+ 'found in resources -> complex_filter%s' % path )
636
658
637
659
if operator == '¬=' :
638
660
# Provides a filter string in the format NOT(FOO=='BAR')
@@ -650,30 +672,34 @@ def _get_filter(self, list_of_filters, complex_filter_string, joiner, path):
650
672
651
673
return complex_filter_string
652
674
675
+ def _convert_filter_operator (self , operator , path ):
676
+ if operator in ['<' , 'LT' ]:
677
+ return '<'
678
+ if operator in ['<=' , 'LE' ]:
679
+ return '<='
680
+ if operator in ['=' , 'EQ' , None ]:
681
+ return '='
682
+ if operator in ['>=' , 'GE' ]:
683
+ return '>='
684
+ if operator in ['>' , 'GT' ]:
685
+ return '>'
686
+ if operator in ['¬=' , '!=' , 'NE' ]:
687
+ return '¬='
688
+ if operator in ['==' , 'IS' ]:
689
+ return '=='
690
+ self ._fail (
691
+ 'value of operator must be one of: %s, got: %s found in '
692
+ 'resources -> complex_filter%s'
693
+ % (", " .join (OPERATORS ), operator , path )
694
+ )
695
+
653
696
def _fail (self , msg ): # type: (str) -> None
654
697
self ._module .fail_json (msg = msg , ** self .result )
655
698
656
699
def _fail_tb (self , msg , tb ): # type: (str, str) -> None
657
700
self ._module .fail_json (msg = msg , exception = tb , ** self .result )
658
701
659
702
660
- def _convert_filter_operator (operator ):
661
- if operator in ['<' , 'LT' ]:
662
- return '<'
663
- if operator in ['<=' , 'LE' ]:
664
- return '<='
665
- if operator in ['=' , 'EQ' , None ]:
666
- return '='
667
- if operator in ['>=' , 'GE' ]:
668
- return '>='
669
- if operator in ['>' , 'GT' ]:
670
- return '>'
671
- if operator in ['¬=' , '!=' , 'NE' ]:
672
- return '¬='
673
- if operator in ['==' , 'IS' ]:
674
- return '=='
675
-
676
-
677
703
def _append_filter_string (existing , to_append , joiner = ' AND ' ):
678
704
# joiner is ' AND ' or ' OR '
679
705
if not existing :
0 commit comments