Generació de configuracions per a nginx, historial d'una sol·licitud d'extracció

Salutacions, companys. Preciós als meus servidors de combat nginx funciona des del 2006 i al llarg dels anys de la seva administració he acumulat moltes configuracions i plantilles. Vaig elogiar molt nginx i, d'alguna manera, va resultar que fins i tot vaig començar un concentrador nginx al concentrador, mostrar m/
Els amics em van demanar que els configurés una granja de desenvolupament i, en lloc d'arrossegar-los les meves plantilles específiques, vaig recordar un projecte interessant. nginxconfig.io, que dispersa les configuracions als prestatges i ho prepara tot per permetre xifrar, etc. Vaig pensar, per què no? Tanmateix, em va indignar el fet que nginxconfig m'ofereix descarregar l'arxiu zip al navegador, sense permetre'm pujar-lo directament al servidor mitjançant wget/fetch/curl. Quina tonteria, per què ho necessito al navegador, ho necessito al servidor des de la consola. Enfadat, vaig anar a github per veure les entranyes del projecte, la qual cosa va portar a la seva bifurcació i, com a resultat, una sol·licitud d'extracció. Sobre el qual no escriuria si no fos interessant 😉

Generació de configuracions per a nginx, historial d'una sol·licitud d'extracció

Per descomptat, abans d'explorar les fonts, vaig mirar d'on Chrome extreu l'arxiu zip generat amb les configuracions, i allí m'esperava una adreça que començava per "blob:", vaja. Ja ha quedat clar que el servei no genera res al llarg del camí, de fet, tot ho fa js. De fet, l'arxiu zip el genera el client, el navegador i javascript mateix. Aquells. la bellesa és que el projecte nginxconfig.io simplement es pot desar com a pàgina html, penjar-se a alguns narod.ru i funcionarà) Aquesta és una solució molt divertida i interessant, però, és terriblement incòmode per configurar servidors, de fet, exactament per al que es va crear aquest projecte. Baixeu l'arxiu generat amb un navegador i després transferiu-lo al servidor mitjançant nc... el 2019? Em vaig proposar la tasca de trobar una manera de descarregar la configuració resultant directament al servidor.
Després de bifurcar el projecte, vaig començar a pensar quines eren les meves opcions. La tasca es va complicar pel fet que no volia desviar-me de la condició que el projecte hagués de seguir sent un front-end pur, sense cap back-end. Per descomptat, la solució més senzilla seria treure nodejs i forçar-lo a generar un arxiu amb configuracions mitjançant enllaços directes.
De fet, no hi havia moltes opcions. Més precisament, només se n'ha vingut al cap un. Hem de configurar les configuracions i obtenir un enllaç que podem copiar a la consola del servidor per obtenir un arxiu zip.
Diversos fitxers de text de l'arxiu zip resultant pesaven bastant, literalment uns quants kilobytes. La solució òbvia era obtenir la cadena base64 de l'arxiu zip generat i llançar-la a la memòria intermèdia, mentre es trobava al servidor amb l'ordre a la consola.

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

podríem crear aquest mateix fitxer zip.

nginxconfig.io va ser escrit a AngularJS, ni tan sols puc imaginar quins quilòmetres de codi haurien estat necessaris si l'autor no hagués triat un marc js reactiu. Però puc imaginar perfectament com de més senzill i bonic es podria implementar tot això a VueJS, tot i que aquest és un tema completament diferent.
Als recursos del projecte veiem un mètode per generar un arxiu 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',
	});
};

tot és bastant senzill, utilitzant la biblioteca jszip Es crea un zip on es col·loquen els fitxers de configuració. Després de crear l'arxiu zip, js l'alimenta al navegador mitjançant la biblioteca FileSaver.js:

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

on el contingut és l'objecte blob resultant de l'arxiu zip.

D'acord, tot el que havia de fer era afegir un altre botó al costat i quan hi feia clic, no desaria l'arxiu zip resultant al navegador, sinó que n'obtenia el codi base64. Després de jugar una mica, vaig obtenir 2 mètodes, en lloc d'una sola descàrrega ZIP:

$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',
	});
};

Com haureu notat, vaig traslladar la generació de l'arxiu zip al mètode privat generateZip, i així successivament. Això és AngularJS, i el mateix autor s'adhereix a les devolucions de trucada i no ho va implementar mitjançant promeses. downloadZip encara va fer SaveAs com a sortida, mentre que downloadBase64 va fer alguna cosa lleugerament diferent. Creem un objecte FileReader que ens va arribar en html5 i que ja és bastant accessible per al seu ús. Que, alhora, pot fer una cadena base64 a partir d'un blob, o més aviat, fa una cadena DataURL, però això no és tan important per a nosaltres, perquè DataURL conté exactament el que necessitem. Bingo, m'esperava un petit problema quan vaig intentar posar tot això al buffer. L'autor va utilitzar la biblioteca en el projecte porta-retallsjs, que permet treballar amb el porta-retalls sense objectes flash, en funció del text seleccionat. Inicialment, vaig decidir posar el meu base64 en un element amb display:none;, però en aquest cas no el vaig poder posar al porta-retalls perquè no es produeix cap separació. Per tant, en lloc de mostrar:cap; ho vaig fer

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

que em va permetre ocultar l'element de la vista i deixar-lo a la pàgina. Voila, la tasca es va completar, quan vaig fer clic al meu botó, es va col·locar una línia com aquesta a la memòria intermèdia:

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

que simplement vaig enganxar a la consola del servidor i de seguida vaig rebre un arxiu zip amb totes les configuracions.
I, per descomptat, vaig enviar una sol·licitud d'extracció a l'autor, perquè... el projecte és actiu i animat, m'agradaria veure actualitzacions de l'autor i tenir el meu propi botó) Per als interessats, aquí el teniu la meva forquilla projecte i jo mateix sol·licitud d’estira, on podeu veure el que he corregit/afegit.
Feliç desenvolupament a tothom)

Generació de configuracions per a nginx, historial d'una sol·licitud d'extracció

Font: www.habr.com

Afegeix comentari