khenaidoo | fdbad6e | 2018-11-06 22:26:38 -0500 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | # |
| 3 | # Copyright 2017 the original author or authors. |
| 4 | # |
| 5 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | # you may not use this file except in compliance with the License. |
| 7 | # You may obtain a copy of the License at |
| 8 | # |
| 9 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | # |
| 11 | # Unless required by applicable law or agreed to in writing, software |
| 12 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | # See the License for the specific language governing permissions and |
| 15 | # limitations under the License. |
| 16 | # |
| 17 | |
| 18 | """ |
| 19 | Alarm filter CLI commands |
| 20 | """ |
| 21 | from optparse import make_option, OptionValueError |
| 22 | |
| 23 | from cmd2 import Cmd, options |
| 24 | from google.protobuf.empty_pb2 import Empty |
| 25 | |
| 26 | from table import print_pb_list_as_table |
Arun Arora | ed4b760 | 2019-04-02 18:42:37 +0000 | [diff] [blame] | 27 | from voltha_protos import voltha_pb2 |
| 28 | from voltha_protos.events_pb2 import AlarmEventType, AlarmEventSeverity, AlarmEventCategory |
khenaidoo | fdbad6e | 2018-11-06 22:26:38 -0500 | [diff] [blame] | 29 | |
khenaidoo | fdbad6e | 2018-11-06 22:26:38 -0500 | [diff] [blame] | 30 | |
| 31 | |
| 32 | class AlarmFiltersCli(Cmd): |
| 33 | def __init__(self, get_stub): |
| 34 | Cmd.__init__(self) |
| 35 | self.get_stub = get_stub |
| 36 | self.prompt = '(' + self.colorize( |
| 37 | self.colorize('alarm_filters', 'red'), 'bold') + ') ' |
| 38 | |
| 39 | def cmdloop(self): |
| 40 | self._cmdloop() |
| 41 | |
| 42 | def help_show(self): |
| 43 | self.poutput( |
| 44 | ''' |
| 45 | Display the list of configured filters. |
| 46 | |
| 47 | Valid options: |
| 48 | |
| 49 | -i FILTER_ID | --filter-id=FILTER_ID Display the filter rules for a specific filter id (OPTIONAL) |
| 50 | |
| 51 | ''' |
| 52 | ) |
| 53 | |
| 54 | @options([ |
| 55 | make_option('-i', '--filter-id', action="store", dest='filter_id') |
| 56 | ]) |
| 57 | def do_show(self, line, opts): |
| 58 | stub = self.get_stub() |
| 59 | |
| 60 | if not opts.filter_id: |
| 61 | result = stub.ListAlarmFilters(Empty()) |
| 62 | print_pb_list_as_table("Alarm Filters:", result.filters, {}, self.poutput) |
| 63 | else: |
| 64 | result = stub.GetAlarmFilter(voltha_pb2.ID(id=opts.filter_id)) |
| 65 | print_pb_list_as_table("Rules for Filter ID = {}:".format(opts.filter_id), |
| 66 | result.rules, {}, self.poutput) |
| 67 | |
| 68 | @staticmethod |
| 69 | def construct_rule(raw_rule): |
| 70 | rule = dict() |
| 71 | |
| 72 | rule_kv = raw_rule.strip().split(':') |
| 73 | |
| 74 | if len(rule_kv) == 2: |
| 75 | rule['key'] = rule_kv[0].lower() |
| 76 | rule['value'] = rule_kv[1].lower() |
| 77 | else: |
| 78 | raise OptionValueError("Error: A rule must be a colon separated key/value pair") |
| 79 | |
| 80 | return rule |
| 81 | |
| 82 | def parse_filter_rules(option, opt_str, value, parser): |
| 83 | rules = getattr(parser.values, option.dest) |
| 84 | if rules is None: |
| 85 | rules = list() |
| 86 | rules.append(AlarmFiltersCli.construct_rule(value)) |
| 87 | |
| 88 | for arg in parser.rargs: |
| 89 | if (arg[:2] == "--" and len(arg) > 2) or (arg[:1] == "-" and len(arg) > 1 and arg[1] != "-"): |
| 90 | break |
| 91 | else: |
| 92 | rules.append(AlarmFiltersCli.construct_rule(arg)) |
| 93 | |
| 94 | setattr(parser.values, option.dest, rules) |
| 95 | else: |
| 96 | raise OptionValueError('Warning: The filter rule option can only be specified once') |
| 97 | |
| 98 | def help_create(self): |
| 99 | types = list( |
| 100 | k for k, v in |
| 101 | AlarmEventType.DESCRIPTOR.enum_values_by_name.items()) |
| 102 | categories = list( |
| 103 | k for k, v in |
| 104 | AlarmEventCategory.DESCRIPTOR.enum_values_by_name.items()) |
| 105 | severities = list( |
| 106 | k for k, v in |
| 107 | AlarmEventSeverity.DESCRIPTOR.enum_values_by_name.items()) |
| 108 | |
| 109 | alarm_types = types |
| 110 | alarm_categories = categories |
| 111 | alarm_severities = severities |
| 112 | |
| 113 | usage = ''' |
| 114 | Create a new alarm filter. |
| 115 | |
| 116 | Valid options: |
| 117 | |
| 118 | -r rule:value ... | --filter-rules rule:value ... Specify one or more filter rules as key/value pairs (REQUIRED) |
| 119 | |
| 120 | Valid rule keys and expected values: |
| 121 | |
| 122 | id : Identifier of an incoming alarm |
| 123 | type : Type of an incoming alarm {} |
| 124 | category : Category of an incoming alarm {} |
| 125 | severity : Severity of an incoming alarm {} |
| 126 | resource_id : Resource identifier of an incoming alarm |
| 127 | device_id : Device identifier of an incoming alarm |
| 128 | |
| 129 | Example: |
| 130 | |
| 131 | # Filter any alarm that matches the following criteria |
| 132 | |
| 133 | create -r type:environment severity:indeterminate |
| 134 | create -r device_id:754f9dcbe4a6 |
| 135 | |
| 136 | '''.format(alarm_types, alarm_categories, alarm_severities) |
| 137 | |
| 138 | self.poutput(usage) |
| 139 | |
| 140 | @options([ |
| 141 | make_option('-r', '--filter-rules', help='<key>:<value>...', action="callback", |
| 142 | callback=parse_filter_rules, type='string', dest='filter_rules'), |
| 143 | ]) |
| 144 | def do_create(self, line, opts): |
| 145 | if opts.filter_rules: |
| 146 | stub = self.get_stub() |
| 147 | result = stub.CreateAlarmFilter(voltha_pb2.AlarmFilter(rules=opts.filter_rules)) |
| 148 | print_pb_list_as_table("Rules for Filter ID = {}:".format(result.id), |
| 149 | result.rules, {}, self.poutput) |
| 150 | |
| 151 | def help_delete(self): |
| 152 | self.poutput( |
| 153 | ''' |
| 154 | Delete a specific alarm filter entry. |
| 155 | |
| 156 | Valid options: |
| 157 | |
| 158 | -i FILTER_ID | --filter-id=FILTER_ID Display the filter rules for a specific filter id (REQUIRED) |
| 159 | |
| 160 | ''' |
| 161 | ) |
| 162 | |
| 163 | @options([ |
| 164 | make_option('-i', '--filter-id', action="store", dest='filter_id') |
| 165 | ]) |
| 166 | def do_delete(self, line, opts): |
| 167 | if not opts.filter_id: |
| 168 | self.poutput(self.colorize('Error: ', 'red') + 'Specify ' + \ |
| 169 | self.colorize(self.colorize('"filter id"', 'blue'), |
| 170 | 'bold') + ' to update') |
| 171 | return |
| 172 | |
| 173 | stub = self.get_stub() |
| 174 | stub.DeleteAlarmFilter(voltha_pb2.ID(id=opts.filter_id)) |
| 175 | |
| 176 | def help_update(self): |
| 177 | types = list( |
| 178 | k for k, v in |
| 179 | AlarmEventType.DESCRIPTOR.enum_values_by_name.items()) |
| 180 | categories = list( |
| 181 | k for k, v in |
| 182 | AlarmEventCategory.DESCRIPTOR.enum_values_by_name.items()) |
| 183 | severities = list( |
| 184 | k for k, v in |
| 185 | AlarmEventSeverity.DESCRIPTOR.enum_values_by_name.items()) |
| 186 | |
| 187 | alarm_types = types |
| 188 | alarm_categories = categories |
| 189 | alarm_severities = severities |
| 190 | |
| 191 | usage = ''' |
| 192 | Update the filter rules for an existing alarm filter. |
| 193 | |
| 194 | Valid options: |
| 195 | |
| 196 | -i FILTER_ID | --filter-id=FILTER_ID Indicate the alarm filter identifier to update (REQUIRED) |
| 197 | -r rule:value ... | --filter-rules rule:value ... Specify one or more filter rules as key/value pairs (REQUIRED) |
| 198 | |
| 199 | Valid rule keys and expected values: |
| 200 | |
| 201 | id : Identifier of an incoming alarm |
| 202 | type : Type of an incoming alarm {} |
| 203 | category : Category of an incoming alarm {} |
| 204 | severity : Severity of an incoming alarm {} |
| 205 | resource_id : Resource identifier of an incoming alarm |
| 206 | device_id : Device identifier of an incoming alarm |
| 207 | |
| 208 | Example: |
| 209 | |
| 210 | # Filter any alarm that matches the following criteria |
| 211 | |
| 212 | update -i 9da115b900bc -r type:environment severity:indeterminate resource_id:1554b0517a07 |
| 213 | |
| 214 | '''.format(alarm_types, alarm_categories, alarm_severities) |
| 215 | |
| 216 | self.poutput(usage) |
| 217 | |
| 218 | @options([ |
| 219 | make_option('-r', '--filter-rules', help='<key>:<value>...', action="callback", |
| 220 | callback=parse_filter_rules, type='string', dest='filter_rules'), |
| 221 | make_option('-i', '--filter-id', action="store", dest='filter_id') |
| 222 | ]) |
| 223 | def do_update(self, line, opts): |
| 224 | if not opts.filter_id: |
| 225 | self.poutput(self.colorize('Error: ', 'red') + 'Specify ' + \ |
| 226 | self.colorize(self.colorize('"filter id"', 'blue'), |
| 227 | 'bold') + ' to update') |
| 228 | return |
| 229 | |
| 230 | if opts.filter_rules: |
| 231 | stub = self.get_stub() |
| 232 | result = stub.UpdateAlarmFilter( |
| 233 | voltha_pb2.AlarmFilter(id=opts.filter_id, rules=opts.filter_rules) |
| 234 | ) |
| 235 | print_pb_list_as_table("Rules for Filter ID = {}:".format(result.id), |
| 236 | result.rules, {}, self.poutput) |