mirror of
https://github.com/netbirdio/plugins.git
synced 2026-05-22 18:44:07 -07:00
add show diff single
add apply diff single
This commit is contained in:
+73
-1
@@ -41,6 +41,18 @@ use OPNsense\HAProxy\HAProxy;
|
||||
*/
|
||||
class MaintenanceController extends ApiControllerBase
|
||||
{
|
||||
/**
|
||||
* jQuery bootstrap certificates diff list
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function searchCertificateDiffAction()
|
||||
{
|
||||
return $this->getData(
|
||||
["cert_diff_list"],
|
||||
["rowCount", "current", "searchPhrase", "sort"]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* jQuery bootstrap server list
|
||||
* @return array|mixed
|
||||
@@ -53,6 +65,42 @@ class MaintenanceController extends ApiControllerBase
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* sync certificate for frontends
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function certSyncAction()
|
||||
{
|
||||
return $this->syncCerts(
|
||||
["cert_sync"],
|
||||
["frontend_ids"]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* show certificate diff for frontends
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function certDiffAction()
|
||||
{
|
||||
return $this->getData(
|
||||
["cert_diff"],
|
||||
["frontend_ids"]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* show certificate actions for frontends
|
||||
* @return array|mixed
|
||||
*/
|
||||
public function certActionsAction()
|
||||
{
|
||||
return $this->getData(
|
||||
["cert_actions"],
|
||||
["frontend_ids"]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* set server weight
|
||||
* @return array|mixed
|
||||
@@ -145,7 +193,7 @@ class MaintenanceController extends ApiControllerBase
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a backend command to save data
|
||||
* Executes a backend command which returns output on error
|
||||
* @param array $command
|
||||
* @param array $arguments
|
||||
* @return array|string[]
|
||||
@@ -167,4 +215,28 @@ class MaintenanceController extends ApiControllerBase
|
||||
"message" => 'only accept POST Requests.'
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a ssl certificate sync
|
||||
* @param array $command
|
||||
* @param array $arguments
|
||||
* @return array|string[]
|
||||
*/
|
||||
protected function syncCerts(array $command, array $arguments = [])
|
||||
{
|
||||
if ($this->request->isPost()) {
|
||||
$output = $this->safeBackendCmd($command, $arguments);
|
||||
$result = json_decode($output, true);
|
||||
|
||||
return [
|
||||
"status" => "ok",
|
||||
"result" => $result,
|
||||
];
|
||||
}
|
||||
return [
|
||||
"status" => 'unavailable',
|
||||
"message" => 'only accept POST Requests.'
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,9 +26,114 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#}
|
||||
|
||||
<script>
|
||||
$( document ).ready(function() {
|
||||
// grid-certificates
|
||||
$("#grid-certificates").bootgrid('destroy');
|
||||
var grid_certificates = $("#grid-certificates").UIBootgrid({
|
||||
search: '/api/haproxy/maintenance/searchCertificateDiff',
|
||||
options: {
|
||||
ajax: true,
|
||||
selection: true,
|
||||
multiSelect: true,
|
||||
keepSelection: true,
|
||||
rowCount:[10,25,50,100,500,1000],
|
||||
searchSettings: {
|
||||
delay: 250,
|
||||
characters: 1
|
||||
},
|
||||
formatters: {
|
||||
"commands": function (column, row) {
|
||||
buttons = ""
|
||||
buttons += "<button type=\"button\" data-action=\"showDiff\" title=\"{{ lang._('Show diff between configured ssl certificates and certificates from HAProxy memory.') }}\" class=\"btn btn-xs btn-default\" data-row-id=\"" + row.id + "\"><span class=\"fa fa-info-circle\"></span></button>"
|
||||
buttons += " <button type=\"button\" data-action=\"applyDiff\" title=\"{{ lang._('Apply diff and sync certificates into HAProxy memory.') }}\" class=\"btn btn-xs btn-default\" data-row-id=\"" + row.id + "\"><span class=\"fa fa-refresh\"></span></button>"
|
||||
return buttons;
|
||||
},
|
||||
},
|
||||
}
|
||||
}).on("loaded.rs.jquery.bootgrid", function(){
|
||||
grid_certificates.find("*[data-action=showDiff]").off().on("click", function(e) {
|
||||
var row_id = $(this).data("row-id");
|
||||
var frontend_ids = row_id;
|
||||
var payload = {
|
||||
'frontend_ids': frontend_ids,
|
||||
};
|
||||
|
||||
$.post('/api/haproxy/maintenance/certDiff', payload, function(data) {
|
||||
BootstrapDialog.show({
|
||||
type: BootstrapDialog.TYPE_INFO,
|
||||
title: "{{ lang._('Diff between configured and remote ssl certificates') }}",
|
||||
message: `<pre>${data}</pre>`,
|
||||
buttons: [{
|
||||
label: '{{ lang._('Close') }}',
|
||||
action: function(dialog){
|
||||
dialog.close();
|
||||
}
|
||||
}]
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
grid_certificates.find("*[data-action=applyDiff]").off().on("click", function(e) {
|
||||
var row_id = $(this).data("row-id");
|
||||
var rows = $("#grid-certificates").bootgrid("getCurrentRows");
|
||||
var row = rows.filter(function(row) {
|
||||
return row.id == row_id;
|
||||
})[0];
|
||||
|
||||
var requested_count = row.total_count;
|
||||
var frontend_ids = row.id
|
||||
var payload = {
|
||||
'frontend_ids': frontend_ids,
|
||||
};
|
||||
|
||||
$.post('/api/haproxy/maintenance/certActions', payload, function(data_actions) {
|
||||
question = ''
|
||||
question += `<pre>${data_actions}</pre>`;
|
||||
question += '<b>{{ lang._('Apply ssl certificates to HaProxy?') }}</b></br></br>';
|
||||
|
||||
stdDialogConfirm('{{ lang._('Confirmation Required') }}',
|
||||
question,
|
||||
'{{ lang._('Yes') }}', '{{ lang._('Cancel') }}', function() {
|
||||
$.post('/api/haproxy/maintenance/certSync', payload, function(data) {
|
||||
modified_count = data.result.add_count + data.result.remove_count + data.result.update_count;
|
||||
if (requested_count != modified_count) {
|
||||
var error_msg = syncErrorMessage(data.result.modified, data.result.deleted);
|
||||
BootstrapDialog.show({
|
||||
type: BootstrapDialog.TYPE_DANGER,
|
||||
title: "{{ lang._('Error applying ssl certificates to HAProxy') }}",
|
||||
message: error_msg,
|
||||
buttons: [{
|
||||
label: '{{ lang._('Close') }}',
|
||||
action: function(dialog){
|
||||
dialog.close();
|
||||
}
|
||||
}]
|
||||
});
|
||||
}
|
||||
$("#grid-certificates").bootgrid("reload");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
grid_certificates.find("*[data-action=showDiffBulk]").off().on("click", function(e) {
|
||||
var rows = $("#grid-certificates").bootgrid("getSelectedRows");
|
||||
console.log('Show diff for multi')
|
||||
});
|
||||
|
||||
grid_certificates.find("*[data-action=applyDiffBulk]").off().on("click", function(e) {
|
||||
var rows = $("#grid-certificates").bootgrid("getSelectedRows");
|
||||
console.log('Apply diff for multi')
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
// grid-status
|
||||
$("#grid-status").bootgrid('destroy');
|
||||
var grid_status = $("#grid-status").UIBootgrid({
|
||||
search: '/api/haproxy/maintenance/searchServer',
|
||||
@@ -45,7 +150,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
formatters: {
|
||||
"commands": function (column, row) {
|
||||
buttons = ""
|
||||
buttons += "<button type=\"button\" title=\"{{ lang._('Set administrative state to ready. Puts the server in normal mode.') }}\" class=\"btn btn-xs btn-default command-set-state\" data-state=\"ready\" data-row-id=\"" + row.id + "\"><span class=\"fa fa-check\"></span></button>"
|
||||
buttons += "<button type=\"button\" title=\"{{ lang._('Set administrative state to ready. Puts the server in normal mode.') }}\" class=\"btn btn-xs btn-default command-set-state\" data-state=\"ready\" data-row-id=\"" + row.id + "\"><span class=\"fa fa-check\"></span></button>"
|
||||
buttons += " <button type=\"button\" title=\"{{ lang._('Set administrative state to drain. Removes the server from load balancing but still allows it to be health checked and to accept new persistent connections') }}\" class=\"btn btn-xs btn-default command-set-state\" data-state=\"drain\" data-row-id=\"" + row.id + "\"><span class=\"fa fa-sort-amount-desc\"></span></button>"
|
||||
buttons += " <button type=\"button\" title=\"{{ lang._('Set administrative state to maintenance. Disables any traffic to the server as well as any health checks.') }}\" class=\"btn btn-xs btn-default command-set-state\" data-state=\"maint\" data-row-id=\"" + row.id + "\"><span class=\"fa fa-wrench\"></span></button>"
|
||||
buttons += " <button type=\"button\" title=\"{{ lang._('Change server weight.') }}\" class=\"btn btn-xs btn-default command-set-weight\" data-weight=\"" + row.weight + "\" data-row-id=\"" + row.id + "\"><span class=\"fa fa-balance-scale\"></span></button>"
|
||||
@@ -91,7 +196,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// set single - server weight
|
||||
@@ -242,6 +346,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
<ul class="nav nav-tabs" role="tablist" id="maintabs">
|
||||
<li class="active"><a data-toggle="tab" href="#server"><b>{{ lang._('Server') }}</b></a></li>
|
||||
<li><a data-toggle="tab" href="#ssl-certs"><b>{{ lang._('SSL Certificates') }}</b></a></li>
|
||||
</ul>
|
||||
|
||||
<div class="content-box tab-content">
|
||||
@@ -281,6 +386,33 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="ssl-certs" class="tab-pane fade in">
|
||||
<!-- tab page "ssl-certs" -->
|
||||
<table id="grid-certificates" class="table table-condensed table-hover table-striped table-responsive">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-column-id="id" data-type="string" data-identifier="true" data-visible="false">{{ lang._('id') }}</th>
|
||||
<th data-column-id="frontend_name" data-type="string">{{ lang._('Public Service Name') }}</th>
|
||||
<th data-column-id="update_count" data-type="string">{{ lang._('Update Certificates') }}</th>
|
||||
<th data-column-id="add_count" data-type="string">{{ lang._('Add Certificates') }}</th>
|
||||
<th data-column-id="remove_count" data-type="string">{{ lang._('Remove Certificates') }}</th>
|
||||
<th data-column-id="commands" data-width="8em" data-formatter="commands" data-sortable="false">{{ lang._('Commands') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<button data-action="showDiff" title="{{ lang._('Show diff between configured ssl certificates and certificates from HAProxy memory.') }}" type="button" class="btn btn-xs btn-default"><span class="fa fa-info-circle"></span></button>
|
||||
<button data-action="applyDiff" title="{{ lang._('Apply diff and sync certificates into HAProxy memory.') }}" type="button" class="btn btn-xs btn-default"><span class="fa fa-refresh"></span></button>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ partial("layout_partials/base_dialog_processing") }}
|
||||
|
||||
@@ -17,7 +17,7 @@ from haproxy import cmds
|
||||
class SyncWithTarget:
|
||||
""" Base class for sync objects to a target """
|
||||
|
||||
def __init__(self, socket='/var/run/haproxy.socket'):
|
||||
def __init__(self, socket='/var/run/haproxy.socket', **kwargs):
|
||||
self.socket = socket
|
||||
|
||||
def _execute_remote_cmd(self, command_class, **command_args):
|
||||
@@ -40,7 +40,7 @@ class SyncWithTarget:
|
||||
class Diff(SyncWithTarget):
|
||||
""" Represents a full diff to sync with remote """
|
||||
|
||||
def __init__(self, crt_lists=None):
|
||||
def __init__(self, crt_lists=None, **kwargs):
|
||||
super().__init__()
|
||||
if crt_lists is None:
|
||||
crt_lists = []
|
||||
@@ -49,6 +49,13 @@ class Diff(SyncWithTarget):
|
||||
self._status = self._get_status()
|
||||
self._transactions = self._get_transactions()
|
||||
|
||||
self.output_format = kwargs['output']
|
||||
self.page = kwargs['page']
|
||||
self.page_rows = kwargs['page_rows']
|
||||
self.search = kwargs['search']
|
||||
self.sort_col = kwargs['sort_col']
|
||||
self.sort_dir = kwargs['sort_dir']
|
||||
|
||||
@property
|
||||
def diff(self):
|
||||
return self._diff
|
||||
@@ -65,13 +72,53 @@ class Diff(SyncWithTarget):
|
||||
def status(self):
|
||||
return self._status
|
||||
|
||||
def _calc_diff(self):
|
||||
result = {}
|
||||
for crt_list in self:
|
||||
result[crt_list.frontend_id] = crt_list.diff
|
||||
return result
|
||||
def _get_bootgrid_output(self, rows):
|
||||
""" Returns jquery bootgrid output """
|
||||
args = {
|
||||
"rows": rows,
|
||||
"page": int(self.page) if self.page != None else 1,
|
||||
"page_rows": int(self.page_rows) if self.page_rows != None else len(rows),
|
||||
"search": self.search,
|
||||
"sort_col": self.sort_col if self.sort_col else 'id',
|
||||
"sort_dir": self.sort_dir,
|
||||
}
|
||||
|
||||
def abort(self, output_format):
|
||||
# search
|
||||
if args['search']:
|
||||
filtered_rows = []
|
||||
for row in rows:
|
||||
def inner(row):
|
||||
for k, v in row.items():
|
||||
if args['search'] in v:
|
||||
return row
|
||||
return None
|
||||
|
||||
match = inner(row)
|
||||
if match:
|
||||
filtered_rows.append(match)
|
||||
rows = filtered_rows
|
||||
|
||||
# sort
|
||||
rows.sort(key=lambda k: k[args['sort_col']], reverse=True if args['sort_dir'] == 'desc' else False)
|
||||
|
||||
# pager
|
||||
total = len(rows)
|
||||
pages = [rows[i:i + args['page_rows']] for i in range(0, total, args['page_rows'])]
|
||||
if pages and (args['page'] > len(pages) or args['page'] < 1):
|
||||
raise KeyError(f"Current page {args['page']} does not exist. Available pages: {len(pages)}")
|
||||
page = pages[args['page'] - 1] if pages else []
|
||||
|
||||
return json.dumps({
|
||||
"rows": page,
|
||||
"total": total,
|
||||
"rowCount": args['page_rows'],
|
||||
"current": args['page']
|
||||
})
|
||||
|
||||
def _calc_diff(self):
|
||||
return [crt_list.diff for crt_list in self if crt_list.diff['total_count'] > 0]
|
||||
|
||||
def abort(self):
|
||||
""" Abort transactions"""
|
||||
aborted = []
|
||||
for certfile in self.transactions:
|
||||
@@ -83,10 +130,10 @@ class Diff(SyncWithTarget):
|
||||
"output": output,
|
||||
})
|
||||
|
||||
if output_format == 'json':
|
||||
if self.output_format == 'json':
|
||||
print(json.dumps({'abort': aborted}))
|
||||
|
||||
if output_format == 'raw':
|
||||
if self.output_format == 'raw':
|
||||
for item in aborted:
|
||||
print(f"ABORT transaction: {item['cert']}")
|
||||
print(f" {repr(item['output'])}")
|
||||
@@ -117,12 +164,12 @@ class Diff(SyncWithTarget):
|
||||
}
|
||||
return status
|
||||
|
||||
def show_status(self, output_format):
|
||||
def show_diff(self):
|
||||
""" Shows current local and remote state """
|
||||
if output_format == 'json':
|
||||
if self.output_format == 'json':
|
||||
print(json.dumps(self.status))
|
||||
|
||||
if output_format == 'raw':
|
||||
if self.output_format == 'raw':
|
||||
print("## STATUS ##")
|
||||
for frontend_id, crt_list in self.status.items():
|
||||
print(f"CRT_LIST: {crt_list['path']}")
|
||||
@@ -140,14 +187,17 @@ class Diff(SyncWithTarget):
|
||||
print(f" REMOTE: {cert['remote']}")
|
||||
print()
|
||||
|
||||
def show_diff(self, output_format):
|
||||
def show_actions(self):
|
||||
""" Shows what will be synced to target """
|
||||
if output_format == 'json':
|
||||
if self.output_format == 'json':
|
||||
print(json.dumps(self.diff))
|
||||
|
||||
if output_format == 'raw':
|
||||
if self.output_format == 'bootgrid':
|
||||
print(self._get_bootgrid_output(self.diff))
|
||||
|
||||
if self.output_format == 'raw':
|
||||
print("## DIFF ##")
|
||||
for frontend_id, diff in self.diff.items():
|
||||
for diff in self.diff:
|
||||
print(f"CRT LIST: {diff['path']}")
|
||||
print(f" FRONTEND NAME: {diff['frontend_name']}")
|
||||
print(f" FRONTEND ID: {diff['frontend_id']}")
|
||||
@@ -157,34 +207,62 @@ class Diff(SyncWithTarget):
|
||||
print(f" Serial: {update['meta']['Serial']}")
|
||||
print(f" Issuer: {update['meta']['Issuer']}")
|
||||
print(f" Subject: {update['meta']['Subject']}")
|
||||
print()
|
||||
else:
|
||||
if not diff['update']:
|
||||
print(f" CERT UPDATE: []")
|
||||
print(f" CERT ADD : {diff['add']}")
|
||||
print(f" CERT DEL : {diff['del']}")
|
||||
|
||||
def show_transactions(self, output_format):
|
||||
if output_format == 'json':
|
||||
for add in diff['add']:
|
||||
print(f" CERT ADD:")
|
||||
print(f" Cert: {add}")
|
||||
print()
|
||||
else:
|
||||
if not diff['add']:
|
||||
print(f" CERT ADD: []")
|
||||
|
||||
for remove in diff['remove']:
|
||||
print(f" CERT REMOVE:")
|
||||
print(f" Cert: {remove['certfile']}")
|
||||
print(f" Serial: {remove['meta'].get('Serial', None)}")
|
||||
print(f" Issuer: {remove['meta'].get('Issuer', None)}")
|
||||
print(f" Subject: {remove['meta'].get('Subject', None)}")
|
||||
print()
|
||||
else:
|
||||
if not diff['remove']:
|
||||
print(f" CERT REMOVE: []")
|
||||
|
||||
|
||||
def show_transactions(self):
|
||||
if self.output_format == 'json':
|
||||
print(json.dumps({'transactions': self.transactions}))
|
||||
|
||||
if output_format == 'raw':
|
||||
if self.output_format == 'raw':
|
||||
print("## OPEN TRANSACTIONS ##")
|
||||
for cert in self.transactions:
|
||||
print(cert)
|
||||
|
||||
def sync(self, output_format):
|
||||
def sync(self):
|
||||
""" Sync to target """
|
||||
sync = {}
|
||||
sync = {
|
||||
'modified': [],
|
||||
'deleted': [],
|
||||
'add_count': 0,
|
||||
'remove_count': 0,
|
||||
'update_count': 0,
|
||||
'del_count': 0,
|
||||
}
|
||||
certs_to_delete = []
|
||||
for frontend_id, diff in self.diff.items():
|
||||
sync[frontend_id] = {
|
||||
for diff in self.diff:
|
||||
sync_item = {
|
||||
'frontend_name': diff['frontend_name'],
|
||||
'frontend_id': diff['frontend_id'],
|
||||
'path': diff['path'],
|
||||
'add': [],
|
||||
'remove': [],
|
||||
'update': [],
|
||||
'del': []
|
||||
'add_count': 0,
|
||||
'remove_count': 0,
|
||||
'update_count': 0,
|
||||
}
|
||||
|
||||
# update cert content
|
||||
@@ -200,48 +278,60 @@ class Diff(SyncWithTarget):
|
||||
output = self._execute_remote_cmd(cmds.commitSslCrt, certfile=cert['certfile'])
|
||||
messages.append(output)
|
||||
|
||||
sync[frontend_id]['update'].append({
|
||||
sync_item['update'].append({
|
||||
'cert': cert['certfile'],
|
||||
'messages': messages
|
||||
})
|
||||
sync['update_count'] += 1
|
||||
sync_item['update_count'] += 1
|
||||
|
||||
# add to crt-list
|
||||
for cert in diff['add']:
|
||||
messages = []
|
||||
output = self._execute_remote_cmd(cmds.addToSslCrtList, crt_list=diff['path'], certfile=cert)
|
||||
messages.append(output)
|
||||
sync[frontend_id]['add'].append({
|
||||
sync_item['add'].append({
|
||||
'cert': cert,
|
||||
'messages': messages
|
||||
})
|
||||
sync['add_count'] += 1
|
||||
sync_item['add_count'] += 1
|
||||
|
||||
# remove from crt-list
|
||||
for cert in diff['del']:
|
||||
for cert in diff['remove']:
|
||||
messages = []
|
||||
output = self._execute_remote_cmd(cmds.delFromSslCrtList, crt_list=diff['path'], certfile=cert)
|
||||
output = self._execute_remote_cmd(cmds.delFromSslCrtList, crt_list=diff['path'], certfile=cert['certfile'])
|
||||
messages.append(output)
|
||||
certs_to_delete.append(cert.split(":")[0])
|
||||
sync[frontend_id]['remove'].append({
|
||||
'cert': cert,
|
||||
certs_to_delete.append(cert['certfile'].split(":")[0])
|
||||
sync_item['remove'].append({
|
||||
'cert': cert['certfile'],
|
||||
'messages': messages
|
||||
})
|
||||
sync['remove_count'] += 1
|
||||
sync_item['remove_count'] += 1
|
||||
|
||||
modified_items = sync_item['update_count'] + sync_item['add_count'] + sync_item['remove_count']
|
||||
if modified_items:
|
||||
sync['modified'].append(sync_item)
|
||||
|
||||
# delete unused certs operation - haproxy does not allow to delete certs in use
|
||||
for cert in certs_to_delete:
|
||||
messages = []
|
||||
output = self._execute_remote_cmd(cmds.delSslCrt, certfile=cert)
|
||||
messages.append(output)
|
||||
sync[frontend_id]['del'].append({
|
||||
cert_item = {
|
||||
'cert': cert,
|
||||
'messages': messages
|
||||
})
|
||||
}
|
||||
sync['del_count'] += 1
|
||||
sync['deleted'].append(cert_item)
|
||||
|
||||
if output_format == 'json':
|
||||
print(json.dumps(self.diff))
|
||||
if self.output_format == 'json':
|
||||
print(json.dumps(sync))
|
||||
|
||||
if output_format == 'raw':
|
||||
if self.output_format == 'raw':
|
||||
print("## SYNC ##")
|
||||
for frontend_id, crt_list in sync.items():
|
||||
for crt_list in sync['modified']:
|
||||
print(f"CRT-LIST: {crt_list['path']}")
|
||||
print(f" FRONTEND NAME: {crt_list['frontend_name']}")
|
||||
print(f" FRONTEND ID: {crt_list['frontend_id']}")
|
||||
@@ -249,6 +339,7 @@ class Diff(SyncWithTarget):
|
||||
print(f" UPDATE: {cert['cert']}")
|
||||
for message in cert['messages']:
|
||||
print(" " + repr(message))
|
||||
|
||||
for cert in crt_list['add']:
|
||||
print(f" ADD: {cert['cert']}")
|
||||
for message in cert['messages']:
|
||||
@@ -259,10 +350,10 @@ class Diff(SyncWithTarget):
|
||||
for message in cert['messages']:
|
||||
print(" " + repr(message))
|
||||
|
||||
for cert in crt_list['del']:
|
||||
print(f"\n DEL: {cert['cert']}")
|
||||
for message in cert['messages']:
|
||||
print(" " + repr(message))
|
||||
for cert in sync['deleted']:
|
||||
print(f"\n DEL: {cert['cert']}")
|
||||
for message in cert['messages']:
|
||||
print(" " + repr(message))
|
||||
print()
|
||||
|
||||
def __iter__(self):
|
||||
@@ -339,12 +430,17 @@ class CertList(SyncWithTarget):
|
||||
def _calc_diff(self):
|
||||
""" return needed operations to get remote object in sync """
|
||||
diff = {
|
||||
'id': self.frontend_id,
|
||||
'frontend_name': self.frontend_name,
|
||||
'frontend_id': self.frontend_id,
|
||||
'path': self.path,
|
||||
'add': [],
|
||||
'del': [],
|
||||
'update': []
|
||||
'add_count': 0,
|
||||
'remove': [],
|
||||
'remove_count': 0,
|
||||
'update': [],
|
||||
'update_count': 0,
|
||||
'total_count': 0
|
||||
}
|
||||
# skip when there is no remote crt list
|
||||
if self.remote is None:
|
||||
@@ -352,8 +448,26 @@ class CertList(SyncWithTarget):
|
||||
|
||||
# certs to add, delete and update on the remote target
|
||||
diff['add'] = self.diff_list(self.local, self.remote)
|
||||
diff['del'] = self.diff_list(self.remote, self.local)
|
||||
diff['add_count'] = len(diff['add'])
|
||||
#for certpath in self.diff_list(self.local, self.remote):
|
||||
# diff['add'].append({
|
||||
# "certfile": certpath,
|
||||
# "meta": self._execute_remote_cmd(cmds.showSslCert, certfile=certpath)
|
||||
# })
|
||||
#diff['add_count'] = len(diff['add'])
|
||||
|
||||
# remove
|
||||
for certpath in self.diff_list(self.remote, self.local):
|
||||
diff['remove'].append({
|
||||
"certfile": certpath,
|
||||
"meta": self._execute_remote_cmd(cmds.showSslCert, certfile=certpath.split(":")[0])
|
||||
})
|
||||
diff['remove_count'] = len(diff['remove'])
|
||||
|
||||
diff['update'] = [cert.diff for cert in self.certs if cert.diff]
|
||||
diff['update_count'] = len(diff['update'])
|
||||
|
||||
diff['total_count'] = diff['add_count'] + diff['remove_count'] + diff['update_count']
|
||||
|
||||
return diff
|
||||
|
||||
@@ -499,7 +613,7 @@ def get_args():
|
||||
)
|
||||
parser.add_argument(
|
||||
'command',
|
||||
choices=['status', 'diff', 'sync', 'transactions', 'abort'],
|
||||
choices=['diff', 'actions', 'sync', 'transactions', 'abort'],
|
||||
nargs='+',
|
||||
help="Execute one or more operations."
|
||||
)
|
||||
@@ -520,10 +634,36 @@ def get_args():
|
||||
)
|
||||
parser.add_argument(
|
||||
'--output',
|
||||
'-o',
|
||||
help='Specify output format.',
|
||||
choices=['json', 'raw'],
|
||||
choices=['json', 'raw', 'bootgrid'],
|
||||
default="raw"
|
||||
)
|
||||
parser.add_argument(
|
||||
'--page-rows',
|
||||
help='Limit output to the specified numbers of rows per page.',
|
||||
default=None
|
||||
)
|
||||
parser.add_argument(
|
||||
'--page',
|
||||
help='Output page number.',
|
||||
default=None
|
||||
)
|
||||
parser.add_argument(
|
||||
'--search',
|
||||
help='Search for string.',
|
||||
default=None
|
||||
)
|
||||
parser.add_argument(
|
||||
'--sort-col',
|
||||
help='Sort output on this column.',
|
||||
default=None
|
||||
)
|
||||
parser.add_argument(
|
||||
'--sort-dir',
|
||||
help='Sort output in this direction.',
|
||||
default=None
|
||||
)
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
@@ -562,16 +702,16 @@ def get_crt_lists_from_config(configfile):
|
||||
|
||||
args = get_args()
|
||||
crt_lists = get_crt_lists_from_config(args.config)
|
||||
diff = Diff(crt_lists=crt_lists)
|
||||
diff = Diff(crt_lists=crt_lists, **vars(args))
|
||||
|
||||
""" Sync ssl certs from configfile to HaProxy """
|
||||
if "status" in args.command:
|
||||
diff.show_status(args.output)
|
||||
if "diff" in args.command:
|
||||
diff.show_diff(args.output)
|
||||
diff.show_diff()
|
||||
if "actions" in args.command:
|
||||
diff.show_actions()
|
||||
if "abort" in args.command:
|
||||
diff.abort(args.output)
|
||||
diff.abort()
|
||||
if "transactions" in args.command:
|
||||
diff.show_transactions(args.output)
|
||||
diff.show_transactions()
|
||||
if "sync" in args.command:
|
||||
diff.sync(args.output)
|
||||
diff.sync()
|
||||
|
||||
@@ -78,15 +78,27 @@ parameters: set-server-weight --server-ids %s --value %s
|
||||
type:script_output
|
||||
message:change haproxy weight for multiple server
|
||||
|
||||
[cert_diff_list]
|
||||
command:/usr/local/opnsense/scripts/OPNsense/HAProxy/syncCerts.py
|
||||
parameters: actions --output bootgrid --page-rows %s --page %s --search %s --sort-col %s --sort-dir %s
|
||||
type:script_output
|
||||
message:Show certificate diff list
|
||||
|
||||
[cert_diff]
|
||||
command:/usr/local/opnsense/scripts/OPNsense/HAProxy/syncCerts.py
|
||||
parameters: diff --output json --frontends %s
|
||||
parameters: diff --frontend-ids %s --output raw
|
||||
type:script_output
|
||||
message:Show diff between configured ssl certificates and certs from HAProxy memory for multiple frontends
|
||||
|
||||
[cert_actions]
|
||||
command:/usr/local/opnsense/scripts/OPNsense/HAProxy/syncCerts.py
|
||||
parameters: actions --frontend-ids %s --output raw
|
||||
type:script_output
|
||||
message:Show diff between configured ssl certificates and certs from HAProxy memory for multiple frontends
|
||||
|
||||
[cert_sync]
|
||||
command:/usr/local/opnsense/scripts/OPNsense/HAProxy/syncCerts.py
|
||||
parameters: sync --frontends %s --output json
|
||||
parameters: sync --frontend-ids %s --output json
|
||||
type:script_output
|
||||
message:Sync ssl certificates into HAProxy memory for multiple frontends
|
||||
|
||||
|
||||
Reference in New Issue
Block a user