Generación de configuraciones para nginx, historial de una solicitud de extracción

Saludos, camaradas. Hermosa en mis servidores de combate nginx ha estado funcionando desde 2006 y a lo largo de los años de su administración he acumulado muchas configuraciones y plantillas. Elogié mucho a nginx y de alguna manera resultó que incluso comencé un concentrador nginx en el concentrador, preséntalo m/
Mis amigos me pidieron que les creara una granja de desarrollo y, en lugar de arrastrarles mis plantillas específicas, recordé un proyecto interesante. nginxconfig.io, que dispersa las configuraciones en los estantes y prepara todo para permitir el cifrado, etc. Pensé, ¿por qué no? Sin embargo, me enfureció el hecho de que nginxconfig me ofrece descargar el archivo zip en el navegador, sin permitirme cargarlo directamente al servidor usando wget/fetch/curl. Qué tontería, por qué lo necesito en el navegador, lo necesito en el servidor desde la consola. Enojado, fui a github para ver las entrañas del proyecto, lo que llevó a su bifurcación y, como resultado, a una solicitud de extracción. Sobre el cual no escribiría si no fuera interesante 😉

Generación de configuraciones para nginx, historial de una solicitud de extracción

Por supuesto, antes de profundizar en las fuentes, miré de dónde Chrome extrae el archivo zip generado con las configuraciones, y allí me estaba esperando una dirección que comenzaba con “blob:”, ¡ups! Ya ha quedado claro que el servicio no genera nada en el camino, de hecho, todo lo hace js. De hecho, el archivo zip lo genera el cliente, el navegador y el propio javascript. Aquellos. lo bonito es que el proyecto nginxconfig.io se puede guardar simplemente como una página html y cargarla en algún narod.ru y funcionará) Esta es una solución muy divertida e interesante, sin embargo, es terriblemente inconveniente para configurar servidores, de hecho, exactamente para lo que se creó este proyecto. Descargue el archivo generado con un navegador y luego transfiéralo al servidor usando nc... ¿en 2019? Me propuse la tarea de encontrar una manera de descargar la configuración resultante directamente al servidor.
Después de bifurcar el proyecto, comencé a pensar cuáles eran mis opciones. La tarea se complicó porque no quería desviarme de la condición de que el proyecto siguiera siendo puramente front-end, sin ningún back-end. Por supuesto, la solución más sencilla sería abrir nodejs y obligarlo a generar un archivo con configuraciones mediante enlaces directos.
En realidad, no había muchas opciones. Más precisamente, sólo me vino a la mente uno. Necesitamos configurar las configuraciones y obtener un enlace que podamos copiar a la consola del servidor para obtener un archivo zip.
Varios archivos de texto en el archivo zip resultante pesaban bastante, literalmente unos pocos kilobytes. La solución obvia era obtener la cadena base64 del archivo zip generado y tirarla al búfer, mientras estaba en el servidor con el comando en la consola.

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

Podríamos crear este mismo archivo zip.

nginxconfig.io fue escrito en AngularJS, ni siquiera puedo imaginar qué kilómetros de código se habrían requerido si el autor no hubiera elegido un marco js reactivo. Pero puedo imaginar perfectamente cuánto más simple y hermoso se podría implementar todo esto en VueJS, aunque este es un tema completamente diferente.
En los recursos del proyecto vemos un método para generar un archivo 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',
	});
};

todo es bastante simple, usando la biblioteca jszip Se crea un zip donde se colocan los archivos de configuración. Después de crear el archivo zip, js lo envía al navegador usando la biblioteca FileSaver.js:

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

donde contenido es el objeto blob resultante del archivo zip.

Ok, todo lo que tenía que hacer era agregar otro botón al lado y cuando hacía clic en él, no guardaba el archivo zip resultante en el navegador, sino que obtenía el código base64. Después de jugar un poco, obtuve 2 métodos, en lugar de solo un 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',
	});
};

Como habrás notado, moví la generación del archivo zip al método privado generateZip, y así sucesivamente. Este es AngularJS, y el propio autor se ciñe a las devoluciones de llamada y no las implementa mediante promesas. downloadZip todavía guardó como salida, mientras que downloadBase64 hizo algo ligeramente diferente. Creamos un objeto FileReader que nos llegó en html5 y ya es bastante доступный para usar. Lo cual, en un momento, puede generar una cadena base64 a partir de un blob, o más bien, genera una cadena DataURL, pero esto no es tan importante para nosotros, porque DataURL contiene exactamente lo que necesitamos. Bingo, me esperaba un pequeño inconveniente cuando intenté poner todo esto en el buffer. El autor utilizó la biblioteca en el proyecto. Portapapeles, que le permite trabajar con el portapapeles sin objetos flash, según el texto seleccionado. Inicialmente decidí poner mi base64 en un elemento con display:none;, pero en este caso no pude ponerlo en el portapapeles porque no se produce ninguna separación. Por lo tanto, en lugar de display:none; Hice

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

lo que me permitió ocultar el elemento a la vista y dejarlo en la página. Listo, la tarea se completó, cuando hice clic en mi botón, se colocó una línea como esta en el búfer:

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

que simplemente pegué en la consola del servidor e inmediatamente recibí un archivo zip con todas las configuraciones.
Y, por supuesto, envié una solicitud de extracción al autor, porque... el proyecto está activo y animado, me gustaría ver actualizaciones del autor y tener mi propio botón) Para aquellos interesados, aquí está mi tenedor proyecto y él mismo solicitud de extracción, donde puedes ver lo que corregí/agregué.
Feliz desarrollo a todos)

Generación de configuraciones para nginx, historial de una solicitud de extracción

Fuente: habr.com

Añadir un comentario