Generazione di configurazioni per nginx, cronologia di una richiesta pull

Saluti, compagni. Bellissimo sui miei server di combattimento nginx è attivo dal 2006 e nel corso degli anni della sua amministrazione ho accumulato molte configurazioni e modelli. Ho elogiato molto nginx e in qualche modo si è scoperto che ho anche avviato un hub nginx sull'hub, mettiti in mostra m/
Gli amici mi hanno chiesto di creare una farm di sviluppo per loro e, invece di trascinare loro i miei modelli specifici, mi sono ricordato di un progetto interessante nginxconfig.io, che sparge le configurazioni sugli scaffali e prepara tutto per la crittografia, ecc. Ho pensato, perché no? Tuttavia, ero infuriato dal fatto che nginxconfig mi offrisse di scaricare l'archivio zip nel browser, senza permettermi di caricarlo direttamente sul server utilizzando wget/fetch/curl. Che sciocchezza, perché ne ho bisogno nel browser, ne ho bisogno sul server dalla console. Arrabbiato, sono andato su github per vedere il cuore del progetto, che ha portato al suo fork e, di conseguenza, a una richiesta pull. Di cui non scriverei se non fosse interessante 😉

Generazione di configurazioni per nginx, cronologia di una richiesta pull

Ovviamente, prima di scavare nei sorgenti, ho guardato dove Chrome estrae l'archivio zip generato con le configurazioni, e lì mi aspettava un indirizzo che inizia con "blob:", oops. È già diventato chiaro che il servizio non genera nulla lungo il percorso, infatti è tutto fatto da js. Infatti, l'archivio zip viene generato dal client, dal browser e dallo stesso JavaScript. Quelli. il bello è che il progetto nginxconfig.io può essere semplicemente salvato come pagina html, caricato su alcuni narod.ru e funzionerà) Questa è una soluzione molto divertente e interessante, tuttavia è terribilmente scomoda per configurare i server, infatti, esattamente per il motivo per cui è stato creato questo progetto. Scaricare l'archivio generato con un browser, e poi trasferirlo sul server utilizzando nc... nel 2019? Mi sono posto il compito di trovare un modo per scaricare la configurazione risultante direttamente sul server.
Dopo aver biforcato il progetto, ho iniziato a pensare a quali fossero le mie opzioni. Il compito è stato complicato dal fatto che non volevo discostarmi dalla condizione che il progetto rimanesse un puro front-end, senza back-end. Naturalmente, la soluzione più semplice sarebbe quella di richiamare nodejs e forzarlo a generare un archivio con configurazioni utilizzando collegamenti diretti.
In realtà non c'erano molte opzioni. Più precisamente, me ne è venuto in mente solo uno. Dobbiamo impostare le configurazioni e ottenere un collegamento che possiamo copiare sulla console del server per ottenere un archivio zip.
Diversi file di testo nell'archivio zip risultante pesavano parecchio, letteralmente pochi kilobyte. La soluzione ovvia era prendere la stringa base64 dall'archivio zip generato e gettarla nel buffer, mentre sul server con il comando nella console

echo 'base64string' | base64 --decode > config.zip

potremmo creare questo stesso file zip.

nginxconfig.io è stato scritto in AngularJS, non riesco nemmeno a immaginare quanti chilometri di codice sarebbero stati necessari se l'autore non avesse scelto un framework js reattivo. Ma posso perfettamente immaginare quanto tutto ciò potrebbe essere implementato in VueJS in modo più semplice e bello, anche se questo è un argomento completamente diverso.
Nelle risorse del progetto vediamo un metodo per generare un archivio zip:

$scope.downloadZip = function() {
	var zip = new JSZip();

	var sourceCodes = $window.document.querySelectorAll('main .file .code.source');

	for (var i = 0; i < sourceCodes.length; i++) {
		var sourceCode = sourceCodes[i];

		var name	= sourceCode.dataset.filename;
		var content	= sourceCode.children[0].children[0].innerText;

		if (!$scope.isSymlink() && name.match(/^sites-available//)) {
			name = name.replace(/^sites-available//, 'sites-enabled/');
		}

		zip.file(name, content);

		if (name.match(/^sites-available//)) {
			zip.file(name.replace(/^sites-available//, 'sites-enabled/'), '../' + name, {
				unixPermissions: parseInt('120755', 8),
			});
		}
	}

	zip.generateAsync({
		type: 'blob',
		platform: 'UNIX',
	}).then(function(content) {
		saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');
	});

	gtag('event', $scope.getDomains().join(','), {
		event_category: 'download_zip',
	});
};

tutto è abbastanza semplice, utilizzando la libreria jszip Viene creato uno zip in cui vengono posizionati i file di configurazione. Dopo aver creato l'archivio zip, js lo alimenta al browser utilizzando la libreria FileSaver.js:

saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');

dove contenuto è l'oggetto BLOB risultante dell'archivio zip.

Ok, tutto quello che dovevo fare era aggiungere un altro pulsante accanto e quando ci cliccavo sopra, non avrei salvato l'archivio zip risultante nel browser, ma avrei ottenuto da esso il codice base64. Dopo aver armeggiato un po', ho ottenuto 2 metodi, invece di un solo downloadZip:

$scope.downloadZip = function() {
	generateZip(function (content) {
		saveAs(content, 'nginxconfig.io-' + $scope.getDomains().join(',') + '.zip');
	});

	gtag('event', $scope.getDomains().join(','), {
		event_category: 'download_zip',
	});
};
$scope.downloadBase64 = function() {
	generateZip(function (content) {
		var reader = new FileReader();
		reader.readAsDataURL(content);
		reader.onloadend = function() {
			var base64 = reader.result.replace(/^data:.+;base64,/, '');
			// в переменной base64 как раз нужный мне zip архив в виде base64 строки
		}
	});

	gtag('event', $scope.getDomains().join(','), {
		event_category: 'download_base64',
	});
};

Come avrai notato, ho spostato la generazione dell'archivio zip stesso nel metodo generateZip privato e così via. Questo è AngularJS e l'autore stesso si attiene ai callback e non lo ha implementato tramite promesse. downloadZip eseguiva comunque saveAs come output, mentre downloadBase64 faceva qualcosa di leggermente diverso. Creiamo un oggetto FileReader che ci è arrivato in html5 ed è già abbastanza доступный per uso. Che, contemporaneamente, può creare una stringa base64 da un blob, o meglio, può creare una stringa DataURL, ma questo per noi non è così importante, perché DataURL contiene esattamente ciò di cui abbiamo bisogno. Bingo, mi aspettava un piccolo intoppo quando ho provato a mettere tutto questo nel buffer. L'autore ha utilizzato la libreria nel progetto appunti, che ti consente di lavorare con gli appunti senza oggetti flash, in base al testo selezionato. Inizialmente, avevo deciso di mettere il mio base64 in un elemento con display:none;, ma in questo caso non potevo metterlo negli appunti perché non avviene alcuna separazione. Pertanto, invece di display:none; L'ho fatto

position: absolute;
z-index: -1;
opacity: 0;

che mi ha permesso sia di nascondere l'elemento alla vista sia di lasciarlo effettivamente sulla pagina. Voilà, l'attività è stata completata, quando ho fatto clic sul pulsante, nel buffer è stata inserita una riga come questa:

echo 'base64string' | base64 --decode > config.zip

che ho semplicemente incollato nella console del server e ho subito ricevuto un archivio zip con tutte le configurazioni.
E, ovviamente, ho inviato una pull request all'autore, perché... il progetto è attivo e vivace, mi piacerebbe vedere gli aggiornamenti dell'autore e avere un mio pulsante) Per chi fosse interessato, eccolo qui la mia forchetta progetto e me stesso richiesta di pull, dove puoi vedere cosa ho corretto/aggiunto.
Buon sviluppo a tutti)

Generazione di configurazioni per nginx, cronologia di una richiesta pull

Fonte: habr.com

Aggiungi un commento