ipfabric_netbox 3.1.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ipfabric_netbox might be problematic. Click here for more details.
- ipfabric_netbox/__init__.py +42 -0
- ipfabric_netbox/api/__init__.py +2 -0
- ipfabric_netbox/api/nested_serializers.py +99 -0
- ipfabric_netbox/api/serializers.py +160 -0
- ipfabric_netbox/api/urls.py +21 -0
- ipfabric_netbox/api/views.py +111 -0
- ipfabric_netbox/choices.py +226 -0
- ipfabric_netbox/filtersets.py +125 -0
- ipfabric_netbox/forms.py +1063 -0
- ipfabric_netbox/jobs.py +95 -0
- ipfabric_netbox/migrations/0001_initial.py +342 -0
- ipfabric_netbox/migrations/0002_ipfabricsnapshot_status.py +17 -0
- ipfabric_netbox/migrations/0003_ipfabricsource_type_and_more.py +49 -0
- ipfabric_netbox/migrations/0004_ipfabricsync_auto_merge.py +17 -0
- ipfabric_netbox/migrations/0005_alter_ipfabricrelationshipfield_source_model_and_more.py +64 -0
- ipfabric_netbox/migrations/0006_alter_ipfabrictransformmap_target_model.py +48 -0
- ipfabric_netbox/migrations/__init__.py +0 -0
- ipfabric_netbox/models.py +874 -0
- ipfabric_netbox/navigation.py +62 -0
- ipfabric_netbox/signals.py +68 -0
- ipfabric_netbox/tables.py +208 -0
- ipfabric_netbox/template_content.py +13 -0
- ipfabric_netbox/templates/ipfabric_netbox/inc/diff.html +72 -0
- ipfabric_netbox/templates/ipfabric_netbox/inc/json.html +20 -0
- ipfabric_netbox/templates/ipfabric_netbox/inc/logs_pending.html +6 -0
- ipfabric_netbox/templates/ipfabric_netbox/inc/merge_form.html +22 -0
- ipfabric_netbox/templates/ipfabric_netbox/inc/site_topology_button.html +70 -0
- ipfabric_netbox/templates/ipfabric_netbox/inc/site_topology_modal.html +61 -0
- ipfabric_netbox/templates/ipfabric_netbox/inc/snapshotdata.html +60 -0
- ipfabric_netbox/templates/ipfabric_netbox/inc/sync_delete.html +19 -0
- ipfabric_netbox/templates/ipfabric_netbox/inc/transform_map_field_map.html +11 -0
- ipfabric_netbox/templates/ipfabric_netbox/inc/transform_map_relationship_map.html +11 -0
- ipfabric_netbox/templates/ipfabric_netbox/ipfabric_table.html +55 -0
- ipfabric_netbox/templates/ipfabric_netbox/ipfabricbranch.html +141 -0
- ipfabric_netbox/templates/ipfabric_netbox/ipfabricsnapshot.html +105 -0
- ipfabric_netbox/templates/ipfabric_netbox/ipfabricsource.html +111 -0
- ipfabric_netbox/templates/ipfabric_netbox/ipfabricsync.html +103 -0
- ipfabric_netbox/templates/ipfabric_netbox/ipfabrictransformmap.html +41 -0
- ipfabric_netbox/templates/ipfabric_netbox/ipfabrictransformmap_list.html +17 -0
- ipfabric_netbox/templates/ipfabric_netbox/ipfabrictransformmap_restore.html +59 -0
- ipfabric_netbox/templates/ipfabric_netbox/partials/branch_all.html +10 -0
- ipfabric_netbox/templates/ipfabric_netbox/partials/branch_progress.html +19 -0
- ipfabric_netbox/templates/ipfabric_netbox/partials/branch_status.html +1 -0
- ipfabric_netbox/templates/ipfabric_netbox/partials/job_logs.html +53 -0
- ipfabric_netbox/templates/ipfabric_netbox/partials/sync_last_branch.html +1 -0
- ipfabric_netbox/templates/ipfabric_netbox/sync_list.html +126 -0
- ipfabric_netbox/templates/static/ipfabric_netbox/css/rack.css +9 -0
- ipfabric_netbox/tests/__init__.py +0 -0
- ipfabric_netbox/tests/test_models.py +1340 -0
- ipfabric_netbox/urls.py +141 -0
- ipfabric_netbox/utilities/__init__.py +0 -0
- ipfabric_netbox/utilities/ipfutils.py +591 -0
- ipfabric_netbox/utilities/logging.py +93 -0
- ipfabric_netbox/utilities/nbutils.py +105 -0
- ipfabric_netbox/utilities/transform_map.py +35 -0
- ipfabric_netbox/views.py +845 -0
- ipfabric_netbox-3.1.2.dist-info/METADATA +88 -0
- ipfabric_netbox-3.1.2.dist-info/RECORD +59 -0
- ipfabric_netbox-3.1.2.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{% load form_helpers %}
|
|
2
|
+
|
|
3
|
+
<form action="{{ form_url }}" method="post">
|
|
4
|
+
{% csrf_token %}
|
|
5
|
+
<div class="modal-header">
|
|
6
|
+
<h5 class="modal-title">Sorry!</h5>
|
|
7
|
+
</div>
|
|
8
|
+
<div class="modal-body">
|
|
9
|
+
<p>Sorry, due to an outstanding issue with NetBox Core we are unable to delete an ingestion. <a href="https://github.com/netbox-community/netbox/issues/13640" target="_blank">Issue Number 13422</a></p>
|
|
10
|
+
{% render_form form %}
|
|
11
|
+
</div>
|
|
12
|
+
<div class="modal-footer">
|
|
13
|
+
{% if return_url %}
|
|
14
|
+
<a href="{{ return_url }}" class="btn btn-outline-secondary">Cancel</a>
|
|
15
|
+
{% else %}
|
|
16
|
+
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Cancel</button>
|
|
17
|
+
{% endif %}
|
|
18
|
+
</div>
|
|
19
|
+
</form>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{% extends 'generic/object_children.html' %}
|
|
2
|
+
|
|
3
|
+
{% block extra_controls %}
|
|
4
|
+
{% if perms.ipfabric_netbox.add_ipfabrictransformfield %}
|
|
5
|
+
<a href="{% url 'plugins:ipfabric_netbox:ipfabrictransformfield_add' %}?transform_map={{ object.pk }}&return_url={% url 'plugins:ipfabric_netbox:ipfabrictransformmap_fields' pk=object.pk %}"
|
|
6
|
+
class="btn btn-primary">
|
|
7
|
+
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Field Map
|
|
8
|
+
</a>
|
|
9
|
+
{% endif %}
|
|
10
|
+
{{ block.super }}
|
|
11
|
+
{% endblock extra_controls %}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{% extends 'generic/object_children.html' %}
|
|
2
|
+
|
|
3
|
+
{% block extra_controls %}
|
|
4
|
+
{% if perms.ipfabric_netbox.add_ipfabricrelationshipfield %}
|
|
5
|
+
<a href="{% url 'plugins:ipfabric_netbox:ipfabricrelationshipfield_add' %}?transform_map={{ object.pk }}&return_url={% url 'plugins:ipfabric_netbox:ipfabrictransformmap_relationships' pk=object.pk %}"
|
|
6
|
+
class="btn btn-primary">
|
|
7
|
+
<i class="mdi mdi-plus-thick" aria-hidden="true"></i> Relationship Map
|
|
8
|
+
</a>
|
|
9
|
+
{% endif %}
|
|
10
|
+
{{ block.super }}
|
|
11
|
+
{% endblock extra_controls %}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{% extends 'generic/object.html' %}
|
|
2
|
+
{% load static %}
|
|
3
|
+
{% load form_helpers %}
|
|
4
|
+
{% load i18n %}
|
|
5
|
+
|
|
6
|
+
{% block content %}
|
|
7
|
+
{{ object.custom_field }}
|
|
8
|
+
|
|
9
|
+
{% if source %}
|
|
10
|
+
{% if not object.serial %}
|
|
11
|
+
<div class="row px-3">
|
|
12
|
+
<div class="card">
|
|
13
|
+
<div class="card-body">
|
|
14
|
+
Device does not have a serial number configured. The serial number is used to match devices between NetBox and IP Fabric.
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
{% elif source.type == "remote" %}
|
|
19
|
+
<div class="row px-3">
|
|
20
|
+
<div class="card">
|
|
21
|
+
<div class="card-body">
|
|
22
|
+
Device has a remote IP Fabric Source configured and cannot directly query IP Fabric.
|
|
23
|
+
</div>
|
|
24
|
+
</div>
|
|
25
|
+
{% else %}
|
|
26
|
+
<div class="row px-3">
|
|
27
|
+
<div class="col col-12 py-3 mx-auto">
|
|
28
|
+
<form action="{% url 'dcim:device' pk=object.pk %}ipfabric" method="get" class="form form-horizontal">
|
|
29
|
+
{% render_form form %}
|
|
30
|
+
<div class="text-end">
|
|
31
|
+
<button type="submit" class="btn btn-primary">
|
|
32
|
+
<span class="mdi mdi-magnify" aria-hidden="true"></span> Fetch
|
|
33
|
+
</button>
|
|
34
|
+
</div>
|
|
35
|
+
</form>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="row px-3">
|
|
39
|
+
<div class="card">
|
|
40
|
+
<div class="card-body htmx-container table-responsive" id="object_list">
|
|
41
|
+
{% include 'htmx/table.html' %}
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
{% endif %}
|
|
46
|
+
{% else %}
|
|
47
|
+
<div class="row px-3">
|
|
48
|
+
<div class="card">
|
|
49
|
+
<div class="card-body">
|
|
50
|
+
Device does not have a IP Fabric source configured in the custom fields. The source is used to match devices between NetBox and IP Fabric instance.
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
{% endif %}
|
|
55
|
+
{% endblock %}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
{% extends 'generic/object.html' %}
|
|
2
|
+
{% load buttons %}
|
|
3
|
+
{% load custom_links %}
|
|
4
|
+
{% load helpers %}
|
|
5
|
+
{% load perms %}
|
|
6
|
+
{% load plugins %}
|
|
7
|
+
{% load tabs %}
|
|
8
|
+
|
|
9
|
+
{% block title %}{{ object }}{% endblock %}
|
|
10
|
+
|
|
11
|
+
{% block control-buttons %}
|
|
12
|
+
{# Clone/Edit/Delete Buttons #}
|
|
13
|
+
<div class="controls">
|
|
14
|
+
<div class="control-group">
|
|
15
|
+
{% custom_links object %}
|
|
16
|
+
</div>
|
|
17
|
+
{% if perms.core.sync_datasource %}
|
|
18
|
+
{% if object.sync.ready_for_sync %}
|
|
19
|
+
<a href="#"
|
|
20
|
+
hx-get="{% url 'plugins:ipfabric_netbox:ipfabricbranch_merge' pk=object.pk %}"
|
|
21
|
+
hx-target="#htmx-modal-content"
|
|
22
|
+
class="btn btn-success"
|
|
23
|
+
data-bs-toggle="modal"
|
|
24
|
+
data-bs-target="#htmx-modal" disabled
|
|
25
|
+
>
|
|
26
|
+
<span class="mdi mdi-sync" aria-hidden="true"></span> Merge
|
|
27
|
+
</a>
|
|
28
|
+
{% else %}
|
|
29
|
+
<span class="inline-block" tabindex="0" data-bs-toggle="tooltip" data-bs-delay="100" data-bs-placement="bottom">
|
|
30
|
+
<button class="btn btn-success" disabled>
|
|
31
|
+
<i class="mdi mdi-sync" aria-hidden="true"></i> Merge
|
|
32
|
+
</button>
|
|
33
|
+
</span>
|
|
34
|
+
{% endif %}
|
|
35
|
+
{% endif %}
|
|
36
|
+
</div>
|
|
37
|
+
{% endblock control-buttons %}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
{% block content %}
|
|
41
|
+
<div class="row mb-3">
|
|
42
|
+
<div class="col col-md-6">
|
|
43
|
+
<div class="card">
|
|
44
|
+
<h5 class="card-header">Branch Information</h5>
|
|
45
|
+
<div class="card-body">
|
|
46
|
+
<table class="table table-hover attr-table">
|
|
47
|
+
<tr>
|
|
48
|
+
<th scope="row">Name</th>
|
|
49
|
+
<td>{{ object.name }}</td>
|
|
50
|
+
</tr>
|
|
51
|
+
<tr>
|
|
52
|
+
<th scope="row">Description</th>
|
|
53
|
+
<td>{{ object.description|placeholder }}</td>
|
|
54
|
+
</tr>
|
|
55
|
+
<tr>
|
|
56
|
+
<th scope="row">Sync Object</th>
|
|
57
|
+
<td><a href="{% url 'plugins:ipfabric_netbox:ipfabricsync' pk=object.sync.pk %}">{{ object.sync.name}}</a>
|
|
58
|
+
</td>
|
|
59
|
+
</tr>
|
|
60
|
+
<tr>
|
|
61
|
+
<th scope="row">Job Object</th>
|
|
62
|
+
<td><a href="{% url 'core:job' pk=object.job.pk %}">{{ object.job }}</a></td>
|
|
63
|
+
</tr>
|
|
64
|
+
<tr>
|
|
65
|
+
<th scope="row">Sync Status</th>
|
|
66
|
+
<td><div id="sync_status" hx-swap-oob="true">{% include 'ipfabric_netbox/partials/branch_status.html' with object=object %}</div></td>
|
|
67
|
+
<!-- <td >{% badge object.sync.get_status_display bg_color=object.sync.get_status_color %}</td> -->
|
|
68
|
+
</div>
|
|
69
|
+
</tr>
|
|
70
|
+
<tr>
|
|
71
|
+
<th scope="row">Snapshot</th>
|
|
72
|
+
<td><a
|
|
73
|
+
href="{% url 'plugins:ipfabric_netbox:ipfabricsnapshot' pk=object.sync.snapshot_data.pk %}">{{object.sync.snapshot_data.name }}</a></td>
|
|
74
|
+
</tr>
|
|
75
|
+
<tr>
|
|
76
|
+
<th scope="row">Source</th>
|
|
77
|
+
<td><a
|
|
78
|
+
href="{% url 'plugins:ipfabric_netbox:ipfabricsource' pk=object.sync.snapshot_data.source.pk %}">{{object.sync.snapshot_data.source.name }}</a></td>
|
|
79
|
+
</tr>
|
|
80
|
+
</table>
|
|
81
|
+
</div>
|
|
82
|
+
</div>
|
|
83
|
+
{% plugin_left_page object %}
|
|
84
|
+
</div>
|
|
85
|
+
<div class="col col-md-6">
|
|
86
|
+
<div class="card">
|
|
87
|
+
<h5 class="card-header">Statistics</h5>
|
|
88
|
+
<div class="card-body">
|
|
89
|
+
<table class="table table-hover attr-table">
|
|
90
|
+
<tr>
|
|
91
|
+
<th scope="row">Created</th>
|
|
92
|
+
<td>
|
|
93
|
+
{% if object.num_created %}
|
|
94
|
+
{{ object.num_created }}
|
|
95
|
+
{% else %}
|
|
96
|
+
{{ ''|placeholder }}
|
|
97
|
+
{% endif %}
|
|
98
|
+
</td>
|
|
99
|
+
</tr>
|
|
100
|
+
<tr>
|
|
101
|
+
<th scope="row">Updated</th>
|
|
102
|
+
<td>
|
|
103
|
+
{% if object.num_updated %}
|
|
104
|
+
{{ object.num_updated }}
|
|
105
|
+
{% else %}
|
|
106
|
+
{{ ''|placeholder }}
|
|
107
|
+
{% endif %}
|
|
108
|
+
</td>
|
|
109
|
+
</tr>
|
|
110
|
+
<tr>
|
|
111
|
+
<th scope="row">Deleted</th>
|
|
112
|
+
<td>
|
|
113
|
+
{% if object.num_deleted %}
|
|
114
|
+
{{ object.num_deleted }}
|
|
115
|
+
{% else %}
|
|
116
|
+
{{ ''|placeholder }}
|
|
117
|
+
{% endif %}
|
|
118
|
+
</td>
|
|
119
|
+
</tr>
|
|
120
|
+
</table>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
<div id="sync_progress">
|
|
124
|
+
{% include 'ipfabric_netbox/partials/branch_progress.html' %}
|
|
125
|
+
</div>
|
|
126
|
+
<!-- {% include 'inc/panels/related_objects.html' %} -->
|
|
127
|
+
{% include 'inc/panels/custom_fields.html' %}
|
|
128
|
+
{% plugin_right_page object %}
|
|
129
|
+
</div>
|
|
130
|
+
</div>
|
|
131
|
+
<div class="row mb-3">
|
|
132
|
+
<div class="col col-md-12" {% if not object.job.completed %} hx-get="{% url 'plugins:ipfabric_netbox:ipfabricbranch_logs' pk=object.pk %}?type=info"
|
|
133
|
+
hx-trigger="every 5s" hx-target="#sync_logs" hx-select="#sync_logs" hx-select-oob="#sync_status:innerHTML"
|
|
134
|
+
hx-swap="innerHTML" {% endif %}>
|
|
135
|
+
<div id="sync_logs">{% include 'ipfabric_netbox/partials/job_logs.html' with job=object.job %}</div>
|
|
136
|
+
</div>
|
|
137
|
+
{% endblock content %}
|
|
138
|
+
|
|
139
|
+
{% block modals %}
|
|
140
|
+
{% include 'inc/htmx_modal.html' with size='lg' %}
|
|
141
|
+
{% endblock modals %}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
{% extends 'generic/object.html' %}
|
|
2
|
+
{% load buttons %}
|
|
3
|
+
{% load helpers %}
|
|
4
|
+
{% load perms %}
|
|
5
|
+
|
|
6
|
+
{% block controls %}
|
|
7
|
+
<div class="controls">
|
|
8
|
+
<div class="control-group">
|
|
9
|
+
{% if request.user|can_delete:object %}
|
|
10
|
+
{% delete_button object %}
|
|
11
|
+
{% endif %}
|
|
12
|
+
</div>
|
|
13
|
+
</div>
|
|
14
|
+
{% endblock controls %}
|
|
15
|
+
|
|
16
|
+
{% block content %}
|
|
17
|
+
<div class="row mb-3">
|
|
18
|
+
<div class="col col-md-6">
|
|
19
|
+
<div class="card">
|
|
20
|
+
<h5 class="card-header">Snapshot Information</h5>
|
|
21
|
+
<div class="card-body">
|
|
22
|
+
<table class="table table-hover attr-table">
|
|
23
|
+
<tr>
|
|
24
|
+
<th scope="row">Name</th>
|
|
25
|
+
<td>{{ object.name|placeholder }}</td>
|
|
26
|
+
</tr>
|
|
27
|
+
<tr>
|
|
28
|
+
<th scope="row">Snapshot ID</th>
|
|
29
|
+
<td>{{ object.snapshot_id|placeholder }}</td>
|
|
30
|
+
</tr>
|
|
31
|
+
<tr>
|
|
32
|
+
<th scope="row">Source</th>
|
|
33
|
+
<td>
|
|
34
|
+
<a href="{% url 'plugins:ipfabric_netbox:ipfabricsource' pk=object.source.pk %}">{{ object.source }}</a>
|
|
35
|
+
</td>
|
|
36
|
+
</tr>
|
|
37
|
+
<tr>
|
|
38
|
+
<th scope="row">Last Updated</th>
|
|
39
|
+
<td>{{ object.last_updated|placeholder }}</td>
|
|
40
|
+
</tr>
|
|
41
|
+
</table>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
<div class="col col-md-6">
|
|
46
|
+
<div class="card">
|
|
47
|
+
<h5 class="card-header">Statistics</h5>
|
|
48
|
+
<div class="card-body">
|
|
49
|
+
<table class="table table-hover attr-table">
|
|
50
|
+
<tr>
|
|
51
|
+
<th scope="row">Version</th>
|
|
52
|
+
<td>{{ object.data.version|placeholder }}</td>
|
|
53
|
+
</tr>
|
|
54
|
+
<tr>
|
|
55
|
+
<th scope="row">Status</th>
|
|
56
|
+
<td>{% badge object.get_status_display bg_color=object.get_status_color %}</td>
|
|
57
|
+
</tr>
|
|
58
|
+
<tr>
|
|
59
|
+
<th scope="row">Site Count</th>
|
|
60
|
+
<td>{{ object.data.sites|length|placeholder }}</td>
|
|
61
|
+
</tr>
|
|
62
|
+
<tr>
|
|
63
|
+
<th scope="row">Sites</th>
|
|
64
|
+
<td>
|
|
65
|
+
{% if object.data.sites %}
|
|
66
|
+
{% for site in object.data.sites %}
|
|
67
|
+
<span class="badge bg-info mt-1">
|
|
68
|
+
{{ site }}
|
|
69
|
+
</span>
|
|
70
|
+
{% endfor %}
|
|
71
|
+
{% else %}
|
|
72
|
+
{{ ''|placeholder }}
|
|
73
|
+
{% endif %}
|
|
74
|
+
</td>
|
|
75
|
+
</tr>
|
|
76
|
+
<tr>
|
|
77
|
+
<th scope="row">Device Count</th>
|
|
78
|
+
<td>{{ object.data.total_dev_count|placeholder }}</td>
|
|
79
|
+
</tr>
|
|
80
|
+
<tr>
|
|
81
|
+
<th scope="row">Interface Count</th>
|
|
82
|
+
<td>{{ object.data.interface_count|placeholder }}</td>
|
|
83
|
+
</tr>
|
|
84
|
+
<tr>
|
|
85
|
+
<th scope="row">Note</th>
|
|
86
|
+
<td>
|
|
87
|
+
<pre>{{ object.data.note|placeholder }}</pre>
|
|
88
|
+
</td>
|
|
89
|
+
</tr>
|
|
90
|
+
</table>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
</div>
|
|
95
|
+
<div class="row">
|
|
96
|
+
<div class="col col-12">
|
|
97
|
+
<div class="card">
|
|
98
|
+
<h5 class="card-header">Data</h5>
|
|
99
|
+
<div class="card-body">
|
|
100
|
+
<pre class="block">{{ object.data | json }}</pre>
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
{% endblock %}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
{% extends 'generic/object.html' %}
|
|
2
|
+
{% load static %}
|
|
3
|
+
{% load helpers %}
|
|
4
|
+
{% load plugins %}
|
|
5
|
+
{% load render_table from django_tables2 %}
|
|
6
|
+
{% load perms %}
|
|
7
|
+
|
|
8
|
+
{% block extra_controls %}
|
|
9
|
+
{% if perms.ipfabric_netbox.sync_source %}
|
|
10
|
+
{% if object.ready_for_sync and object.type == 'local' %}
|
|
11
|
+
<form action="{% url 'plugins:ipfabric_netbox:ipfabricsource_sync' pk=object.pk %}" method="post">
|
|
12
|
+
{% csrf_token %}
|
|
13
|
+
<button type="submit" class="btn btn-primary">
|
|
14
|
+
<i class="mdi mdi-sync" aria-hidden="true"></i> Sync
|
|
15
|
+
</button>
|
|
16
|
+
</form>
|
|
17
|
+
{% else %}
|
|
18
|
+
<span class="inline-block" tabindex="0" data-bs-toggle="tooltip" data-bs-delay="100" data-bs-placement="bottom">
|
|
19
|
+
<button class="btn btn-primary" disabled>
|
|
20
|
+
<i class="mdi mdi-sync" aria-hidden="true"></i> Sync
|
|
21
|
+
</button>
|
|
22
|
+
</span>
|
|
23
|
+
{% endif %}
|
|
24
|
+
{% endif %}
|
|
25
|
+
{% endblock %}
|
|
26
|
+
|
|
27
|
+
{% block content %}
|
|
28
|
+
<div class="row mb-3">
|
|
29
|
+
<div class="col col-md-6">
|
|
30
|
+
<div class="card">
|
|
31
|
+
<h5 class="card-header">Data Source</h5>
|
|
32
|
+
<div class="card-body">
|
|
33
|
+
<table class="table table-hover attr-table">
|
|
34
|
+
<tr>
|
|
35
|
+
<th scope="row">Name</th>
|
|
36
|
+
<td>{{ object.name }}</td>
|
|
37
|
+
</tr>
|
|
38
|
+
<tr>
|
|
39
|
+
<th scope="row">Type</th>
|
|
40
|
+
<td>{{ object.get_type_display }}</td>
|
|
41
|
+
</tr>
|
|
42
|
+
<tr>
|
|
43
|
+
<th scope="row">Status</th>
|
|
44
|
+
<td>{% badge object.get_status_display bg_color=object.get_status_color %}</td>
|
|
45
|
+
</tr>
|
|
46
|
+
<tr>
|
|
47
|
+
<th scope="row">Last synced</th>
|
|
48
|
+
<td>{{ object.last_synced|placeholder }}</td>
|
|
49
|
+
</tr>
|
|
50
|
+
<tr>
|
|
51
|
+
<th scope="row">Description</th>
|
|
52
|
+
<td>{{ object.description|placeholder }}</td>
|
|
53
|
+
</tr>
|
|
54
|
+
<tr>
|
|
55
|
+
<th scope="row">URL</th>
|
|
56
|
+
<td>
|
|
57
|
+
<a href="{{ object.url }}">{{ object.url }}</a>
|
|
58
|
+
</td>
|
|
59
|
+
</tr>
|
|
60
|
+
</table>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
{% include 'inc/panels/tags.html' %}
|
|
64
|
+
{% include 'inc/panels/comments.html' %}
|
|
65
|
+
{% plugin_left_page object %}
|
|
66
|
+
</div>
|
|
67
|
+
<div class="col col-md-6">
|
|
68
|
+
<div class="card">
|
|
69
|
+
<h5 class="card-header">Parameters</h5>
|
|
70
|
+
<div class="card-body">
|
|
71
|
+
<table class="table table-hover attr-table">
|
|
72
|
+
{% for name, value in object.parameters.items %}
|
|
73
|
+
<tr>
|
|
74
|
+
<th scope="row">{{ name | capfirst}}</th>
|
|
75
|
+
{% if name == "auth" and object.parameters|get_key:name %}
|
|
76
|
+
<td>
|
|
77
|
+
{% if request.user|can_add:object or request.user|can_change:object or request.user|can_delete:object %}
|
|
78
|
+
<span id="secret" class="font-monospace" data-secret="{{ object.parameters|get_key:name }}">{{
|
|
79
|
+
object.parameters|get_key:name|placeholder }}</span>
|
|
80
|
+
<button type="button" class="btn btn-sm btn-primary toggle-secret float-end" data-bs-toggle="button">Show
|
|
81
|
+
Secret</button>
|
|
82
|
+
{% else %}
|
|
83
|
+
<i>Password Hidden</i>
|
|
84
|
+
{% endif %}
|
|
85
|
+
</td>
|
|
86
|
+
{% else %}
|
|
87
|
+
<td>{{ object.parameters|get_key:name|placeholder }}</td>
|
|
88
|
+
{% endif %}
|
|
89
|
+
</tr>
|
|
90
|
+
{% empty %}
|
|
91
|
+
<tr>
|
|
92
|
+
<td colspan="2" class="text-muted">
|
|
93
|
+
No parameters defined
|
|
94
|
+
</td>
|
|
95
|
+
</tr>
|
|
96
|
+
{% endfor %}
|
|
97
|
+
</table>
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
{% include 'inc/panels/related_objects.html' %}
|
|
101
|
+
{% include 'inc/panels/custom_fields.html' %}
|
|
102
|
+
{% plugin_right_page object %}
|
|
103
|
+
</div>
|
|
104
|
+
{% if job %}
|
|
105
|
+
<div class="col col-md-12" {% if not object.job.completed %} hx-trigger="every 5s" hx-target="#sync_logs"
|
|
106
|
+
hx-select="#sync_logs" hx-select-oob="#sync_status:innerHTML" hx-swap="innerHTML" {% endif %}>
|
|
107
|
+
<div id="sync_logs">{% include 'ipfabric_netbox/partials/job_logs.html' with job=job %}</div>
|
|
108
|
+
</div>
|
|
109
|
+
{% endif %}
|
|
110
|
+
</div>
|
|
111
|
+
{% endblock %}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
{% extends 'generic/object.html' %}
|
|
2
|
+
{% load static %}
|
|
3
|
+
{% load helpers %}
|
|
4
|
+
{% load plugins %}
|
|
5
|
+
{% load render_table from django_tables2 %}
|
|
6
|
+
|
|
7
|
+
{% block extra_controls %}
|
|
8
|
+
{% if perms.ipfabric_netbox.sync_ingest %}
|
|
9
|
+
{% if object.ready_for_sync %}
|
|
10
|
+
<form action="{% url 'plugins:ipfabric_netbox:ipfabricsync_sync' pk=object.pk %}" method="post">
|
|
11
|
+
{% csrf_token %}
|
|
12
|
+
<button type="submit" class="btn btn-primary">
|
|
13
|
+
<i class="mdi mdi-sync" aria-hidden="true"></i> Adhoc Ingestion
|
|
14
|
+
</button>
|
|
15
|
+
</form>
|
|
16
|
+
{% else %}
|
|
17
|
+
<span class="inline-block" tabindex="0" data-bs-toggle="tooltip" data-bs-delay="100" data-bs-placement="bottom">
|
|
18
|
+
<button class="btn btn-primary" disabled>
|
|
19
|
+
<i class="mdi mdi-sync" aria-hidden="true"></i> Adhoc Ingestion
|
|
20
|
+
</button>
|
|
21
|
+
</span>
|
|
22
|
+
{% endif %}
|
|
23
|
+
{% endif %}
|
|
24
|
+
{% endblock %}
|
|
25
|
+
|
|
26
|
+
{% block content %}
|
|
27
|
+
<div class="row mb-3">
|
|
28
|
+
<div class="col col-md-6">
|
|
29
|
+
<div class="card">
|
|
30
|
+
<h5 class="card-header">Ingestion Information</h5>
|
|
31
|
+
<div class="card-body">
|
|
32
|
+
<table class="table table-hover attr-table">
|
|
33
|
+
<tr>
|
|
34
|
+
<th scope="row">Name</th>
|
|
35
|
+
<td>{{ object.name }}</td>
|
|
36
|
+
</tr>
|
|
37
|
+
<tr>
|
|
38
|
+
<th scope="row">Source</th>
|
|
39
|
+
<td><a href="{% url 'plugins:ipfabric_netbox:ipfabricsource' pk=object.snapshot_data.source.pk %}">{{ object.snapshot_data.source.name }}</a></td>
|
|
40
|
+
</tr>
|
|
41
|
+
<tr>
|
|
42
|
+
<th scope="row">Snapshot</th>
|
|
43
|
+
<td><a href="{% url 'plugins:ipfabric_netbox:ipfabricsnapshot' pk=object.snapshot_data.pk %}">{{ object.snapshot_data.name}}</a></td>
|
|
44
|
+
</tr>
|
|
45
|
+
<tr>
|
|
46
|
+
<th scope="row">Status</th>
|
|
47
|
+
<td>{% badge object.get_status_display bg_color=object.get_status_color %}</td>
|
|
48
|
+
</tr>
|
|
49
|
+
<tr>
|
|
50
|
+
<th scope="row">Last synced</th>
|
|
51
|
+
<td>{{ object.last_synced|placeholder }}</td>
|
|
52
|
+
</tr>
|
|
53
|
+
<tr>
|
|
54
|
+
<th scope="row">Latest branch</th>
|
|
55
|
+
<td><div {% if object.status == 'queued' or object.status == 'syncing' %} hx-get="{% url 'plugins:ipfabric_netbox:ipfabricsync' pk=object.pk %}" hx-trigger="every 1s"{% endif %}>{% include 'ipfabric_netbox/partials/sync_last_branch.html' %}</div></td>
|
|
56
|
+
</tr>
|
|
57
|
+
<tr>
|
|
58
|
+
<th scope="row">Schedule</th>
|
|
59
|
+
<td><div>{{ object.scheduled }}</div></td>
|
|
60
|
+
</tr>
|
|
61
|
+
<tr>
|
|
62
|
+
<th scope="row">Interval</th>
|
|
63
|
+
<td><div>{{ object.interval }}</div></td>
|
|
64
|
+
</tr>
|
|
65
|
+
<tr>
|
|
66
|
+
<th scope="row">User</th>
|
|
67
|
+
<td><div>{{ object.user }}</div></td>
|
|
68
|
+
</tr>
|
|
69
|
+
</tr>
|
|
70
|
+
</table>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
{% include 'inc/panels/tags.html' %}
|
|
74
|
+
{% plugin_left_page object %}
|
|
75
|
+
</div>
|
|
76
|
+
<div class="col col-md-6">
|
|
77
|
+
<div class="card">
|
|
78
|
+
<h5 class="card-header">Parameters</h5>
|
|
79
|
+
<div class="card-body">
|
|
80
|
+
<table class="table table-hover attr-table">
|
|
81
|
+
{% for name, field in object.parameters.items %}
|
|
82
|
+
<tr>
|
|
83
|
+
<th scope="row">{{ name }}</th>
|
|
84
|
+
<td>{{ object.parameters|get_key:name|placeholder }}</td>
|
|
85
|
+
</tr>
|
|
86
|
+
{% empty %}
|
|
87
|
+
<tr>
|
|
88
|
+
<td colspan="2" class="text-muted">
|
|
89
|
+
No parameters defined
|
|
90
|
+
</td>
|
|
91
|
+
</tr>
|
|
92
|
+
{% endfor %}
|
|
93
|
+
</table>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
<div class="card">
|
|
97
|
+
{% include 'extras/inc/configcontext_data.html' with title="Parameters" data=object.parameters format=format copyid="parameters"%}
|
|
98
|
+
</div>
|
|
99
|
+
{% include 'inc/panels/custom_fields.html' %}
|
|
100
|
+
{% plugin_right_page object %}
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
{% endblock %}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{% extends 'generic/object.html' %}
|
|
2
|
+
{% load static %}
|
|
3
|
+
{% load helpers %}
|
|
4
|
+
{% load plugins %}
|
|
5
|
+
{% load render_table from django_tables2 %}
|
|
6
|
+
|
|
7
|
+
{% block content %}
|
|
8
|
+
<div class="row mb-3">
|
|
9
|
+
<div class="col col-md-6">
|
|
10
|
+
<div class="card">
|
|
11
|
+
<h5 class="card-header">Transform Map Information</h5>
|
|
12
|
+
<div class="card-body">
|
|
13
|
+
<table class="table table-hover attr-table">
|
|
14
|
+
<tr>
|
|
15
|
+
<th scope="row">Name</th>
|
|
16
|
+
<td>{{ object.name }}</td>
|
|
17
|
+
</tr>
|
|
18
|
+
<tr>
|
|
19
|
+
<th scope="row">Source Model</th>
|
|
20
|
+
<td>ipfabric | {{ object.source_model }}</td>
|
|
21
|
+
</tr>
|
|
22
|
+
<tr>
|
|
23
|
+
<th scope="row">Target Model</th>
|
|
24
|
+
<td>{{ object.target_model }}</td>
|
|
25
|
+
</tr>
|
|
26
|
+
<tr>
|
|
27
|
+
<th scope="row">Status</th>
|
|
28
|
+
<td>{{ object.status }}</td>
|
|
29
|
+
</tr>
|
|
30
|
+
</tr>
|
|
31
|
+
</table>
|
|
32
|
+
</div>
|
|
33
|
+
</div>
|
|
34
|
+
{% plugin_left_page object %}
|
|
35
|
+
</div>
|
|
36
|
+
<div class="col col-md-6">
|
|
37
|
+
{% include 'inc/panels/custom_fields.html' %}
|
|
38
|
+
{% plugin_right_page object %}
|
|
39
|
+
</div>
|
|
40
|
+
</div>
|
|
41
|
+
{% endblock %}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{% extends 'generic/object_list.html' %}
|
|
2
|
+
|
|
3
|
+
{% block extra_controls %}
|
|
4
|
+
<a href="#"
|
|
5
|
+
hx-get="{% url 'plugins:ipfabric_netbox:ipfabrictransformmap_restore' %}"
|
|
6
|
+
hx-target="#htmx-modal-content"
|
|
7
|
+
class="btn btn-warning"
|
|
8
|
+
data-bs-toggle="modal"
|
|
9
|
+
data-bs-target="#htmx-modal"
|
|
10
|
+
>
|
|
11
|
+
<span class="mdi mdi-file-restore" aria-hidden="true"></span> Restore
|
|
12
|
+
</a>
|
|
13
|
+
{% endblock %}
|
|
14
|
+
|
|
15
|
+
{% block modals %}
|
|
16
|
+
{% include 'inc/htmx_modal.html' %}
|
|
17
|
+
{% endblock modals %}
|