seijaku 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/README.md +16 -2
 - data/docs/1 - basic.md +10 -0
 - data/docs/2 - variables.md +24 -0
 - data/docs/3 - ssh.md +78 -0
 - data/lib/seijaku/executors/bash.rb +27 -0
 - data/lib/seijaku/executors/sh.rb +27 -0
 - data/lib/seijaku/executors/ssh.rb +43 -0
 - data/lib/seijaku/payload.rb +33 -0
 - data/lib/seijaku/ssh/group.rb +15 -0
 - data/lib/seijaku/ssh/host.rb +15 -0
 - data/lib/seijaku/step.rb +50 -0
 - data/lib/seijaku/task.rb +32 -0
 - data/lib/seijaku/variable.rb +24 -0
 - data/lib/seijaku/version.rb +1 -1
 - data/lib/seijaku.rb +4 -0
 - data/seijaku.gemspec +3 -5
 - metadata +57 -3
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 63fdce33cce3f7b4496f7ba0968a069554f351f5b1ea37d84c0dc20b7cfb3d49
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 01fc22c0d064e13bbf514633545ec4f947176a531bf57fe479294d816f60154b
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: ffc15482a72317f1617f65374e2de9dd86008d7d4faa64dc3a34fe9dc9e5f940f77982f2a009a82c54613b1226135e3b8a58a2a37d126e6b0a6b105d4de7b0f6
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 3bdfd31aac02d9bdd5be33b5f77f05327ac4eaa05af82654b00d9fb4c30382be07c0879ae1ac91deaaf36468e934a6f0696b7e6223659332de25a2ed22f31fca
         
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -6,7 +6,7 @@ Seijaku is a program that allows you to execute shell commands listed in YAML pa 
     | 
|
| 
       6 
6 
     | 
    
         | 
| 
       7 
7 
     | 
    
         
             
            Payloads are YAML files that describe the various tasks Seijaku will have to perform (in order). Each task contains one or more steps.
         
     | 
| 
       8 
8 
     | 
    
         | 
| 
       9 
     | 
    
         
            -
            A step is a shell command to be executed. Seijaku currently supports the following shells: bash and  
     | 
| 
      
 9 
     | 
    
         
            +
            A step is a shell command to be executed. Seijaku currently supports the following shells: bash, sh and ssh.
         
     | 
| 
       10 
10 
     | 
    
         | 
| 
       11 
11 
     | 
    
         
             
            Each task can have "pre" and "post" tasks, for example to create and delete folders, or install and uninstall software needed to run a task.
         
     | 
| 
       12 
12 
     | 
    
         | 
| 
         @@ -17,6 +17,11 @@ A step sometimes needs variables in order to be performed correctly: Seijaku sup 
     | 
|
| 
       17 
17 
     | 
    
         
             
            ```yaml
         
     | 
| 
       18 
18 
     | 
    
         
             
            name: my payload
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
      
 20 
     | 
    
         
            +
            ssh:
         
     | 
| 
      
 21 
     | 
    
         
            +
              - host: my-host
         
     | 
| 
      
 22 
     | 
    
         
            +
                user: user
         
     | 
| 
      
 23 
     | 
    
         
            +
                port: 22
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
       20 
25 
     | 
    
         
             
            variables:
         
     | 
| 
       21 
26 
     | 
    
         
             
              MY_VARIABLE: a static variable
         
     | 
| 
       22 
27 
     | 
    
         
             
              MY_ENV_VARIABLE: $MY_ENV_VARIABLE
         
     | 
| 
         @@ -37,6 +42,11 @@ tasks: 
     | 
|
| 
       37 
42 
     | 
    
         
             
                    soft_fail: true
         
     | 
| 
       38 
43 
     | 
    
         
             
                post:
         
     | 
| 
       39 
44 
     | 
    
         
             
                  - sh: "do something after"
         
     | 
| 
      
 45 
     | 
    
         
            +
              
         
     | 
| 
      
 46 
     | 
    
         
            +
              - name: task with SSH executor
         
     | 
| 
      
 47 
     | 
    
         
            +
                host: my-host
         
     | 
| 
      
 48 
     | 
    
         
            +
                steps:
         
     | 
| 
      
 49 
     | 
    
         
            +
                  - ssh: echo "executed on host"
         
     | 
| 
       40 
50 
     | 
    
         
             
            ```
         
     | 
