Generering av konfigurasjoner for nginx, historie med én pull-forespørsel

Hilsen, kamerater. Vakkert på mine kampservere nginx har kjørt siden 2006 og i løpet av årene med administrasjonen har jeg samlet mange konfigurasjoner og maler. Jeg berømmet nginx mye og på en eller annen måte viste det seg at jeg til og med startet en nginx-hub på huben også, vis frem m/
Venner ba meg sette opp en utviklingsgård for dem, og i stedet for å dra dem mine spesifikke maler, husket jeg et interessant prosjekt nginxconfig.io, som sprer konfigurasjoner i hyllene og forbereder alt for lar kryptering osv. Jeg tenkte, hvorfor ikke? Imidlertid ble jeg rasende over det faktum at nginxconfig tilbyr meg å laste ned zip-arkivet til nettleseren, uten å la meg laste det opp direkte til serveren ved å bruke wget/fetch/curl. Hvilket tull, hvorfor trenger jeg det i nettleseren, jeg trenger det på serveren fra konsollen. Jeg gikk sint til github for å se guts av prosjektet, noe som førte til gaffelen og, som et resultat, en pull-forespørsel. Som jeg ikke ville skrevet om hvis det ikke var interessant 😉

Generering av konfigurasjoner for nginx, historie med én pull-forespørsel

Selvfølgelig, før jeg gravde i kildene, så jeg på hvor Chrome henter det genererte zip-arkivet med konfigurasjoner, og der ventet en adresse som startet med "blob:" på meg, ups. Det har allerede blitt klart at tjenesten ikke genererer noe underveis, faktisk er det hele gjort av js. Faktisk er zip-arkivet generert av klienten, nettleseren og javascriptet selv. De. det fine er at prosjektet nginxconfig.io kan enkelt lagres som en HTML-side, lastes opp til noen narod.ru og det vil fungere) Dette er en veldig morsom og interessant løsning, men den er veldig upraktisk for å sette opp servere, faktisk akkurat for det dette prosjektet ble opprettet. Laste ned det genererte arkivet med en nettleser, og deretter overføre det til serveren ved hjelp av nc... i 2019? Jeg satte meg selv i oppgave å finne en måte å laste ned den resulterende konfigurasjonen direkte til serveren.
Etter å ha forkastet prosjektet, begynte jeg å tenke på hva alternativene mine var. Oppgaven ble komplisert av at jeg ikke ønsket å fravike vilkåret om at prosjektet skulle forbli en ren front-end, uten noen back-end. Selvfølgelig ville den enkleste løsningen være å trekke opp nodejs og tvinge den til å generere et arkiv med konfigurasjoner ved å bruke direkte lenker.
Egentlig var det ikke mange alternativer. Mer presist kom bare én til tankene. Vi må sette opp konfigurasjonene og få en lenke som vi kan kopiere til serverkonsollen for å få et zip-arkiv.
Flere tekstfiler i det resulterende zip-arkivet veide ganske mye, bokstavelig talt noen få kilobyte. Den åpenbare løsningen var å hente base64-strengen fra det genererte zip-arkivet og kaste den inn i bufferen mens du var på serveren med kommandoen i konsollen

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

vi kunne lage den samme zip-filen.

nginxconfig.io ble skrevet i AngularJS, kan jeg ikke engang forestille meg hvilke kilometer med kode som ville vært nødvendig hvis forfatteren ikke hadde valgt et reaktivt js-rammeverk. Men jeg kan perfekt forestille meg hvor mye enklere og vakrere alt dette kan implementeres i VueJS, selv om dette er et helt annet tema.
I prosjektressursene ser vi en metode for å 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 ganske enkelt, ved å bruke biblioteket jszip En zip opprettes der konfigurasjonsfilene plasseres. Etter å ha opprettet zip-arkivet, mater js det til nettleseren ved hjelp av biblioteket FileSaver.js:

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

der innholdet er det resulterende blob-objektet i zip-arkivet.

Ok, alt jeg måtte gjøre var å legge til en annen knapp ved siden av den, og når jeg klikket på den, ville jeg ikke lagre det resulterende zip-arkivet i nettleseren, men hente base64-koden fra den. Etter å ha rotet litt, fikk jeg 2 metoder, i stedet for bare é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 kanskje har lagt merke til, flyttet jeg generasjonen av selve zip-arkivet til den private genererZip-metoden, og så videre. Dette er AngularJS, og forfatteren selv holder seg til tilbakeringinger og implementerte det ikke gjennom løfter. downloadZip gjorde fortsatt saveAs som en utgang, mens downloadBase64 gjorde noe litt annerledes. Vi lager et FileReader-objekt som kom til oss i html5 og som allerede er ganske tilgjengelig for bruk. Som på en gang kan lage en base64-streng fra en blob, eller rettere sagt, den lager en DataURL-streng, men dette er ikke så viktig for oss, fordi DataURL inneholder akkurat det vi trenger. Bingo, en liten hake ventet på meg da jeg prøvde å legge alt dette i bufferen. Forfatteren brukte biblioteket i prosjektet utklippstavler, som lar deg jobbe med utklippstavlen uten flash-objekter, basert på den valgte teksten. Til å begynne med bestemte jeg meg for å sette base64-en min i et element med display:none;, men i dette tilfellet kunne jeg ikke sette den på utklippstavlen fordi ingen separasjon forekommer. Derfor, i stedet for display:none; jeg gjorde

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

som gjorde at jeg både kunne skjule elementet og faktisk la det ligge på siden. Voila, oppgaven ble fullført, da jeg klikket på knappen min ble en linje som denne plassert i bufferen:

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

som jeg bare limte inn i konsollen på serveren og umiddelbart mottok et zip-arkiv med alle konfigurasjonene.
Og selvfølgelig sendte jeg en pull-forespørsel til forfatteren, fordi... prosjektet er aktivt og livlig, jeg vil gjerne se oppdateringer fra forfatteren og ha min egen knapp) For de som er interessert, her er den gaffelen min prosjektet og meg selv trekk forespørsel, hvor du kan se hva jeg har rettet/lagt til.
God utvikling alle sammen)

Generering av konfigurasjoner for nginx, historie med én pull-forespørsel

Kilde: www.habr.com

Legg til en kommentar