Completed
Pull Request — master (#487)
by
unknown
02:57
created

OrionBaseAction.get_ncm_transfer_results()   B

Complexity

Conditions 5

Size

Total Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 5
c 2
b 0
f 0
dl 0
loc 38
rs 8.0894
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
from lib.node import OrionNode
22
from lib.utils import send_user_error, is_ip
23
24
25
class OrionBaseAction(Action):
26
    def __init__(self, config):
27
        super(OrionBaseAction, self).__init__(config)
28
29
        self.client = None
30
31
        if "orion" not in self.config:
32
            raise ValueError("Orion host details not in the config.yaml")
33
34
    def connect(self, platform):
35
        """
36
        Connect to an Orion platform from the packs config.yaml.
37
        """
38
        if platform is None:
39
            try:
40
                platform = self.config['defaults']['platform']
41
            except IndexError:
42
                send_user_error("No default Orion platform.")
43
                raise ValueError("No default Orion platform.")
44
45
        self.logger.debug("Connecting to Orion platform: {}".format(platform))
46
47
        try:
48
            self.client = SwisClient(
49
                self.config['orion'][platform]['host'],
50
                self.config['orion'][platform]['user'],
51
                self.config['orion'][platform]['password'])
52
        except KeyError:
53
            raise ValueError("Orion host details not in the config.yaml")
54
55
        return platform
56
57
    def get_node(self, node):
58
        """
59
        Get an OrionNode object
60
        """
61
62
        orion_node = OrionNode()
63
64
        if is_ip(node):
65
            query_for_where = "IPAddress"
66
        else:
67
            query_for_where = "Caption"
68
69
        swql = """SELECT NodeID, Uri, IPAddress, Caption
70
        FROM Orion.Nodes
71
        WHERE {}=@query_on""".format(query_for_where)
72
        kargs = {'query_on': node}
73
        data = self.query(swql, **kargs)
74
75
        if len(data['results']) == 1:
76
            try:
77
                orion_node.npm_id = data['results'][0]['NodeID']
78
                orion_node.uri = data['results'][0]['Uri']
79
                orion_node.ip_address = data['results'][0]['IPAddress']
80
                orion_node.caption = data['results'][0]['Caption']
81
            except IndexError:
82
                pass
83
        elif len(data['results']) >= 2:
84
            self.logger.debug(
85
                "Muliple Nodes match '{}' Caption: {}".format(
86
                    node, data))
87
            raise ValueError("Muliple Nodes match '{}' Caption".format(
88
                node))
89
90
        if orion_node.npm:
91
            swql = """SELECT NodeID
92
            FROM Cirrus.Nodes
93
            WHERE CoreNodeID=@CoreNodeID"""
94
            kargs = {'CoreNodeID': orion_node.npm_id}
95
            data = self.query(swql, **kargs)
96
97
            if len(data['results']) == 1:
98
                try:
99
                    orion_node.ncm_id = data['results'][0]['NodeID']
100
                except IndexError:
101
                    pass
102
103
        return orion_node
104
105
    def query(self, swql, **kargs):
106
        """
107
        Run SWQL against the Orion Platform.
108
        """
109
        return self.client.query(swql, **kargs)
110
111
    def invoke(self, entity, verb, *args):
112
        """
113
        Run an Invoke against the Orion Platform.
114
        """
115
        return self.client.invoke(entity, verb, *args)
116
117
    def create(self, entity, **kargs):
118
        """
119
        Run an Create against the Orion Platform.
120
        """
121
        return self.client.create(entity, **kargs)
122
123
    def read(self, uri):
124
        """
125
        Run an Read against the Orion Platform.
126
        """
127
        return self.client.read(uri)
128
129
    def update(self, uri, **kargs):
130
        """
131
        Run an Update against the Orion Platform.
132
        """
133
        return self.client.update(uri, **kargs)
134
135
    def delete(self, uri):
136
        """
137
        Run an Delete of an URI against the Orion Platform.
138
        """
139
        return self.client.delete(uri)
140
141
    def get_snmp_community(self, community, std_community):
142
        """
143
        Return the correct SNMP comminity to use.
144
        """
145
        if community is not None:
146
            return community
147
        elif std_community is not None:
148
            try:
149
                return self.config['defaults']['snmp'][std_community]
150
            except KeyError:
151
                raise ValueError("Invalid standard community")
152
        elif std_community is None:
153
            raise ValueError("Need one of community or std_community")
154
155
    def get_snmp_cred_id(self, community):
156
        """
157
        Look up an SNMP community in the config and then look up
158
        the Orion ID for the Credential.
159
        """
160
161
        # Check if community is a know standard, otherwise
162
        # use it as the community.
163
        try:
164
            name = self.get_snmp_community(None, community)
165
        except ValueError:
166
            name = community
167
168
        swql = """SELECT ID FROM Orion.Credential
169
        WHERE CredentialType=@CredentialType and Name=@name"""
170
171
        kargs = {'CredentialType':
172
                 'SolarWinds.Orion.Core.Models.Credentials.SnmpCredentialsV2',
173
                 'name': name}
174
        orion_data = self.query(swql, **kargs)
175
176
        if len(orion_data['results']) == 1:
177
            return orion_data['results'][0]['ID']
178
        else:
179
            raise ValueError(
180
                "Failed to lookup community in Orion.Credential!")
181
182
    def get_engine_id(self, poller):
183
        """
184
        Takes a poller name (or primary) and returns the EngineID for
185
        the poller.
186
187
        Raises: ValueError on an invaild poller.
188
189
        Returns: The EngineID (int)
190
        """
191
192
        if poller == "primary":
193
            return 1
194
        else:
195
            swql = """SELECT EngineID, ServerName, IP, ServerType
196
            FROM Orion.Engines
197
            WHERE ServerName=@poller"""
198
            kargs = {'poller': poller}
199
            data = self.query(swql, **kargs)
200
201
            if len(data['results']) == 1:
202
                return data['results'][0]['EngineID']
203
            else:
204
                send_user_error("Invalid poller name")
205
                raise ValueError("Invalid poller name")
206
207
    def get_ncm_transfer_results(self, transfer_id, sleep_delay=10):
208
        """
209
        Gets the completed (waits until finished). NCM job transfer status
210
        from Orion.
211
212
        Retruns: The completed status.
213
        """
214
        ts = {}
215
        while True:
216
            swql = """SELECT TransferID, NodeID, Action, RequestedConfigType,
217
            RequestedScript, RequestedReboot, ConfigID, TransferProtocol,
218
            Status, ErrorMessage, DeviceOutput, DateTime, UserName
219
            FROM NCM.TransferResults
220
            WHERE TransferID=@transfer_id"""
221
            kargs = {'transfer_id': transfer_id}
222
223
            transfer_data = self.query(swql, **kargs)
224
            status = transfer_data['results'][0]['Status']
225
226
            if status == 1:
227
                time.sleep(sleep_delay)
228
            elif status == 2:
229
                ts['status'] = "Complete"
230
                break
231
            elif status == 3:
232
                ts['status'] = "Error"
233
                break
234
            else:
235
                ts['status'] = "Unknown"
236
                break
237
238
        ts['RequestedScript'] = transfer_data['results'][0]['RequestedScript']
239
        ts['RequestedReboot'] = transfer_data['results'][0]['RequestedReboot']
240
        ts['ErrorMessage'] = transfer_data['results'][0]['ErrorMessage']
241
        ts['DeviceOutput'] = transfer_data['results'][0]['DeviceOutput']
242
        ts['UserName'] = transfer_data['results'][0]['UserName']
243
244
        return ts
245