| 
       41 
51 
     | 
    
         | 
| 
       42 
52 
     | 
    
         
             
            ## Installation
         
     | 
| 
         @@ -46,11 +56,15 @@ tasks: 
     | 
|
| 
       46 
56 
     | 
    
         
             
            * Ruby 2.5+
         
     | 
| 
       47 
57 
     | 
    
         
             
            * Rubygem
         
     | 
| 
       48 
58 
     | 
    
         | 
| 
       49 
     | 
    
         
            -
             
     | 
| 
       50 
59 
     | 
    
         
             
            Install Seijaku using Gem:
         
     | 
| 
       51 
60 
     | 
    
         | 
| 
       52 
61 
     | 
    
         
             
            ```bash
         
     | 
| 
       53 
62 
     | 
    
         
             
            gem install seijaku
         
     | 
| 
       54 
63 
     | 
    
         
             
            ```
         
     | 
| 
       55 
64 
     | 
    
         | 
| 
      
 65 
     | 
    
         
            +
            ## Usage
         
     | 
| 
       56 
66 
     | 
    
         | 
| 
      
 67 
     | 
    
         
            +
            ```bash
         
     | 
| 
      
 68 
     | 
    
         
            +
            seijaku -h
         
     | 
| 
      
 69 
     | 
    
         
            +
            seijaku -f ./my-payload.yaml
         
     | 
| 
      
 70 
     | 
    
         
            +
            ```
         
     | 
    
        data/docs/1 - basic.md	
    ADDED
    
    
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Variables
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Steps can call environment variables, listed in the `variables` dictionary.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            Variable values can either be given in the payload (static) or be defined from the executive shell.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            ```yaml
         
     | 
| 
      
 8 
     | 
    
         
            +
            name: payload with variables
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            variables:
         
     | 
| 
      
 11 
     | 
    
         
            +
              ENV_VARIABLE: value
         
     | 
| 
      
 12 
     | 
    
         
            +
              PROVIDED_ENV_VARIABLE: $PROVIDED_ENV_VARIABLE
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            tasks:
         
     | 
| 
      
 15 
     | 
    
         
            +
              - name: do something useful
         
     | 
| 
      
 16 
     | 
    
         
            +
                steps:
         
     | 
| 
      
 17 
     | 
    
         
            +
                  - sh: echo "sh executor: $ENV_VARIABLE"
         
     | 
| 
      
 18 
     | 
    
         
            +
                  - bash: echo "bash executor: $PROVIDED_ENV_VARIABLE"
         
     | 
| 
      
 19 
     | 
    
         
            +
            ```
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            ```bash
         
     | 
| 
      
 22 
     | 
    
         
            +
            export PROVIDED_ENV_VARIABLE=value 
         
     | 
| 
      
 23 
     | 
    
         
            +
            seijaku -f ./docs/variables.yaml
         
     | 
| 
      
 24 
     | 
    
         
            +
            ```
         
     | 
    
        data/docs/3 - ssh.md	
    ADDED
    
    | 
         @@ -0,0 +1,78 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # SSH
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Since version `0.1.0`, Seijaku implements a SSH step executor. Only one SSH host can be set per task.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            ```yaml
         
     | 
| 
      
 7 
     | 
    
         
            +
            name: payload with SSH executor
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            ssh:
         
     | 
| 
      
 10 
     | 
    
         
            +
              - host: my-host
         
     | 
| 
      
 11 
     | 
    
         
            +
                port: 22
         
     | 
| 
      
 12 
     | 
    
         
            +
                user: ubuntu
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            tasks:
         
     | 
| 
      
 15 
     | 
    
         
            +
              - name: do something useful
         
     | 
| 
      
 16 
     | 
    
         
            +
                host: my-host
         
     | 
| 
      
 17 
     | 
    
         
            +
                steps:
         
     | 
| 
      
 18 
     | 
    
         
            +
                  - ssh: echo "connection test"
         
     | 
| 
      
 19 
     | 
    
         
            +
            ```
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            It is recommended to run `ssh-add` before running Seijaku, as each step would require you to enter your password.
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            ## Variables
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            Variables can be set from the Seijaku executive host and ran in the SSH host context:
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            ```yaml
         
     | 
| 
      
 28 
     | 
    
         
            +
            name: payload with SSH executor (variables)
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
            ssh:
         
     | 
| 
      
 31 
     | 
    
         
            +
              - host: my-host
         
     | 
| 
      
 32 
     | 
    
         
            +
                port: 22
         
     | 
| 
      
 33 
     | 
    
         
            +
                user: ubuntu
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            variables:
         
     | 
| 
      
 36 
     | 
    
         
            +
              ENV_VARIABLE: value
         
     | 
| 
      
 37 
     | 
    
         
            +
              PROVIDED_ENV_VARIABLE: $PROVIDED_ENV_VARIABLE
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
            tasks:
         
     | 
| 
      
 40 
     | 
    
         
            +
              - name: do something useful
         
     | 
| 
      
 41 
     | 
    
         
            +
                host: my-host
         
     | 
| 
      
 42 
     | 
    
         
            +
                steps:
         
     | 
| 
      
 43 
     | 
    
         
            +
                  - ssh: echo "connection test"
         
     | 
| 
      
 44 
     | 
    
         
            +
                  - ssh: echo "$ENV_VARIABLE"
         
     | 
| 
      
 45 
     | 
    
         
            +
                  - ssh: echo "$PROVIDED_ENV_VARIABLE"
         
     | 
| 
      
 46 
     | 
    
         
            +
            ```
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            ## Bastion / Jump host / Proxy
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            You sometimes need to jump over a publicly exposed server to reach another one. Seijaku supports SSH Proxy, with a maximum of 1 hop.
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            ```yaml
         
     | 
| 
      
 53 
     | 
    
         
            +
            name: payload with SSH executor (bastion)
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            ssh:
         
     | 
| 
      
 56 
     | 
    
         
            +
              - host: bastion-host
         
     | 
| 
      
 57 
     | 
    
         
            +
                port: 22
         
     | 
| 
      
 58 
     | 
    
         
            +
                user: bastion_user
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              - host: my-host
         
     | 
| 
      
 61 
     | 
    
         
            +
                port: 22
         
     | 
| 
      
 62 
     | 
    
         
            +
                user: ubuntu
         
     | 
| 
      
 63 
     | 
    
         
            +
                bastion: bastion-host
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
            variables:
         
     | 
| 
      
 66 
     | 
    
         
            +
              ENV_VARIABLE: value
         
     | 
| 
      
 67 
     | 
    
         
            +
              PROVIDED_ENV_VARIABLE: $PROVIDED_ENV_VARIABLE
         
     | 
| 
      
 68 
     | 
    
         
            +
             
     | 
| 
      
 69 
     | 
    
         
            +
            tasks:
         
     | 
| 
      
 70 
     | 
    
         
            +
              - name: do something useful
         
     | 
| 
      
 71 
     | 
    
         
            +
                host: my-host
         
     | 
| 
      
 72 
     | 
    
         
            +
                steps:
         
     | 
| 
      
 73 
     | 
    
         
            +
                  - ssh: echo "connection test"
         
     | 
| 
      
 74 
     | 
    
         
            +
                  - ssh: echo "$ENV_VARIABLE"
         
     | 
| 
      
 75 
     | 
    
         
            +
                  - ssh: echo "$PROVIDED_ENV_VARIABLE"
         
     | 
| 
      
 76 
     | 
    
         
            +
            ```
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
            The `ssh.[].host` must be a reachable address (domain name or IP).
         
     | 
