diff --git a/Readme.md b/Readme.md index 2da3cd3..ee96f81 100644 --- a/Readme.md +++ b/Readme.md @@ -32,6 +32,7 @@ Request to will serve ({ + default: { + resolve: () => "/root/path", + }, +})); + beforeEach(() => { vi.resetAllMocks(); vi.clearAllMocks(); diff --git a/packages/cli/src/__snapshots__/list-container.test.ts.snap b/packages/cli/src/__snapshots__/list-container.test.ts.snap index 477c298..88529d0 100644 --- a/packages/cli/src/__snapshots__/list-container.test.ts.snap +++ b/packages/cli/src/__snapshots__/list-container.test.ts.snap @@ -1,6 +1,6 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`List container > success > commmand found local-ssl-management container running 1`] = ` +exports[`Actions - listContainer > success > commmand found local-ssl-management container running 1`] = ` [MockFunction spy] { "calls": [ [ diff --git a/packages/cli/src/__snapshots__/on-create-action.test.ts.snap b/packages/cli/src/__snapshots__/on-create-action.test.ts.snap index 92e3fd4..a5e9209 100644 --- a/packages/cli/src/__snapshots__/on-create-action.test.ts.snap +++ b/packages/cli/src/__snapshots__/on-create-action.test.ts.snap @@ -1,10 +1,10 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`On create action > success > multiple services > domain config created sucessfully (does not exists /ssl) 1`] = ` +exports[`Actions - onCreateAction > success > multiple services > domain config created sucessfully (does not exists /ssl) 1`] = ` [MockFunction writeFileSync] { "calls": [ [ - "/Users/dimaslz/Development/local-ssl-management/packages/cli/src/.local-ssl-management/nginx.conf", + "/root/path/.local-ssl-management/nginx.conf", "user nginx; worker_processes 20; @@ -81,7 +81,7 @@ http { }", ], [ - "/Users/dimaslz/Development/local-ssl-management/packages/cli/src/.local-ssl-management/Dockerfile", + "/root/path/.local-ssl-management/Dockerfile", "FROM nginx # RUN rm -f /etc/nginx/conf.d/default.conf @@ -105,7 +105,7 @@ EXPOSE 80 443 CMD ["nginx", "-g", "daemon off;"]", ], [ - "/Users/dimaslz/Development/local-ssl-management/packages/cli/src/.local-ssl-management/config.json", + "/root/path/.local-ssl-management/config.json", "[ { "id": "48d1a85c-377a-40ef-8a82-d1405f7a074f", @@ -138,11 +138,11 @@ CMD ["nginx", "-g", "daemon off;"]", } `; -exports[`On create action > success > multiple services > domain config created sucessfully 1`] = ` +exports[`Actions - onCreateAction > success > multiple services > domain config created sucessfully 1`] = ` [MockFunction writeFileSync] { "calls": [ [ - "/Users/dimaslz/Development/local-ssl-management/packages/cli/src/.local-ssl-management/nginx.conf", + "/root/path/.local-ssl-management/nginx.conf", "user nginx; worker_processes 20; @@ -243,7 +243,7 @@ location ~ ^/app-name(/?)(.*) { }", ], [ - "/Users/dimaslz/Development/local-ssl-management/packages/cli/src/.local-ssl-management/Dockerfile", + "/root/path/.local-ssl-management/Dockerfile", "FROM nginx # RUN rm -f /etc/nginx/conf.d/default.conf @@ -267,7 +267,7 @@ EXPOSE 80 443 CMD ["nginx", "-g", "daemon off;"]", ], [ - "/Users/dimaslz/Development/local-ssl-management/packages/cli/src/.local-ssl-management/config.json", + "/root/path/.local-ssl-management/config.json", "[ { "id": "54a04fef-f263-4eab-a17a-016c76986160", @@ -305,11 +305,11 @@ CMD ["nginx", "-g", "daemon off;"]", } `; -exports[`On create action > success > single service > domain config created sucessfully (does not exists /ssl) 1`] = ` +exports[`Actions - onCreateAction > success > single service > domain config created sucessfully (does not exists /ssl) 1`] = ` [MockFunction writeFileSync] { "calls": [ [ - "/Users/dimaslz/Development/local-ssl-management/packages/cli/src/.local-ssl-management/nginx.conf", + "/root/path/.local-ssl-management/nginx.conf", "user nginx; worker_processes 20; @@ -386,7 +386,7 @@ http { }", ], [ - "/Users/dimaslz/Development/local-ssl-management/packages/cli/src/.local-ssl-management/Dockerfile", + "/root/path/.local-ssl-management/Dockerfile", "FROM nginx # RUN rm -f /etc/nginx/conf.d/default.conf @@ -410,7 +410,7 @@ EXPOSE 80 443 CMD ["nginx", "-g", "daemon off;"]", ], [ - "/Users/dimaslz/Development/local-ssl-management/packages/cli/src/.local-ssl-management/config.json", + "/root/path/.local-ssl-management/config.json", "[ { "id": "48d1a85c-377a-40ef-8a82-d1405f7a074f", @@ -443,11 +443,11 @@ CMD ["nginx", "-g", "daemon off;"]", } `; -exports[`On create action > success > single service > domain config created sucessfully 1`] = ` +exports[`Actions - onCreateAction > success > single service > domain config created sucessfully 1`] = ` [MockFunction writeFileSync] { "calls": [ [ - "/Users/dimaslz/Development/local-ssl-management/packages/cli/src/.local-ssl-management/nginx.conf", + "/root/path/.local-ssl-management/nginx.conf", "user nginx; worker_processes 20; @@ -524,7 +524,7 @@ http { }", ], [ - "/Users/dimaslz/Development/local-ssl-management/packages/cli/src/.local-ssl-management/Dockerfile", + "/root/path/.local-ssl-management/Dockerfile", "FROM nginx # RUN rm -f /etc/nginx/conf.d/default.conf @@ -548,7 +548,7 @@ EXPOSE 80 443 CMD ["nginx", "-g", "daemon off;"]", ], [ - "/Users/dimaslz/Development/local-ssl-management/packages/cli/src/.local-ssl-management/config.json", + "/root/path/.local-ssl-management/config.json", "[ { "id": "48d1a85c-377a-40ef-8a82-d1405f7a074f", diff --git a/packages/cli/src/__snapshots__/on-list-action.test.ts.snap b/packages/cli/src/__snapshots__/on-list-action.test.ts.snap index 5182a05..bffad92 100644 --- a/packages/cli/src/__snapshots__/on-list-action.test.ts.snap +++ b/packages/cli/src/__snapshots__/on-list-action.test.ts.snap @@ -1,6 +1,6 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`On list action > list domains availables 1`] = ` +exports[`Actions - onListAction > list domains availables 1`] = ` [MockFunction spy] { "calls": [ [ diff --git a/packages/cli/src/__snapshots__/on-update-action.test.ts.snap b/packages/cli/src/__snapshots__/on-update-action.test.ts.snap index de2115d..3b563bb 100644 --- a/packages/cli/src/__snapshots__/on-update-action.test.ts.snap +++ b/packages/cli/src/__snapshots__/on-update-action.test.ts.snap @@ -1,6 +1,6 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html -exports[`On update action > success > update location > update domain by domain id 1`] = ` +exports[`Actions - onUpdateAction > success > update location > update domain by domain id 1`] = ` [MockFunction writeFileSync] { "calls": [ [ @@ -138,7 +138,7 @@ CMD ["nginx", "-g", "daemon off;"]", } `; -exports[`On update action > success > update location > update domain by domain key 1`] = ` +exports[`Actions - onUpdateAction > success > update location > update domain by domain key 1`] = ` [MockFunction writeFileSync] { "calls": [ [ @@ -276,7 +276,7 @@ CMD ["nginx", "-g", "daemon off;"]", } `; -exports[`On update action > success > update location and port > update domain by domain id 1`] = ` +exports[`Actions - onUpdateAction > success > update location and port > update domain by domain id 1`] = ` [MockFunction writeFileSync] { "calls": [ [ @@ -414,7 +414,7 @@ CMD ["nginx", "-g", "daemon off;"]", } `; -exports[`On update action > success > update port > update domain by domain id 1`] = ` +exports[`Actions - onUpdateAction > success > update port > update domain by domain id 1`] = ` [MockFunction writeFileSync] { "calls": [ [ @@ -552,7 +552,7 @@ CMD ["nginx", "-g", "daemon off;"]", } `; -exports[`On update action > success > update port > update domain by domain key 1`] = ` +exports[`Actions - onUpdateAction > success > update port > update domain by domain key 1`] = ` [MockFunction writeFileSync] { "calls": [ [ diff --git a/packages/cli/src/constants.ts b/packages/cli/src/constants.ts index 964a4f1..0dcd9ce 100644 --- a/packages/cli/src/constants.ts +++ b/packages/cli/src/constants.ts @@ -1,3 +1,2 @@ -export const { pathname: DIRNAME } = new URL(import.meta.url); export const HOSTS_START = "#--------------- LOCAL SSL ---------------#"; export const HOSTS_END = "#--------------- LOCAL SSL ---------------#"; diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 914eedb..a29fddd 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -4,10 +4,11 @@ import { Command } from "commander"; import fs from "fs"; import path from "path"; -import onCreateAction from "./on-create-action"; -import onListAction from "./on-list-action"; -import onRemoveAction from "./on-remove-action"; -import onUpdateAction from "./on-update-action"; +import onCreateAction from "@/on-create-action"; +import onListAction from "@/on-list-action"; +import onRemoveAction from "@/on-remove-action"; +import onResetHosts from "@/on-reset-hosts"; +import onUpdateAction from "@/on-update-action"; const createBaseFolders = () => { const distPath = path.resolve(__dirname, "./"); @@ -68,6 +69,11 @@ const cli = () => { ) .action(onRemoveAction); + program + .command("reset") + .description("Remove all domain in `/etc/hosts` created by this cli") + .action(onResetHosts); + program.parse(); }; diff --git a/packages/cli/src/list-container.test.ts b/packages/cli/src/list-container.test.ts index 325ea5e..e3c7718 100644 --- a/packages/cli/src/list-container.test.ts +++ b/packages/cli/src/list-container.test.ts @@ -1,9 +1,9 @@ import consola from "consola"; import shell from "shelljs"; -import listContainer from "./list-container"; +import listContainer from "@/list-container"; -describe("List container", () => { +describe("Actions - listContainer", () => { describe("success", () => { test("commmand found local-ssl-management container running", async () => { // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/packages/cli/src/on-create-action.test.ts b/packages/cli/src/on-create-action.test.ts index 735d430..3deb619 100644 --- a/packages/cli/src/on-create-action.test.ts +++ b/packages/cli/src/on-create-action.test.ts @@ -2,14 +2,14 @@ import consola from "consola"; import fs from "fs"; import shell from "shelljs"; -import onCreateAction from "./on-create-action"; +import onCreateAction from "@/on-create-action"; -vi.mock("./list-container"); -vi.mock("./utils/domain-exists-in-hosts", () => ({ +vi.mock("@/list-container"); +vi.mock("@/utils/domain-exists-in-hosts", () => ({ domainExistsInHosts: () => false, })); -describe("On create action", () => { +describe("Actions - onCreateAction", () => { beforeEach(() => { vi.spyOn(fs, "readFileSync").mockReturnValue("[]"); vi.spyOn(fs, "existsSync").mockReturnValueOnce(true); @@ -146,7 +146,7 @@ describe("On create action", () => { expect(shell.exec).toBeCalledTimes(2); expect(shell.exec).nthCalledWith( 1, - "NAME=local-ssl-management && docker rm -f $NAME && docker rmi -f $NAME && docker build --no-cache -t $NAME /Users/dimaslz/Development/local-ssl-management/packages/cli/src/.local-ssl-management && docker run --name $NAME -p 80:80 -p 443:443 -d $NAME", + "NAME=local-ssl-management && docker rm -f $NAME && docker rmi -f $NAME && docker build --no-cache -t $NAME /root/path/.local-ssl-management && docker run --name $NAME -p 80:80 -p 443:443 -d $NAME", { silent: true }, ); expect(shell.exec).nthCalledWith( @@ -204,7 +204,7 @@ describe("On create action", () => { expect(shell.exec).toBeCalledTimes(2); expect(shell.exec).nthCalledWith( 1, - "NAME=local-ssl-management && docker rm -f $NAME && docker rmi -f $NAME && docker build --no-cache -t $NAME /Users/dimaslz/Development/local-ssl-management/packages/cli/src/.local-ssl-management && docker run --name $NAME -p 80:80 -p 443:443 -d $NAME", + "NAME=local-ssl-management && docker rm -f $NAME && docker rmi -f $NAME && docker build --no-cache -t $NAME /root/path/.local-ssl-management && docker run --name $NAME -p 80:80 -p 443:443 -d $NAME", { silent: true }, ); expect(shell.exec).nthCalledWith( @@ -313,7 +313,7 @@ describe("On create action", () => { expect(shell.exec).toBeCalledTimes(2); expect(shell.exec).nthCalledWith( 1, - "NAME=local-ssl-management && docker rm -f $NAME && docker rmi -f $NAME && docker build --no-cache -t $NAME /Users/dimaslz/Development/local-ssl-management/packages/cli/src/.local-ssl-management && docker run --name $NAME -p 80:80 -p 443:443 -d $NAME", + "NAME=local-ssl-management && docker rm -f $NAME && docker rmi -f $NAME && docker build --no-cache -t $NAME /root/path/.local-ssl-management && docker run --name $NAME -p 80:80 -p 443:443 -d $NAME", { silent: true }, ); expect(shell.exec).nthCalledWith( @@ -374,7 +374,7 @@ describe("On create action", () => { expect(shell.exec).toBeCalledTimes(2); expect(shell.exec).nthCalledWith( 1, - "NAME=local-ssl-management && docker rm -f $NAME && docker rmi -f $NAME && docker build --no-cache -t $NAME /Users/dimaslz/Development/local-ssl-management/packages/cli/src/.local-ssl-management && docker run --name $NAME -p 80:80 -p 443:443 -d $NAME", + "NAME=local-ssl-management && docker rm -f $NAME && docker rmi -f $NAME && docker build --no-cache -t $NAME /root/path/.local-ssl-management && docker run --name $NAME -p 80:80 -p 443:443 -d $NAME", { silent: true }, ); expect(shell.exec).nthCalledWith( diff --git a/packages/cli/src/on-create-action.ts b/packages/cli/src/on-create-action.ts index 65637f3..d167f29 100644 --- a/packages/cli/src/on-create-action.ts +++ b/packages/cli/src/on-create-action.ts @@ -4,14 +4,14 @@ import crypto from "crypto"; import fs from "fs"; import path from "path"; -import generateProxyImage from "./generate-proxy-image"; +import { generateProxyImage, updateHosts } from "@/utils"; + import { domainExistsInHosts, validateDomain, validateLocation, validatePort, } from "./utils"; -import { updateHosts } from "./utils/hosts"; const distPath = path.resolve(__dirname, "./"); const rootPath = `${distPath}/.local-ssl-management`; diff --git a/packages/cli/src/on-list-action.test.ts b/packages/cli/src/on-list-action.test.ts index b501da7..31a5e6f 100644 --- a/packages/cli/src/on-list-action.test.ts +++ b/packages/cli/src/on-list-action.test.ts @@ -2,9 +2,9 @@ import consola from "consola"; import fs from "fs"; import shell from "shelljs"; -import onListAction from "./on-list-action"; +import onListAction from "@/on-list-action"; -describe("On list action", () => { +describe("Actions - onListAction", () => { test("no domains available", () => { vi.spyOn(fs, "readFileSync").mockReturnValue("[]"); diff --git a/packages/cli/src/on-remove-action.test.ts b/packages/cli/src/on-remove-action.test.ts index 3624def..f817173 100644 --- a/packages/cli/src/on-remove-action.test.ts +++ b/packages/cli/src/on-remove-action.test.ts @@ -2,18 +2,13 @@ import consola from "consola"; import fs from "fs"; import shell from "shelljs"; -import generateProxyImage from "./generate-proxy-image"; -import onRemoveAction from "./on-remove-action"; - -vi.mock("./list-container"); -vi.mock("./generate-proxy-image"); -vi.mock("path", () => ({ - default: { - resolve: () => "/root/path", - }, -})); - -describe("On remove action", () => { +import onRemoveAction from "@/on-remove-action"; +import { generateProxyImage } from "@/utils/generate-proxy-image"; + +vi.mock("@/list-container"); +vi.mock("@/utils/generate-proxy-image"); + +describe("Actions - onRemoveAction", () => { describe("failure", () => { test("removing domain by name does not exists", () => { vi.spyOn(fs, "readFileSync").mockReturnValueOnce(JSON.stringify([])); diff --git a/packages/cli/src/on-remove-action.ts b/packages/cli/src/on-remove-action.ts index 02cfe52..2230e60 100644 --- a/packages/cli/src/on-remove-action.ts +++ b/packages/cli/src/on-remove-action.ts @@ -3,7 +3,8 @@ import consola from "consola"; import fs from "fs"; import path from "path"; -import generateProxyImage from "./generate-proxy-image"; +import { generateProxyImage } from "@/utils"; + const distPath = path.resolve(__dirname, "./"); const rootPath = `${distPath}/.local-ssl-management`; const configPath = `${rootPath}/config.json`; diff --git a/packages/cli/src/on-reset-hosts.test.ts b/packages/cli/src/on-reset-hosts.test.ts new file mode 100644 index 0000000..193e048 --- /dev/null +++ b/packages/cli/src/on-reset-hosts.test.ts @@ -0,0 +1,33 @@ +import fs from "fs"; + +import { HOSTS_END, HOSTS_START } from "@/constants"; +import onResetHosts from "@/on-reset-hosts"; +import { updateSystemHosts } from "@/utils/update-system-hosts"; + +vi.mock("@/utils/update-system-hosts"); + +describe("Actions - onResetHosts", () => { + describe("success", () => { + test("reset hosts", async () => { + vi.spyOn(fs, "readFileSync").mockReturnValue(` +127.0.0.1 other-domain.com +${HOSTS_START} +127.0.0.1 domain-name.com +${HOSTS_END} +`); + await onResetHosts(); + + expect(fs.writeFileSync).toBeCalledWith( + expect.stringMatching(/\/.tmp-hosts/i), + ` +127.0.0.1 other-domain.com + +`, + ); + + expect(updateSystemHosts).toBeCalledWith( + expect.stringMatching(/\/.tmp-hosts/i), + ); + }); + }); +}); diff --git a/packages/cli/src/on-reset-hosts.ts b/packages/cli/src/on-reset-hosts.ts new file mode 100644 index 0000000..78f0480 --- /dev/null +++ b/packages/cli/src/on-reset-hosts.ts @@ -0,0 +1,33 @@ +import fs from "fs"; +import path from "path"; + +import { HOSTS_END, HOSTS_START } from "@/constants"; +import { updateSystemHosts } from "@/utils"; + +const distPath = path.resolve(__dirname, "./"); +const tmpHostsPath = `${distPath}/.tmp-hosts`; + +const onResetHosts = async () => { + const hostsContent = await fs.readFileSync("/etc/hosts", { + encoding: "utf8", + }); + const [, localSSLHosts = ""] = + hostsContent.match(new RegExp(`${HOSTS_START}([^#]+)${HOSTS_END}`, "im")) || + []; + + let newContent = ""; + if (!localSSLHosts) { + newContent = `${hostsContent}\n\n${HOSTS_START}\n[^\n]+\n${HOSTS_END}\n`; + } else { + newContent = hostsContent.replace( + new RegExp(`${HOSTS_START}[^#]+${HOSTS_END}`, "im"), + newContent, + ); + } + + await fs.writeFileSync(tmpHostsPath, newContent); + + updateSystemHosts(tmpHostsPath); +}; + +export default onResetHosts; diff --git a/packages/cli/src/on-update-action.test.ts b/packages/cli/src/on-update-action.test.ts index ff77c53..4f3cc9b 100644 --- a/packages/cli/src/on-update-action.test.ts +++ b/packages/cli/src/on-update-action.test.ts @@ -2,19 +2,19 @@ import consola from "consola"; import fs from "fs"; import shell from "shelljs"; -import onUpdateAction from "./on-update-action"; -import { validatePort } from "./utils"; +import onUpdateAction from "@/on-update-action"; +import { validatePort } from "@/utils"; -vi.mock("./utils/validate-port"); +vi.mock("@/utils/validate-port"); -vi.mock("./list-container"); +vi.mock("@/list-container"); vi.mock("path", () => ({ default: { resolve: () => "/root/path", }, })); -describe("On update action", () => { +describe("Actions - onUpdateAction", () => { describe("failures", () => { test("update domain by wrong domain name", () => { const domain = "foo-domain.com"; diff --git a/packages/cli/src/on-update-action.ts b/packages/cli/src/on-update-action.ts index 8d8c5cf..186cbf7 100644 --- a/packages/cli/src/on-update-action.ts +++ b/packages/cli/src/on-update-action.ts @@ -3,8 +3,7 @@ import consola from "consola"; import fs from "fs"; import path from "path"; -import generateProxyImage from "./generate-proxy-image"; -import { validatePort } from "./utils"; +import { generateProxyImage, validatePort } from "@/utils"; const distPath = path.resolve(__dirname, "./"); const rootPath = `${distPath}/.local-ssl-management`; diff --git a/packages/cli/src/utils/__snapshots__/generate-proxy-image.test.ts.snap b/packages/cli/src/utils/__snapshots__/generate-proxy-image.test.ts.snap new file mode 100644 index 0000000..5d0caee --- /dev/null +++ b/packages/cli/src/utils/__snapshots__/generate-proxy-image.test.ts.snap @@ -0,0 +1,913 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`Generate proxy image > success > multiple service > create domain config succesful (domain certs does not exists) 1`] = ` +[MockFunction writeFileSync] { + "calls": [ + [ + "/root/path/.local-ssl-management/nginx.conf", + "user nginx; +worker_processes 20; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + server { + listen 443 ssl; + server_name _; + ssl_certificate /etc/nginx/localhost-cert.pem; + ssl_certificate_key /etc/nginx/localhost-key.pem; + location / { + root /var/www/html; + } + } + + server { + listen 80 default_server; + server_name _; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + location / { + root /var/www/html; + } + } + + server { + listen 443 ssl; + + autoindex off; + + access_log /var/log/nginx/demo.com.access.log; + error_log /var/log/nginx/demo.com.error.log; + + server_tokens off; + server_name demo.com; + + ssl_certificate /etc/nginx/demo.com-cert.pem; + ssl_certificate_key /etc/nginx/demo.com-key.pem; + + gzip_static on; + + location ~ ^/(/?)(.*) { + gzip on; + gzip_disable "msie6"; + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_min_length 256; + gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon; + proxy_pass http://11.22.33.445:4000/$2; + proxy_redirect off; + proxy_http_version 1.1; + proxy_cache_bypass $http_upgrade; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_set_header 'Access-Control-Allow-Origin' '*'; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; + expires off; + } + +location ~ ^/app-name(/?)(.*) { + gzip on; + gzip_disable "msie6"; + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_min_length 256; + gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon; + proxy_pass http://11.22.33.445:3000/$2; + proxy_redirect off; + proxy_http_version 1.1; + proxy_cache_bypass $http_upgrade; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_set_header 'Access-Control-Allow-Origin' '*'; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; + expires off; + } + } +}", + ], + [ + "/root/path/.local-ssl-management/Dockerfile", + "FROM nginx + +# RUN rm -f /etc/nginx/conf.d/default.conf + +# WORKDIR /var/www/html +# COPY index.html /var/www/html +# RUN chmod 755 /var/www/html/index.html + +COPY nginx.conf /etc/nginx/conf.d/ + +COPY ssl/demo.com-key.pem /etc/nginx/ +COPY ssl/demo.com-cert.pem /etc/nginx/ + +COPY ssl/localhost-key.pem /etc/nginx/ +COPY ssl/localhost-cert.pem /etc/nginx/ + +COPY nginx.conf /etc/nginx/ + +EXPOSE 80 443 + +CMD ["nginx", "-g", "daemon off;"]", + ], + ], + "results": [ + { + "type": "return", + "value": undefined, + }, + { + "type": "return", + "value": undefined, + }, + ], +} +`; + +exports[`Generate proxy image > success > multiple service > create domain config succesful (domain certs does not exists) 2`] = ` +[MockFunction spy] { + "calls": [ + [ + " +┌──────────────────┬─────────────┐ +│ domain │ app running │ +├──────────────────┼─────────────┤ +│ https://demo.com │ no │ +└──────────────────┴─────────────┘ +", + ], + ], + "results": [ + { + "type": "return", + "value": undefined, + }, + ], +} +`; + +exports[`Generate proxy image > success > multiple service > create domain config succesful (localhost certs does not exists) 1`] = ` +[MockFunction writeFileSync] { + "calls": [ + [ + "/root/path/.local-ssl-management/nginx.conf", + "user nginx; +worker_processes 20; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + server { + listen 443 ssl; + server_name _; + ssl_certificate /etc/nginx/localhost-cert.pem; + ssl_certificate_key /etc/nginx/localhost-key.pem; + location / { + root /var/www/html; + } + } + + server { + listen 80 default_server; + server_name _; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + location / { + root /var/www/html; + } + } + + server { + listen 443 ssl; + + autoindex off; + + access_log /var/log/nginx/demo.com.access.log; + error_log /var/log/nginx/demo.com.error.log; + + server_tokens off; + server_name demo.com; + + ssl_certificate /etc/nginx/demo.com-cert.pem; + ssl_certificate_key /etc/nginx/demo.com-key.pem; + + gzip_static on; + + location ~ ^/(/?)(.*) { + gzip on; + gzip_disable "msie6"; + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_min_length 256; + gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon; + proxy_pass http://11.22.33.445:4000/$2; + proxy_redirect off; + proxy_http_version 1.1; + proxy_cache_bypass $http_upgrade; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_set_header 'Access-Control-Allow-Origin' '*'; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; + expires off; + } + +location ~ ^/app-name(/?)(.*) { + gzip on; + gzip_disable "msie6"; + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_min_length 256; + gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon; + proxy_pass http://11.22.33.445:3000/$2; + proxy_redirect off; + proxy_http_version 1.1; + proxy_cache_bypass $http_upgrade; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_set_header 'Access-Control-Allow-Origin' '*'; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; + expires off; + } + } +}", + ], + [ + "/root/path/.local-ssl-management/Dockerfile", + "FROM nginx + +# RUN rm -f /etc/nginx/conf.d/default.conf + +# WORKDIR /var/www/html +# COPY index.html /var/www/html +# RUN chmod 755 /var/www/html/index.html + +COPY nginx.conf /etc/nginx/conf.d/ + +COPY ssl/demo.com-key.pem /etc/nginx/ +COPY ssl/demo.com-cert.pem /etc/nginx/ + +COPY ssl/localhost-key.pem /etc/nginx/ +COPY ssl/localhost-cert.pem /etc/nginx/ + +COPY nginx.conf /etc/nginx/ + +EXPOSE 80 443 + +CMD ["nginx", "-g", "daemon off;"]", + ], + ], + "results": [ + { + "type": "return", + "value": undefined, + }, + { + "type": "return", + "value": undefined, + }, + ], +} +`; + +exports[`Generate proxy image > success > multiple service > create domain config succesful (localhost certs does not exists) 2`] = ` +[MockFunction spy] { + "calls": [ + [ + " +┌──────────────────┬─────────────┐ +│ domain │ app running │ +├──────────────────┼─────────────┤ +│ https://demo.com │ no │ +└──────────────────┴─────────────┘ +", + ], + ], + "results": [ + { + "type": "return", + "value": undefined, + }, + ], +} +`; + +exports[`Generate proxy image > success > multiple service > does not exists localhost certs 1`] = ` +[MockFunction writeFileSync] { + "calls": [ + [ + "/root/path/.local-ssl-management/nginx.conf", + "user nginx; +worker_processes 20; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + server { + listen 443 ssl; + server_name _; + ssl_certificate /etc/nginx/localhost-cert.pem; + ssl_certificate_key /etc/nginx/localhost-key.pem; + location / { + root /var/www/html; + } + } + + server { + listen 80 default_server; + server_name _; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + location / { + root /var/www/html; + } + } + + server { + listen 443 ssl; + + autoindex off; + + access_log /var/log/nginx/demo.com.access.log; + error_log /var/log/nginx/demo.com.error.log; + + server_tokens off; + server_name demo.com; + + ssl_certificate /etc/nginx/demo.com-cert.pem; + ssl_certificate_key /etc/nginx/demo.com-key.pem; + + gzip_static on; + + location ~ ^/(/?)(.*) { + gzip on; + gzip_disable "msie6"; + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_min_length 256; + gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon; + proxy_pass http://11.22.33.445:4000/$2; + proxy_redirect off; + proxy_http_version 1.1; + proxy_cache_bypass $http_upgrade; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_set_header 'Access-Control-Allow-Origin' '*'; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; + expires off; + } + +location ~ ^/app-name(/?)(.*) { + gzip on; + gzip_disable "msie6"; + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_min_length 256; + gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon; + proxy_pass http://11.22.33.445:3000/$2; + proxy_redirect off; + proxy_http_version 1.1; + proxy_cache_bypass $http_upgrade; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_set_header 'Access-Control-Allow-Origin' '*'; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; + expires off; + } + } +}", + ], + [ + "/root/path/.local-ssl-management/Dockerfile", + "FROM nginx + +# RUN rm -f /etc/nginx/conf.d/default.conf + +# WORKDIR /var/www/html +# COPY index.html /var/www/html +# RUN chmod 755 /var/www/html/index.html + +COPY nginx.conf /etc/nginx/conf.d/ + +COPY ssl/demo.com-key.pem /etc/nginx/ +COPY ssl/demo.com-cert.pem /etc/nginx/ + +COPY ssl/localhost-key.pem /etc/nginx/ +COPY ssl/localhost-cert.pem /etc/nginx/ + +COPY nginx.conf /etc/nginx/ + +EXPOSE 80 443 + +CMD ["nginx", "-g", "daemon off;"]", + ], + ], + "results": [ + { + "type": "return", + "value": undefined, + }, + { + "type": "return", + "value": undefined, + }, + ], +} +`; + +exports[`Generate proxy image > success > multiple service > does not exists localhost certs 2`] = ` +[MockFunction spy] { + "calls": [ + [ + " +┌──────────────────┬─────────────┐ +│ domain │ app running │ +├──────────────────┼─────────────┤ +│ https://demo.com │ no │ +└──────────────────┴─────────────┘ +", + ], + ], + "results": [ + { + "type": "return", + "value": undefined, + }, + ], +} +`; + +exports[`Generate proxy image > success > single service > create domain config succesful (domain certs does not exists) 1`] = ` +[MockFunction writeFileSync] { + "calls": [ + [ + "/root/path/.local-ssl-management/nginx.conf", + "user nginx; +worker_processes 20; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + server { + listen 443 ssl; + server_name _; + ssl_certificate /etc/nginx/localhost-cert.pem; + ssl_certificate_key /etc/nginx/localhost-key.pem; + location / { + root /var/www/html; + } + } + + server { + listen 80 default_server; + server_name _; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + location / { + root /var/www/html; + } + } + + server { + listen 443 ssl; + + autoindex off; + + access_log /var/log/nginx/demo.com.access.log; + error_log /var/log/nginx/demo.com.error.log; + + server_tokens off; + server_name demo.com; + + ssl_certificate /etc/nginx/demo.com-cert.pem; + ssl_certificate_key /etc/nginx/demo.com-key.pem; + + gzip_static on; + + location ~ ^/(/?)(.*) { + gzip on; + gzip_disable "msie6"; + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_min_length 256; + gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon; + proxy_pass http://11.22.33.445:4000/$2; + proxy_redirect off; + proxy_http_version 1.1; + proxy_cache_bypass $http_upgrade; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_set_header 'Access-Control-Allow-Origin' '*'; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; + expires off; + } + } +}", + ], + [ + "/root/path/.local-ssl-management/Dockerfile", + "FROM nginx + +# RUN rm -f /etc/nginx/conf.d/default.conf + +# WORKDIR /var/www/html +# COPY index.html /var/www/html +# RUN chmod 755 /var/www/html/index.html + +COPY nginx.conf /etc/nginx/conf.d/ + +COPY ssl/demo.com-key.pem /etc/nginx/ +COPY ssl/demo.com-cert.pem /etc/nginx/ + +COPY ssl/localhost-key.pem /etc/nginx/ +COPY ssl/localhost-cert.pem /etc/nginx/ + +COPY nginx.conf /etc/nginx/ + +EXPOSE 80 443 + +CMD ["nginx", "-g", "daemon off;"]", + ], + ], + "results": [ + { + "type": "return", + "value": undefined, + }, + { + "type": "return", + "value": undefined, + }, + ], +} +`; + +exports[`Generate proxy image > success > single service > create domain config succesful (domain certs does not exists) 2`] = ` +[MockFunction spy] { + "calls": [ + [ + " +┌──────────────────┬─────────────┐ +│ domain │ app running │ +├──────────────────┼─────────────┤ +│ https://demo.com │ no │ +└──────────────────┴─────────────┘ +", + ], + ], + "results": [ + { + "type": "return", + "value": undefined, + }, + ], +} +`; + +exports[`Generate proxy image > success > single service > create domain config succesful (localhost certs does not exists) 1`] = ` +[MockFunction writeFileSync] { + "calls": [ + [ + "/root/path/.local-ssl-management/nginx.conf", + "user nginx; +worker_processes 20; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + server { + listen 443 ssl; + server_name _; + ssl_certificate /etc/nginx/localhost-cert.pem; + ssl_certificate_key /etc/nginx/localhost-key.pem; + location / { + root /var/www/html; + } + } + + server { + listen 80 default_server; + server_name _; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + location / { + root /var/www/html; + } + } + + server { + listen 443 ssl; + + autoindex off; + + access_log /var/log/nginx/demo.com.access.log; + error_log /var/log/nginx/demo.com.error.log; + + server_tokens off; + server_name demo.com; + + ssl_certificate /etc/nginx/demo.com-cert.pem; + ssl_certificate_key /etc/nginx/demo.com-key.pem; + + gzip_static on; + + location ~ ^/(/?)(.*) { + gzip on; + gzip_disable "msie6"; + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_min_length 256; + gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon; + proxy_pass http://11.22.33.445:4000/$2; + proxy_redirect off; + proxy_http_version 1.1; + proxy_cache_bypass $http_upgrade; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_set_header 'Access-Control-Allow-Origin' '*'; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; + expires off; + } + } +}", + ], + [ + "/root/path/.local-ssl-management/Dockerfile", + "FROM nginx + +# RUN rm -f /etc/nginx/conf.d/default.conf + +# WORKDIR /var/www/html +# COPY index.html /var/www/html +# RUN chmod 755 /var/www/html/index.html + +COPY nginx.conf /etc/nginx/conf.d/ + +COPY ssl/demo.com-key.pem /etc/nginx/ +COPY ssl/demo.com-cert.pem /etc/nginx/ + +COPY ssl/localhost-key.pem /etc/nginx/ +COPY ssl/localhost-cert.pem /etc/nginx/ + +COPY nginx.conf /etc/nginx/ + +EXPOSE 80 443 + +CMD ["nginx", "-g", "daemon off;"]", + ], + ], + "results": [ + { + "type": "return", + "value": undefined, + }, + { + "type": "return", + "value": undefined, + }, + ], +} +`; + +exports[`Generate proxy image > success > single service > create domain config succesful (localhost certs does not exists) 2`] = ` +[MockFunction spy] { + "calls": [ + [ + " +┌──────────────────┬─────────────┐ +│ domain │ app running │ +├──────────────────┼─────────────┤ +│ https://demo.com │ no │ +└──────────────────┴─────────────┘ +", + ], + ], + "results": [ + { + "type": "return", + "value": undefined, + }, + ], +} +`; + +exports[`Generate proxy image > success > single service > does not exists localhost certs 1`] = ` +[MockFunction writeFileSync] { + "calls": [ + [ + "/root/path/.local-ssl-management/nginx.conf", + "user nginx; +worker_processes 20; + +error_log /var/log/nginx/error.log warn; +pid /var/run/nginx.pid; + +events { + worker_connections 1024; +} + +http { + server { + listen 443 ssl; + server_name _; + ssl_certificate /etc/nginx/localhost-cert.pem; + ssl_certificate_key /etc/nginx/localhost-key.pem; + location / { + root /var/www/html; + } + } + + server { + listen 80 default_server; + server_name _; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + + location / { + root /var/www/html; + } + } + + server { + listen 443 ssl; + + autoindex off; + + access_log /var/log/nginx/domain.tld.access.log; + error_log /var/log/nginx/domain.tld.error.log; + + server_tokens off; + server_name domain.tld; + + ssl_certificate /etc/nginx/domain.tld-cert.pem; + ssl_certificate_key /etc/nginx/domain.tld-key.pem; + + gzip_static on; + + location ~ ^/(/?)(.*) { + gzip on; + gzip_disable "msie6"; + gzip_vary on; + gzip_proxied any; + gzip_comp_level 6; + gzip_buffers 16 8k; + gzip_http_version 1.1; + gzip_min_length 256; + gzip_types text/plain text/css application/json application/x-javascript application/javascript text/xml application/xml application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf font/opentype image/svg+xml image/x-icon; + proxy_pass http://11.22.33.445:3000/$2; + proxy_redirect off; + proxy_http_version 1.1; + proxy_cache_bypass $http_upgrade; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection 'upgrade'; + proxy_set_header Host $host; + proxy_set_header 'Access-Control-Allow-Origin' '*'; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header 'Cache-Control' 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0'; + expires off; + } + } +}", + ], + [ + "/root/path/.local-ssl-management/Dockerfile", + "FROM nginx + +# RUN rm -f /etc/nginx/conf.d/default.conf + +# WORKDIR /var/www/html +# COPY index.html /var/www/html +# RUN chmod 755 /var/www/html/index.html + +COPY nginx.conf /etc/nginx/conf.d/ + +COPY ssl/domain.tld-key.pem /etc/nginx/ +COPY ssl/domain.tld-cert.pem /etc/nginx/ + +COPY ssl/localhost-key.pem /etc/nginx/ +COPY ssl/localhost-cert.pem /etc/nginx/ + +COPY nginx.conf /etc/nginx/ + +EXPOSE 80 443 + +CMD ["nginx", "-g", "daemon off;"]", + ], + ], + "results": [ + { + "type": "return", + "value": undefined, + }, + { + "type": "return", + "value": undefined, + }, + ], +} +`; + +exports[`Generate proxy image > success > single service > does not exists localhost certs 2`] = ` +[MockFunction spy] { + "calls": [ + [ + " +┌────────────────────┬─────────────┐ +│ domain │ app running │ +├────────────────────┼─────────────┤ +│ https://domain.tld │ no │ +└────────────────────┴─────────────┘ +", + ], + ], + "results": [ + { + "type": "return", + "value": undefined, + }, + ], +} +`; diff --git a/packages/cli/src/generate-proxy-image.test.ts b/packages/cli/src/utils/generate-proxy-image.test.ts similarity index 98% rename from packages/cli/src/generate-proxy-image.test.ts rename to packages/cli/src/utils/generate-proxy-image.test.ts index 1ac4b80..772d8b4 100644 --- a/packages/cli/src/generate-proxy-image.test.ts +++ b/packages/cli/src/utils/generate-proxy-image.test.ts @@ -3,15 +3,11 @@ import consola from "consola"; import fs from "fs"; import shell from "shelljs"; -import generateProxyImage from "./generate-proxy-image"; -import listContainer from "./list-container"; - -vi.mock("./list-container"); -vi.mock("path", () => ({ - default: { - resolve: () => "/root/path", - }, -})); +import listContainer from "@/list-container"; + +import { generateProxyImage } from "."; + +vi.mock("@/list-container"); describe("Generate proxy image", () => { beforeEach(() => { diff --git a/packages/cli/src/generate-proxy-image.ts b/packages/cli/src/utils/generate-proxy-image.ts similarity index 95% rename from packages/cli/src/generate-proxy-image.ts rename to packages/cli/src/utils/generate-proxy-image.ts index de6560e..a8bfddf 100644 --- a/packages/cli/src/generate-proxy-image.ts +++ b/packages/cli/src/utils/generate-proxy-image.ts @@ -6,8 +6,8 @@ import fs from "fs"; import path from "path"; import shell from "shelljs"; -import listContainer from "./list-container"; -import Templates from "./templates"; +import listContainer from "@/list-container"; +import Templates from "@/templates"; const LOCAL_IP = getLocalIP(); const distPath = path.resolve(__dirname, "./"); @@ -38,7 +38,7 @@ const renderTable = (config: Config[]) => { shell.echo(`\n${tablePing.toString()}\n`); }; -const generateProxyImage = (config: Config[]) => { +export const generateProxyImage = (config: Config[]) => { if (!config.length) { consola.warn("Does not exists config to create reverse proxy"); @@ -147,5 +147,3 @@ docker run --name $NAME -p 80:80 -p 443:443 -d $NAME`, renderTable(config); }; - -export default generateProxyImage; diff --git a/packages/cli/src/utils/index.ts b/packages/cli/src/utils/index.ts index 60e8b89..20a9ef8 100644 --- a/packages/cli/src/utils/index.ts +++ b/packages/cli/src/utils/index.ts @@ -1,4 +1,6 @@ export * from "./domain-exists-in-hosts"; +export * from "./generate-proxy-image"; +export * from "./hosts"; export * from "./list-configs"; export * from "./update-system-hosts"; export * from "./validate-domain";