Generering af konfigurationer til nginx, historie med én pull-anmodning

Hilsen, kammerater. Smukt på mine kampservere Nginx har kørt siden 2006, og gennem årene med administrationen har jeg akkumuleret en masse konfigurationer og skabeloner. Jeg roste nginx meget og på en eller anden måde viste det sig, at jeg selv startede en nginx hub på hub'en, vis frem m/
Venner bad mig om at oprette en udviklingsgård til dem, og i stedet for at trække dem i mine specifikke skabeloner, huskede jeg et interessant projekt nginxconfig.io, som spreder konfigurationer på hylderne og forbereder alt til lader kryptere osv. Jeg tænkte, hvorfor ikke? Jeg blev dog rasende over det faktum, at nginxconfig tilbyder mig at downloade zip-arkivet til browseren, uden at tillade mig at uploade det direkte til serveren ved hjælp af wget/fetch/curl. Hvilket sludder, hvorfor skal jeg bruge det i browseren, jeg skal bruge det på serveren fra konsollen. Vred gik jeg til github for at se indmaden i projektet, hvilket førte til dets gaffel og som et resultat en pull-anmodning. Hvilket jeg ikke ville skrive om, hvis det ikke var interessant 😉

Generering af konfigurationer til nginx, historie med én pull-anmodning

Før jeg gravede i kilderne, kiggede jeg selvfølgelig på, hvor Chrome trækker det genererede zip-arkiv med konfigurationer, og der ventede en adresse, der starter med "blob:", på mig, ups. Det er allerede blevet klart, at tjenesten ikke genererer noget undervejs, faktisk er det hele udført af js. Faktisk er zip-arkivet genereret af klienten, browseren og javascriptet selv. De der. skønheden er, at projektet nginxconfig.io kan simpelthen gemmes som en html-side, uploades til nogle narod.ru og det vil virke) Dette er en meget sjov og interessant løsning, men den er frygtelig ubelejlig til at opsætte servere, faktisk præcis til det, som dette projekt blev skabt. Download det genererede arkiv med en browser, og overfør det derefter til serveren ved hjælp af nc... i 2019? Jeg satte mig selv til opgave at finde en måde at downloade den resulterende konfiguration direkte til serveren.
Efter at have splittet projektet begyndte jeg at tænke over, hvad mine muligheder var. Opgaven kompliceredes af, at jeg ikke ønskede at fravige betingelsen om, at projektet skulle forblive en ren front-end, uden nogen back-end. Selvfølgelig ville den enkleste løsning være at trække nodejs op og tvinge det til at generere et arkiv med konfigurationer ved hjælp af direkte links.
Faktisk var der ikke mange muligheder. Mere præcist kom der kun én til at tænke på. Vi skal opsætte konfigurationerne og få et link, som vi kan kopiere til serverkonsollen for at få et zip-arkiv.
Flere tekstfiler i det resulterende zip-arkiv vejede en del, bogstaveligt talt et par kilobyte. Den åbenlyse løsning var at hente base64-strengen fra det genererede zip-arkiv og smide den ind i bufferen, mens du var på serveren med kommandoen i konsollen

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

vi kunne lave den samme zip-fil.

nginxconfig.io blev skrevet i AngularJS, kan jeg ikke engang forestille mig, hvor mange kilometer kode der ville have været påkrævet, hvis forfatteren ikke havde valgt en reaktiv js-ramme. Men jeg kan udmærket forestille mig, hvor meget enklere og smukkere alt dette kunne implementeres i VueJS, selvom dette er et helt andet emne.
I projektressourcerne ser vi en metode til at generere et zip-arkiv:

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

alt er ret simpelt, ved at bruge biblioteket jszip Der oprettes en zip, hvor konfigurationsfilerne placeres. Efter oprettelse af zip-arkivet, feeder js det til browseren ved hjælp af biblioteket FileSaver.js:

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

hvor indhold er det resulterende blob-objekt i zip-arkivet.

Ok, alt hvad jeg skulle gøre var at tilføje en anden knap ved siden af ​​den, og når jeg klikkede på den, ville jeg ikke gemme det resulterende zip-arkiv i browseren, men hente base64-koden fra den. Efter at have rodet lidt rundt, fik jeg 2 metoder, i stedet for kun én 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',
	});
};

Som du måske har bemærket, flyttede jeg generationen af ​​selve zip-arkivet til den private genererZip-metode og så videre. Dette er AngularJS, og forfatteren selv holder fast i tilbagekald og implementerede det ikke gennem løfter. downloadZip gjorde stadig saveAs som output, mens downloadBase64 gjorde noget lidt anderledes. Vi opretter et FileReader-objekt, der kom til os i html5 og allerede er ret ledig til brug. Som på én gang kan lave en base64-streng ud fra en klat, eller rettere sagt, den laver en DataURL-streng, men det er ikke så vigtigt for os, fordi DataURL indeholder præcis det, vi har brug for. Bingo, en lille hage ventede mig, da jeg prøvede at lægge alt dette i bufferen. Forfatteren brugte biblioteket i projektet clipboardjs, som giver dig mulighed for at arbejde med udklipsholderen uden flash-objekter, baseret på den valgte tekst. Til at begynde med besluttede jeg mig for at sætte min base64 i et element med display:none;, men i dette tilfælde kunne jeg ikke sætte det på udklipsholderen, fordi der sker ingen adskillelse. Derfor, i stedet for display:none; jeg gjorde

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

hvilket gjorde det muligt for mig både at skjule elementet og faktisk lade det blive på siden. Voila, opgaven var fuldført, da jeg klikkede på min knap, blev en linje som denne placeret i bufferen:

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

som jeg blot indsatte i konsollen på serveren og straks modtog et zip-arkiv med alle configs.
Og selvfølgelig sendte jeg en pull-anmodning til forfatteren, fordi... projektet er aktivt og livligt, jeg vil gerne se opdateringer fra forfatteren og have min egen knap) For de interesserede, her er det min gaffel projektet og mig selv Træk anmodning, hvor du kan se hvad jeg rettede/tilføjede.
God udvikling alle sammen)

Generering af konfigurationer til nginx, historie med én pull-anmodning

Kilde: www.habr.com

Tilføj en kommentar