| 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "open3"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module Seijaku
         
     | 
| 
      
 6 
     | 
    
         
            +
              # executes `bash` commands
         
     | 
| 
      
 7 
     | 
    
         
            +
              class BashExecutor
         
     | 
| 
      
 8 
     | 
    
         
            +
                def initialize(raw, variables)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @command = ["bash", "-c", "'#{raw}'"]
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @variables = variables
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                def run!
         
     | 
| 
      
 14 
     | 
    
         
            +
                  stdout, stderr, exit_status = Open3.capture3(
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @variables,
         
     | 
| 
      
 16 
     | 
    
         
            +
                    @command.join(" ")
         
     | 
| 
      
 17 
     | 
    
         
            +
                  )
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  {
         
     | 
| 
      
 20 
     | 
    
         
            +
                    stdout: stdout.chomp,
         
     | 
| 
      
 21 
     | 
    
         
            +
                    stderr: stderr.chomp,
         
     | 
| 
      
 22 
     | 
    
         
            +
                    exit_status: exit_status.exitstatus,
         
     | 
| 
      
 23 
     | 
    
         
            +
                    command: @command.join(" ")
         
     | 
| 
      
 24 
     | 
    
         
            +
                  }
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,27 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "open3"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module Seijaku
         
     | 
| 
      
 6 
     | 
    
         
            +
              # Execute `sh` commands
         
     | 
