-
Notifications
You must be signed in to change notification settings - Fork 48
/
Copy pathworker.py
117 lines (90 loc) · 4.13 KB
/
worker.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
"""Worker code for processing inbound OnboardingTasks.
(c) 2020 Network To Code
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import logging
from django.core.exceptions import ValidationError
from django_rq import job
from prometheus_client import Summary
from dcim.models import Device
from .choices import OnboardingFailChoices
from .choices import OnboardingStatusChoices
from .exceptions import OnboardException
from .helpers import onboarding_task_fqdn_to_ip
from .metrics import onboardingtask_results_counter
from .models import OnboardingDevice
from .models import OnboardingTask
from .onboard import OnboardingManager
logger = logging.getLogger("rq.worker")
REQUEST_TIME = Summary("onboardingtask_processing_seconds", "Time spent processing onboarding request")
@REQUEST_TIME.time()
@job("default")
def onboard_device(task_id, credentials): # pylint: disable=too-many-statements, too-many-branches
"""Process a single OnboardingTask instance."""
username = credentials.username
password = credentials.password
secret = credentials.secret
ot = OnboardingTask.objects.get(id=task_id)
# Rewrite FQDN to IP for Onboarding Task
onboarding_task_fqdn_to_ip(ot)
logger.info("START: onboard device")
onboarded_device = None
try:
try:
if ot.ip_address:
onboarded_device = Device.objects.get(primary_ip4__address__net_host=ot.ip_address)
if OnboardingDevice.objects.filter(device=onboarded_device, enabled=False):
ot.status = OnboardingStatusChoices.STATUS_SKIPPED
return dict(ok=True)
except Device.DoesNotExist as exc:
logger.info("Getting device with IP lookup failed: %s", str(exc))
except Device.MultipleObjectsReturned as exc:
logger.info("Getting device with IP lookup failed: %s", str(exc))
raise OnboardException(
reason="fail-general", message=f"ERROR Multiple devices exist for IP {ot.ip_address}"
)
except ValueError as exc:
logger.info("Getting device with IP lookup failed: %s", str(exc))
except ValidationError as exc:
logger.info("Getting device with IP lookup failed: %s", str(exc))
ot.status = OnboardingStatusChoices.STATUS_RUNNING
ot.save()
onboarding_manager = OnboardingManager(ot=ot, username=username, password=password, secret=secret)
if onboarding_manager.created_device:
ot.created_device = onboarding_manager.created_device
ot.status = OnboardingStatusChoices.STATUS_SUCCEEDED
ot.save()
logger.info("FINISH: onboard device")
onboarding_status = True
except OnboardException as exc:
if onboarded_device:
ot.created_device = onboarded_device
logger.error("%s", exc)
ot.status = OnboardingStatusChoices.STATUS_FAILED
ot.failed_reason = exc.reason
ot.message = exc.message
ot.save()
onboarding_status = False
except Exception as exc: # pylint: disable=broad-except
if onboarded_device:
ot.created_device = onboarded_device
logger.error("Onboarding Error - Exception")
logger.error(str(exc))
ot.status = OnboardingStatusChoices.STATUS_FAILED
ot.failed_reason = OnboardingFailChoices.FAIL_GENERAL
ot.message = str(exc)
ot.save()
onboarding_status = False
finally:
if onboarded_device and not OnboardingDevice.objects.filter(device=onboarded_device):
OnboardingDevice.objects.create(device=onboarded_device)
onboardingtask_results_counter.labels(status=ot.status).inc()
return dict(ok=onboarding_status)