Completed
Pull Request — master (#466)
by
unknown
02:36
created

OrionBaseAction   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 116
Duplicated Lines 0 %
Metric Value
wmc 29
dl 0
loc 116
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A query() 0 2 1
A connect() 0 7 2
A __init__() 0 7 2
A invoke() 0 2 1
B get_node_id() 0 16 5
A create() 0 2 1
A send_user_error() 0 2 1
B get_ncm_transfer_results() 0 27 5
B status_code_to_text() 0 16 6
B get_ncm_node_id() 0 25 5
1
# Licensed to the StackStorm, Inc ('StackStorm') under one or more
2
# contributor license agreements.  See the NOTICE file distributed with
3
# this work for additional information regarding copyright ownership.
4
# The ASF licenses this file to You under the Apache License, Version 2.0
5
# (the "License"); you may not use this file except in compliance with
6
# the License.  You may obtain a copy of the License at
7
#
8
#     http://www.apache.org/licenses/LICENSE-2.0
9
#
10
# Unless required by applicable law or agreed to in writing, software
11
# distributed under the License is distributed on an "AS IS" BASIS,
12
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
# See the License for the specific language governing permissions and
14
# limitations under the License.
15
16
import time
17
18
from st2actions.runners.pythonrunner import Action
19
from orionsdk import SwisClient
20
21
22
class OrionBaseAction(Action):
23
    def __init__(self, config):
24
        super(OrionBaseAction, self).__init__(config)
25
26
        self.client = None
27
28
        if "orion" not in self.config:
29
            raise ValueError("Orion host details not in the config.yaml")
30
31
    def connect(self, platform):
32
        try:
33
            self.client = SwisClient(self.config['orion'][platform]['host'],
34
                                   self.config['orion'][platform]['user'],
35
                                   self.config['orion'][platform]['password'])
36
        except KeyError:
37
            raise ValueError("Orion host details not in the config.yaml")
38
39
    def query(self, swql, **kargs):
40
        return self.client.query(swql, **kargs)
41
42
    def invoke(self, entity, verb, *args):
43
        return self.client.invoke(entity, verb, *args)
44
45
    def create(self, entity, **kargs):
46
        return self.client.create(entity, **kargs)
47
48
    def get_node_id(self, caption):
49
        swql = "SELECT NodeID FROM Orion.Nodes WHERE Caption=@caption"
50
        kargs = {'caption': caption}
51
        data = self.query(swql, **kargs)
52
53
        if len(data['results']) == 1:
54
            try:
55
                return data['results'][0]['NodeID']
56
            except IndexError:
57
                raise ValueError("Invalid Node")
58
        elif len(data['results']) >= 2:
59
            raise ValueError("Muliple Nodes match '{}' Caption".format(
60
                caption))
61
        elif len(data['results']) == 0:
62
            raise ValueError("No matching Caption for '{}'".format(
63
                caption))
64
65
    def get_ncm_node_id(self, caption):
66
        """
67
        Queries the Network configuration Manager nodes table on the Orion
68
        platform for the NodeID of a given node name (aka NodeCaption).
69
70
        Raises: IndexError on Invalid number of nodes (e.g. 0 or 2+).
71
72
        Returns: A single node id.
73
        """
74
75
        swql = "SELECT NodeID FROM Cirrus.Nodes WHERE NodeCaption=@node"
76
        kargs = {'node': caption}
77
        data = self.query(swql, **kargs)
78
79
        if len(data['results']) == 1:
80
            try:
81
                return data['results'][0]['NodeID']
82
            except IndexError:
83
                raise IndexError("Invalid Node")
84
        elif len(data['results']) >= 2:
85
            raise IndexError("Muliple Nodes match '{}' NodeCaption".format(
86
                caption))
87
        elif len(data['results']) == 0:
88
            raise IndexError("No matching NodeCaption for '{}'".format(
89
                caption))
90
91
    def get_ncm_transfer_results(self, transfer_id):
92
        ts = {}
93
        while True:
94
            swql = """SELECT TransferID, Action, Status, ErrorMessage,
95
            DeviceOutput FROM NCM.TransferResults
96
            WHERE TransferID=@transfer_id"""
97
            kargs = {'transfer_id': transfer_id}
98
99
            transfer_data = self.query(swql, **kargs)
100
            status = transfer_data['results'][0]['Status']
101
102
            if status == 1:
103
                time.sleep(10)
104
            elif status == 2:
105
                ts['status'] = "Complete"
106
                break
107
            elif status == 3:
108
                ts['status'] = "Error"
109
                ts['ErrorMessage'] = transfer_data['results'][0][
110
                    'ErrorMessage']
111
                break
112
            else:
113
                ts['status'] = "Unknown"
114
                ts['ErrorMessage'] = "Invalid stauts: {}".format(status)
115
                break
116
117
        return ts
118
119
    def status_code_to_text(self, status):
120
        """
121
        Takes an Solarwinds Orion status code and translates it to
122
        human text and also a colour that can be used in Slack.
123
        """
124
125
        if status == 0:
126
            return ("Unknown", "grey")
127
        elif status == 1:
128
            return ("Up", "good")
129
        elif status == 2:
130
            return ("Down", "danger")
131
        elif status == 3:
132
            return ("Warning", "warning")
133
        elif status == 14:
134
            return ("Critical", "danger")
135
136
    def send_user_error(self, message):
137
        print(message)
138