| 
      
 7 
     | 
    
         
            +
              class SHExecutor
         
     | 
| 
      
 8 
     | 
    
         
            +
                def initialize(raw, variables)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @command = ["sh", "-c", "'#{raw}'"]
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @variables = variables
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                def run!
         
     | 
| 
      
 14 
     | 
    
         
            +
                  stdout, stderr, exit_status = Open3.capture3(
         
     | 
| 
      
 15 
     | 
    
         
            +
                    @variables,
         
     | 
| 
      
 16 
     | 
    
         
            +
                    @command.join(" ")
         
     | 
| 
      
 17 
     | 
    
         
            +
                  )
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  {
         
     | 
| 
      
 20 
     | 
    
         
            +
                    stdout: stdout.chomp,
         
     | 
| 
      
 21 
     | 
    
         
            +
                    stderr: stderr.chomp,
         
     | 
| 
      
 22 
     | 
    
         
            +
                    exit_status: exit_status.exitstatus,
         
     | 
| 
      
 23 
     | 
    
         
            +
                    command: @command.join(" ")
         
     | 
| 
      
 24 
     | 
    
         
            +
                  }
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,43 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require "net/ssh"
         
     | 
| 
      
 4 
     | 
    
         
            +
            require "net/ssh/proxy/jump"
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            module Seijaku
         
     | 
| 
      
 7 
     | 
    
         
            +
              # SSHExecutor connects to SSH host and runs command
         
     | 
| 
      
 8 
     | 
    
         
            +
              class SSHExecutor
         
     | 
| 
      
 9 
     | 
    
         
            +
                def initialize(raw, variables, task, ssh_hosts)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @command = ["sh", "-c", "'#{raw}'"]
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @hosts = ssh_hosts
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @variables = variables
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @task = task
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @ssh_hosts = ssh_hosts
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  raise SSHExecutorError, "no ssh host defined in payload", [] if ssh_hosts.nil?
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                def run!
         
     | 
| 
      
 20 
     | 
    
         
            +
                  machine = @ssh_hosts.hosts[@task.host]
         
     | 
| 
      
 21 
     | 
    
         
            +
                  result = { command: @command.join(" "), stdout: nil, stderr: nil }
         
     | 
| 
      
 22 
     | 
    
         
            +
                  status = {}
         
     | 
| 
      
 23 
     | 
    
         
            +
                  options = machine.bastion ? { proxy: bastion_setup } : {}
         
     | 
