From 0374d240c3252e73899fd8216aad34a65f8d4492 Mon Sep 17 00:00:00 2001 From: shimataro Date: Mon, 30 Dec 2019 08:24:22 +0900 Subject: [PATCH] Feature/append config known hosts (#47) * * append to "config" and "known_hosts" instead of overwriting * * refactor options * * add test * * fix test * * print created files twice * * print the contents of known_hosts and config * * fix revision for test * * fix revision * * add LF to known_hosts / config * * append LF to config and known_hosts * * fix test * * reject overwriting private-key and public-key * * update test (will cause error) * * revert verify.yml * * update README and CHANGELOG * * fix example in README * * update CHANGELOG --- CHANGELOG.md | 4 ++++ README.md | 41 +++++++++++++++++++++++++++++++++++++++++ lib/main.js | 28 +++++++++++++++++++--------- lib/main.js.map | 2 +- src/main.ts | 30 ++++++++++++++++++++---------- 5 files changed, 85 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb72391..40b527f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## [Unreleased] +### Changed + +* Append contents of `config` and `known_hosts` when called multiple times. + ## [1.4.0] ### Added diff --git a/README.md b/README.md index fc83088..e07a921 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,47 @@ steps: See [Workflow syntax for GitHub Actions](https://help.github.com/en/articles/workflow-syntax-for-github-actions) for details. +### Install multiple keys + +If you want to install multiple keys, call this action multiple times. +It is useful for port forwarding. + +**NOTE:** When this action is called multiple times, **the contents of `known-hosts` and `config` will be appended**. But `public-key` and `private-key` must be saved as different name, by using `name` option. + +```yaml +runs-on: ubuntu-latest +steps: +- name: Install SSH key of bastion + uses: shimataro/ssh-key-action@v1 + with: + private-key: ${{ secrets.SSH_KEY_OF_BASTION }} + public-key: ${{ secrets.SSH_KEY_OF_BASTION_PUBLIC }} + name: id_rsa-bastion + known-hosts: ${{ secrets.KNOWN_HOSTS_OF_BASTION }} + config: | + Host bastion + HostName xxx.xxx.xxx.xxx + User user-of-bastion + IdentityFile ~/.ssh/id_rsa-bastion +- name: Install SSH key of target + uses: shimataro/ssh-key-action@v1 + with: + private-key: ${{ secrets.SSH_KEY_OF_TARGET }} + public-key: ${{ secrets.SSH_KEY_OF_TARGET_PUBLIC }} + name: id_rsa-target + known-hosts: ${{ secrets.KNOWN_HOSTS_OF_TARGET }} # will be appended! + config: | # will be appended! + Host target + HostName yyy.yyy.yyy.yyy + User user-of-target + IdentityFile ~/.ssh/id_rsa-target + ProxyCommand ssh -W %h:%p bastion +- name: Install packages + run: apt install openssh-client +- name: SCP via port-forwarding + run: scp ./foo/ target:bar/ +``` + ## License The scripts and documentation in this project are released under the [MIT License](LICENSE) diff --git a/lib/main.js b/lib/main.js index 33583bf..c33d2de 100644 --- a/lib/main.js +++ b/lib/main.js @@ -19,23 +19,35 @@ function main() { const files = [ { name: name, - mode: 0o400, contents: core.getInput("private-key"), + options: { + mode: 0o400, + flag: "ax", + }, }, { name: `${name}.pub`, - mode: 0o444, contents: core.getInput("public-key"), + options: { + mode: 0o444, + flag: "ax", + }, }, { name: "known_hosts", - mode: 0o644, - contents: core.getInput("known-hosts"), + contents: core.getInput("known-hosts") + "\n", + options: { + mode: 0o644, + flag: "a", + }, }, { name: "config", - mode: 0o644, - contents: core.getInput("config"), + contents: core.getInput("config") + "\n", + options: { + mode: 0o644, + flag: "a", + }, }, ]; // create ".ssh" directory @@ -48,9 +60,7 @@ function main() { // create files for (const file of files) { const fileName = path.join(dirName, file.name); - fs.writeFileSync(fileName, file.contents, { - mode: file.mode, - }); + fs.writeFileSync(fileName, file.contents, file.options); } console.log(`SSH key has been stored to ${dirName} successfully.`); } diff --git a/lib/main.js.map b/lib/main.js.map index 48f897a..aa16479 100644 --- a/lib/main.js.map +++ b/lib/main.js.map @@ -1 +1 @@ -{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAE7B,oDAAsC;AAStC;;GAEG;AACH,SAAS,IAAI;IAEZ,IACA;QACC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACnC,MAAM,KAAK,GAAe;YACzB;gBACC,IAAI,EAAE,IAAI;gBACV,IAAI,EAAE,KAAK;gBACX,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC;aACtC;YACD;gBACC,IAAI,EAAE,GAAG,IAAI,MAAM;gBACnB,IAAI,EAAE,KAAK;gBACX,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;aACrC;YACD;gBACC,IAAI,EAAE,aAAa;gBACnB,IAAI,EAAE,KAAK;gBACX,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC;aACtC;YACD;gBACC,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,KAAK;gBACX,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;aACjC;SACD,CAAC;QAEF,0BAA0B;QAC1B,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC3C,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE;YACrB,SAAS,EAAE,IAAI;YACf,IAAI,EAAE,KAAK;SACX,CAAC,CAAC;QAEH,eAAe;QACf,KAAI,MAAM,IAAI,IAAI,KAAK,EACvB;YACC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/C,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE;gBACzC,IAAI,EAAE,IAAI,CAAC,IAAI;aACf,CAAC,CAAC;SACH;QAED,OAAO,CAAC,GAAG,CAAC,8BAA8B,OAAO,gBAAgB,CAAC,CAAC;KACnE;IACD,OAAM,GAAG,EACT;QACC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;KAC5B;AACF,CAAC;AAED;;;GAGG;AACH,SAAS,gBAAgB;IAExB,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC;IACrE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAClC,IAAG,IAAI,KAAK,SAAS,EACrB;QACC,MAAM,KAAK,CAAC,GAAG,OAAO,iBAAiB,CAAC,CAAC;KACzC;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AAED,IAAI,EAAE,CAAC"} \ No newline at end of file +{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAE7B,oDAAsC;AAStC;;GAEG;AACH,SAAS,IAAI;IAEZ,IACA;QACC,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACnC,MAAM,KAAK,GAAe;YACzB;gBACC,IAAI,EAAE,IAAI;gBACV,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC;gBACtC,OAAO,EAAE;oBACR,IAAI,EAAE,KAAK;oBACX,IAAI,EAAE,IAAI;iBACV;aACD;YACD;gBACC,IAAI,EAAE,GAAG,IAAI,MAAM;gBACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC;gBACrC,OAAO,EAAE;oBACR,IAAI,EAAE,KAAK;oBACX,IAAI,EAAE,IAAI;iBACV;aACD;YACD;gBACC,IAAI,EAAE,aAAa;gBACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,GAAG,IAAI;gBAC7C,OAAO,EAAE;oBACR,IAAI,EAAE,KAAK;oBACX,IAAI,EAAE,GAAG;iBACT;aACD;YACD;gBACC,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,IAAI;gBACxC,OAAO,EAAE;oBACR,IAAI,EAAE,KAAK;oBACX,IAAI,EAAE,GAAG;iBACT;aACD;SACD,CAAC;QAEF,0BAA0B;QAC1B,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;QAChC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC3C,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE;YACrB,SAAS,EAAE,IAAI;YACf,IAAI,EAAE,KAAK;SACX,CAAC,CAAC;QAEH,eAAe;QACf,KAAI,MAAM,IAAI,IAAI,KAAK,EACvB;YACC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/C,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;SACxD;QAED,OAAO,CAAC,GAAG,CAAC,8BAA8B,OAAO,gBAAgB,CAAC,CAAC;KACnE;IACD,OAAM,GAAG,EACT;QACC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;KAC5B;AACF,CAAC;AAED;;;GAGG;AACH,SAAS,gBAAgB;IAExB,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC;IACrE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAClC,IAAG,IAAI,KAAK,SAAS,EACrB;QACC,MAAM,KAAK,CAAC,GAAG,OAAO,iBAAiB,CAAC,CAAC;KACzC;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AAED,IAAI,EAAE,CAAC"} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 8ee9b8f..5cf1974 100644 --- a/src/main.ts +++ b/src/main.ts @@ -6,8 +6,8 @@ import * as core from "@actions/core"; interface FileInfo { name: string; - mode: number; contents: string; + options: fs.WriteFileOptions; } /** @@ -21,23 +21,35 @@ function main(): void const files: FileInfo[] = [ { name: name, - mode: 0o400, contents: core.getInput("private-key"), + options: { + mode: 0o400, + flag: "ax", + }, }, { name: `${name}.pub`, - mode: 0o444, contents: core.getInput("public-key"), + options: { + mode: 0o444, + flag: "ax", + }, }, { name: "known_hosts", - mode: 0o644, - contents: core.getInput("known-hosts"), + contents: core.getInput("known-hosts") + "\n", + options: { + mode: 0o644, + flag: "a", + }, }, { name: "config", - mode: 0o644, - contents: core.getInput("config"), + contents: core.getInput("config") + "\n", + options: { + mode: 0o644, + flag: "a", + }, }, ]; @@ -53,9 +65,7 @@ function main(): void for(const file of files) { const fileName = path.join(dirName, file.name); - fs.writeFileSync(fileName, file.contents, { - mode: file.mode, - }); + fs.writeFileSync(fileName, file.contents, file.options); } console.log(`SSH key has been stored to ${dirName} successfully.`);