| 
      
 24 
     | 
    
         
            +
                  ssh = Net::SSH.start(machine.host, machine.user, port: machine.port, **options)
         
     | 
| 
      
 25 
     | 
    
         
            +
                  ssh.exec!(@command.join(" "), status: status) do |_ch, stream, data|
         
     | 
| 
      
 26 
     | 
    
         
            +
                    result[:stdout] = data.chomp if stream == :stdout
         
     | 
| 
      
 27 
     | 
    
         
            +
                    result[:stderr] = data.chomp unless stream == :stdout
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
                  ssh.close
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                  result[:exit_status] = status[:exit_code]
         
     | 
| 
      
 32 
     | 
    
         
            +
                  result
         
     | 
| 
      
 33 
     | 
    
         
            +
                end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                def bastion_setup
         
     | 
| 
      
 36 
     | 
    
         
            +
                  bastion_name = @ssh_hosts.hosts[@task.host].bastion
         
     | 
| 
      
 37 
     | 
    
         
            +
                  bastion_host = @ssh_hosts.hosts[bastion_name]
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
                  connect_str = "#{bastion_host.user}@#{bastion_host.host}:#{bastion_host.port}"
         
     | 
| 
      
 40 
     | 
    
         
            +
                  Net::SSH::Proxy::Jump.new(connect_str)
         
     | 
| 
      
 41 
     | 
    
         
            +
                end
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Seijaku
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Payload refers to the payload YAML file submitted by the user.
         
     | 
| 
      
 5 
     | 
    
         
            +
              # it includes tasks, steps, variables and name.
         
     | 
| 
      
 6 
     | 
    
         
            +
              class Payload
         
     | 
| 
      
 7 
     | 
    
         
            +
                def initialize(payload, logger)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @name = payload.fetch("name")
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @variables = get_variables(payload.fetch("variables"))
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @ssh_hosts = SSHGroup.new(payload.fetch("ssh", []))
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @tasks = payload.fetch("tasks").map do |task|
         
     | 
| 
      
 12 
     | 
    
         
            +
                    Task.new(task, @variables, logger, @ssh_hosts)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def execute!
         
     | 
| 
      
 17 
     | 
    
         
            +
                  @tasks.each(&:execute!)
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                def get_variables(payload_variables)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  sorted_variables = {}
         
     | 
| 
      
 22 
     | 
    
         
            +
                  variables = payload_variables.map do |var|
         
     | 
| 
      
 23 
     | 
    
         
            +
                    Variable.new(var)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                  variables.each do |var|
         
     | 
| 
      
 27 
     | 
    
         
            +
                    sorted_variables.merge!({ var.key => var.value })
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
                  sorted_variables
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Seijaku
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Host of SSHGroup
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Host
         
     | 
| 
      
 6 
     | 
    
         
            +
                attr_reader :host, :port, :user, :bastion
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                def initialize(host)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @host = host.fetch("host", "localhost")
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @port = host.fetch("port", 22)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @bastion = host.fetch("bastion", nil)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @user = host.fetch("user", "root")
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/seijaku/step.rb
    ADDED
    
    | 
         @@ -0,0 +1,50 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Seijaku
         
     | 
| 
      
 4 
     | 
    
         
            +
              # A step is a bash or sh command that must be executed.
         
     | 
| 
      
 5 
     | 
    
         
            +
              # steps execution is always fifo.
         
     | 
| 
      
 6 
     | 
    
         
            +
              class Step
         
     | 
| 
      
 7 
     | 
    
         
            +
                attr_reader :command, :pipeline
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                def initialize(step, variables, pipeline, logger, task, ssh_hosts = nil)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @sh = step.fetch("sh", nil)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @bash = step.fetch("bash", nil)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @ssh = step.fetch("ssh", nil)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @soft_fail = step.fetch("soft_fail", false)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @output = step.fetch("output", false)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  @variables = variables
         
     | 
| 
      
 16 
     | 
    
         
            +
                  @pipeline = pipeline
         
     | 
| 
      
 17 
     | 
    
         
            +
                  @logger = logger
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @task = task
         
     | 
| 
      
 19 
     | 
    
         
            +
                  @ssh_hosts = ssh_hosts
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  @command = (@sh || @bash) || @ssh
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def execute!
         
     | 
| 
      
 25 
     | 
    
         
            +
                  result = SHExecutor.new(@sh, @variables).run! if @sh
         
     | 
| 
      
 26 
     | 
    
         
            +
                  result = BashExecutor.new(@bash, @variables).run! if @bash
         
     | 
| 
      
 27 
     | 
    
         
            +
                  result = SSHExecutor.new(@ssh, @variables, @task, @ssh_hosts).run!
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  if result[:exit_status] != 0
         
     | 
| 
      
 30 
     | 
    
         
            +
                    logger_output(result)
         
     | 
| 
      
 31 
     | 
    
         
            +
                    exit(1) unless @soft_fail
         
     | 
| 
      
 32 
     | 
    
         
            +
                  end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  return unless @output
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  %i[stdout stderr].each do |stream|
         
     | 
| 
      
 37 
     | 
    
         
            +
                    puts format("%<stream>s:\t %<result>s", stream: stream, result: result[stream])
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                def logger_output(result)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  @logger.info <<~OUTPUT
         
     | 
| 
      
 43 
     | 
    
         
            +
                    command: `#{result[:command]}`
         
     | 
| 
      
 44 
     | 
    
         
            +
                    exit_code: #{result[:exit_status]}
         
     | 
| 
      
 45 
     | 
    
         
            +
                    stdout: #{result[:stdout]}
         
     | 
| 
      
 46 
     | 
    
         
            +
                    stderr: #{result[:stderr]}"
         
     | 
| 
      
 47 
     | 
    
         
            +
                  OUTPUT
         
     | 
| 
      
 48 
     | 
    
         
            +
                end
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/seijaku/task.rb
    ADDED
    
    | 
         @@ -0,0 +1,32 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Seijaku
         
     | 
| 
      
 4 
     | 
    
         
            +
              # Task is composed of a name, an array of Step (Pre, Post)
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Task
         
     | 
| 
      
 6 
     | 
    
         
            +
                attr_reader :host
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                def initialize(task, variables, logger, ssh_hosts = nil)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @name = task.fetch("name", nil)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @host = task.fetch("host", nil)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @steps = task.fetch("steps", []).map { |step| Step.new(step, variables, :steps, logger, self, ssh_hosts) }
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @pre_steps = task.fetch("pre", []).map { |step| Step.new(step, variables, :pre, logger, self, ssh_hosts) }
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @post_steps = task.fetch("post", []).map { |step| Step.new(step, variables, :post, logger, self, ssh_hosts) }
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @logger = logger
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  raise TaskError, "no name set in task", [] if @name.nil?
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                def execute!
         
     | 
| 
      
 20 
     | 
    
         
            +
                  [@pre_steps, @steps, @post_steps].each do |pipeline_steps|
         
     | 
| 
      
 21 
     | 
    
         
            +
                    pipeline_steps.each do |step|
         
     | 
| 
      
 22 
     | 
    
         
            +
                      @logger.info(format("[%<name>s:%<pipeline>s] running %<command>s",
         
     | 
| 
      
 23 
     | 
    
         
            +
                                          name: @name,
         
     | 
| 
      
 24 
     | 
    
         
            +
                                          pipeline: step.pipeline,
         
     | 
| 
      
 25 
     | 
    
         
            +
                                          command: step.command))
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                      step.execute!
         
     | 
| 
      
 28 
     | 
    
         
            +
                    end
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module Seijaku
         
     | 
| 
      
 4 
     | 
    
         
            +
              # variable
         
     | 
| 
      
 5 
     | 
    
         
            +
              class Variable
         
     | 
| 
      
 6 
     | 
    
         
            +
                attr_reader :key, :value
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                def initialize(variable)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @key = variable.first
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  value = variable.last
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @value = value
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  return unless value.start_with?("$")
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  env_key = value.split("$").last
         
     | 
| 
      
 17 
     | 
    
         
            +
                  env_value = ENV.fetch(env_key, nil)
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  raise VariableError, "no value set for #{env_key}", [] if env_value.nil?
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  @value = env_value
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/seijaku/version.rb
    CHANGED
    
    
    
        data/lib/seijaku.rb
    CHANGED
    
    | 
         @@ -5,12 +5,16 @@ require_relative "seijaku/payload" 
     | 
|
| 
       5 
5 
     | 
    
         
             
            require_relative "seijaku/variable"
         
     | 
| 
       6 
6 
     | 
    
         
             
            require_relative "seijaku/task"
         
     | 
| 
       7 
7 
     | 
    
         
             
            require_relative "seijaku/step"
         
     | 
| 
      
 8 
     | 
    
         
            +
            require_relative "seijaku/ssh/group"
         
     | 
| 
      
 9 
     | 
    
         
            +
            require_relative "seijaku/ssh/host"
         
     | 
| 
       8 
10 
     | 
    
         | 
| 
       9 
11 
     | 
    
         
             
            require_relative "seijaku/executors/sh"
         
     | 
| 
       10 
12 
     | 
    
         
             
            require_relative "seijaku/executors/bash"
         
     | 
| 
      
 13 
     | 
    
         
            +
            require_relative "seijaku/executors/ssh"
         
     | 
| 
       11 
14 
     | 
    
         | 
| 
       12 
15 
     | 
    
         
             
            module Seijaku
         
     | 
| 
       13 
16 
     | 
    
         
             
              class Error < StandardError; end
         
     | 
| 
       14 
17 
     | 
    
         
             
              class VariableError < Error; end
         
     | 
| 
       15 
18 
     | 
    
         
             
              class TaskError < Error; end
         
     | 
| 
      
 19 
     | 
    
         
            +
              class SSHExecutorError < Error; end
         
     | 
| 
       16 
20 
     | 
    
         
             
            end
         
     | 
    
        data/seijaku.gemspec
    CHANGED
    
    | 
         @@ -32,9 +32,7 @@ Gem::Specification.new do |spec| 
     | 
|
| 
       32 
32 
     | 
    
         
             
              spec.executables = %w[seijaku]
         
     | 
| 
       33 
33 
     | 
    
         
             
              spec.require_paths = ["lib"]
         
     | 
| 
       34 
34 
     | 
    
         | 
| 
       35 
     | 
    
         
            -
               
     | 
| 
       36 
     | 
    
         
            -
               
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
              # For more information and examples about making a new gem, check out our
         
     | 
| 
       39 
     | 
    
         
            -
              # guide at: https://bundler.io/guides/creating_gem.html
         
     | 
| 
      
 35 
     | 
    
         
            +
              spec.add_dependency "bcrypt_pbkdf", "~> 1.1"
         
     | 
| 
      
 36 
     | 
    
         
            +
              spec.add_dependency "ed25519", "~> 1.3"
         
     | 
| 
      
 37 
     | 
    
         
            +
              spec.add_dependency "net-ssh", "~> 7.2"
         
     | 
| 
       40 
38 
     | 
    
         
             
            end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,15 +1,57 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: seijaku
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.2.0
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors:
         
     | 
| 
       7 
7 
     | 
    
         
             
            - Kohlrabbit
         
     | 
| 
       8 
8 
     | 
    
         
             
            autorequire:
         
     | 
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
     | 
    
         
            -
            date: 2023-12- 
     | 
| 
       12 
     | 
    
         
            -
            dependencies: 
     | 
| 
      
 11 
     | 
    
         
            +
            date: 2023-12-12 00:00:00.000000000 Z
         
     | 
| 
      
 12 
     | 
    
         
            +
            dependencies:
         
     | 
| 
      
 13 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 14 
     | 
    
         
            +
              name: bcrypt_pbkdf
         
     | 
| 
      
 15 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 16 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 17 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 18 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 19 
     | 
    
         
            +
                    version: '1.1'
         
     | 
| 
      
 20 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 21 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 22 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 23 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 24 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 25 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 26 
     | 
    
         
            +
                    version: '1.1'
         
     | 
| 
      
 27 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 28 
     | 
    
         
            +
              name: ed25519
         
     | 
| 
      
 29 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 30 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 31 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 32 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 33 
     | 
    
         
            +
                    version: '1.3'
         
     | 
| 
      
 34 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 35 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 36 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 37 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 38 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 39 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 40 
     | 
    
         
            +
                    version: '1.3'
         
     | 
| 
      
 41 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency
         
     | 
| 
      
 42 
     | 
    
         
            +
              name: net-ssh
         
     | 
| 
      
 43 
     | 
    
         
            +
              requirement: !ruby/object:Gem::Requirement
         
     | 
| 
      
 44 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 45 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 46 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 47 
     | 
    
         
            +
                    version: '7.2'
         
     | 
| 
      
 48 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 49 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 50 
     | 
    
         
            +
              version_requirements: !ruby/object:Gem::Requirement
         
     | 
| 
      
 51 
     | 
    
         
            +
                requirements:
         
     | 
| 
      
 52 
     | 
    
         
            +
                - - "~>"
         
     | 
| 
      
 53 
     | 
    
         
            +
                  - !ruby/object:Gem::Version
         
     | 
| 
      
 54 
     | 
    
         
            +
                    version: '7.2'
         
     | 
| 
       13 
55 
     | 
    
         
             
            description: CLI tool ingesting YAML files to execute tasks on different shells with
         
     | 
| 
       14 
56 
     | 
    
         
             
              pre and post routines.
         
     | 
| 
       15 
57 
     | 
    
         
             
            email:
         
     | 
| 
         @@ -26,7 +68,19 @@ files: 
     | 
|
| 
       26 
68 
     | 
    
         
             
            - README.md
         
     | 
| 
       27 
69 
     | 
    
         
             
            - Rakefile
         
     | 
| 
       28 
70 
     | 
    
         
             
            - bin/seijaku
         
     | 
| 
      
 71 
     | 
    
         
            +
            - docs/1 - basic.md
         
     | 
| 
      
 72 
     | 
    
         
            +
            - docs/2 - variables.md
         
     | 
| 
      
 73 
     | 
    
         
            +
            - docs/3 - ssh.md
         
     | 
| 
       29 
74 
     | 
    
         
             
            - lib/seijaku.rb
         
     | 
| 
      
 75 
     | 
    
         
            +
            - lib/seijaku/executors/bash.rb
         
     | 
| 
      
 76 
     | 
    
         
            +
            - lib/seijaku/executors/sh.rb
         
     | 
| 
      
 77 
     | 
    
         
            +
            - lib/seijaku/executors/ssh.rb
         
     | 
| 
      
 78 
     | 
    
         
            +
            - lib/seijaku/payload.rb
         
     | 
| 
      
 79 
     | 
    
         
            +
            - lib/seijaku/ssh/group.rb
         
     | 
| 
      
 80 
     | 
    
         
            +
            - lib/seijaku/ssh/host.rb
         
     | 
| 
      
 81 
     | 
    
         
            +
            - lib/seijaku/step.rb
         
     | 
| 
      
 82 
     | 
    
         
            +
            - lib/seijaku/task.rb
         
     | 
| 
      
 83 
     | 
    
         
            +
            - lib/seijaku/variable.rb
         
     | 
| 
       30 
84 
     | 
    
         
             
            - lib/seijaku/version.rb
         
     | 
| 
       31 
85 
     | 
    
         
             
            - seijaku.gemspec
         
     | 
| 
       32 
86 
     | 
    
         
             
            - sig/seijaku.rbs
         
     |