ccli 0.1.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 +7 -0
 - data/.rubocop.yml +121 -0
 - data/.travis.yml +9 -0
 - data/Gemfile +13 -0
 - data/Gemfile.lock +75 -0
 - data/README.md +63 -0
 - data/bin/cry +6 -0
 - data/ccli.gemspec +24 -0
 - data/lib/adapters/cluster_secret_adapter.rb +70 -0
 - data/lib/adapters/cryptopus_adapter.rb +100 -0
 - data/lib/adapters/k8s_adapter.rb +20 -0
 - data/lib/adapters/ose_adapter.rb +20 -0
 - data/lib/adapters/session_adapter.rb +74 -0
 - data/lib/cli.rb +342 -0
 - data/lib/errors.rb +40 -0
 - data/lib/models/account.rb +44 -0
 - data/lib/models/folder.rb +25 -0
 - data/lib/models/k8s_secret.rb +11 -0
 - data/lib/models/ose_secret.rb +28 -0
 - data/lib/models/team.rb +45 -0
 - data/lib/presenters/team_presenter.rb +18 -0
 - data/lib/serializers/account_serializer.rb +57 -0
 - data/lib/serializers/folder_serializer.rb +12 -0
 - data/lib/serializers/ose_secret_serializer.rb +16 -0
 - data/lib/serializers/team_serializer.rb +18 -0
 - metadata +129 -0
 
    
        checksums.yaml
    ADDED
    
    | 
         @@ -0,0 +1,7 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            SHA256:
         
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: b51dfcdf9a76d67d7bb633b23527d834e1eefeed029b4d8cce842ce1d114126c
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: e4aaff7ebd82de60040209ee625b7e4b479d84ffff1f2eeed3f9d919ea48ac83
         
     | 
| 
      
 5 
     | 
    
         
            +
            SHA512:
         
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: c325b131a7eacbee13c0c6caa99288876958ee5a1424a7a14cbff80d13fdc3d8f7886f4f46d57b483fa6ee47c2e019497e72a75d223360698079c59d6db8e138
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: ec80bdf42056d9101b64a7eb99ec991b7aef7a7007a9481ab714253455e260c777af1d42b26765c250c3e9343f84a716b86c860c4c6f677fa9682a5a0e198eb3
         
     | 
    
        data/.rubocop.yml
    ADDED
    
    | 
         @@ -0,0 +1,121 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            AllCops:
         
     | 
| 
      
 2 
     | 
    
         
            +
              DisplayCopNames: true
         
     | 
| 
      
 3 
     | 
    
         
            +
              Exclude:
         
     | 
| 
      
 4 
     | 
    
         
            +
                - spec/**/*
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            Metrics/AbcSize:
         
     | 
| 
      
 7 
     | 
    
         
            +
              Max: 20
         
     | 
| 
      
 8 
     | 
    
         
            +
              Severity: error
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            Metrics/ClassLength:
         
     | 
| 
      
 11 
     | 
    
         
            +
              Max: 200
         
     | 
| 
      
 12 
     | 
    
         
            +
              Severity: error
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            Metrics/ModuleLength:
         
     | 
| 
      
 15 
     | 
    
         
            +
              Max: 200
         
     | 
| 
      
 16 
     | 
    
         
            +
              Severity: error
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            Metrics/CyclomaticComplexity:
         
     | 
| 
      
 19 
     | 
    
         
            +
              Max: 6
         
     | 
| 
      
 20 
     | 
    
         
            +
              Severity: error
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            Layout/LineLength:
         
     | 
| 
      
 23 
     | 
    
         
            +
              Max: 100
         
     | 
| 
      
 24 
     | 
    
         
            +
              Severity: warning
         
     | 
| 
      
 25 
     | 
    
         
            +
              AutoCorrect: true
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            Metrics/MethodLength:
         
     | 
| 
      
 28 
     | 
    
         
            +
              Max: 10
         
     | 
| 
      
 29 
     | 
    
         
            +
              Severity: error
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            Metrics/ParameterLists:
         
     | 
| 
      
 32 
     | 
    
         
            +
              Max: 6
         
     | 
| 
      
 33 
     | 
    
         
            +
              Severity: warning
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            Layout/ClassStructure:
         
     | 
| 
      
 36 
     | 
    
         
            +
              Enabled: true
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            # controller#entry methods have @model_name instance variables.
         
     | 
| 
      
 39 
     | 
    
         
            +
            # therefore disable this cop
         
     | 
| 
      
 40 
     | 
    
         
            +
            Naming/MemoizedInstanceVariableName:
         
     | 
| 
      
 41 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            # Keep for now, easier with superclass definitions
         
     | 
| 
      
 44 
     | 
    
         
            +
            Style/ClassAndModuleChildren:
         
     | 
| 
      
 45 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            # The ones we use must exist for the entire class hierarchy.
         
     | 
| 
      
 48 
     | 
    
         
            +
            Style/ClassVars:
         
     | 
| 
      
 49 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            Style/EmptyMethod:
         
     | 
| 
      
 52 
     | 
    
         
            +
              EnforcedStyle: expanded
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            # We thinks that's fine
         
     | 
| 
      
 55 
     | 
    
         
            +
            Style/FormatStringToken:
         
     | 
| 
      
 56 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            Style/HashSyntax:
         
     | 
| 
      
 60 
     | 
    
         
            +
              Exclude:
         
     | 
| 
      
 61 
     | 
    
         
            +
                - lib/tasks/**/*.rake
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            Style/SymbolArray:
         
     | 
| 
      
 64 
     | 
    
         
            +
              EnforcedStyle: brackets
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
            # map instead of collect, reduce instead of inject.
         
     | 
| 
      
 67 
     | 
    
         
            +
            # Probably later
         
     | 
| 
      
 68 
     | 
    
         
            +
            Style/CollectionMethods:
         
     | 
| 
      
 69 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
            # Well, well, well
         
     | 
| 
      
 72 
     | 
    
         
            +
            Style/Documentation:
         
     | 
| 
      
 73 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
            # Probably later
         
     | 
| 
      
 76 
     | 
    
         
            +
            Layout/DotPosition:
         
     | 
| 
      
 77 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
            # Missing UTF-8 encoding statements should always be created.
         
     | 
| 
      
 80 
     | 
    
         
            +
            Style/Encoding:
         
     | 
| 
      
 81 
     | 
    
         
            +
              Severity: error
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
            # Keep single line bodys for if and unless
         
     | 
| 
      
 84 
     | 
    
         
            +
            Style/IfUnlessModifier:
         
     | 
| 
      
 85 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
            # That's no huge stopper
         
     | 
| 
      
 88 
     | 
    
         
            +
            Layout/EmptyLines:
         
     | 
| 
      
 89 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
            # We thinks that's fine for specs
         
     | 
| 
      
 92 
     | 
    
         
            +
            Layout/EmptyLinesAroundBlockBody:
         
     | 
| 
      
 93 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            # We thinks that's fine
         
     | 
| 
      
 96 
     | 
    
         
            +
            Layout/EmptyLinesAroundClassBody:
         
     | 
| 
      
 97 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
            # We thinks that's fine
         
     | 
| 
      
 100 
     | 
    
         
            +
            Layout/EmptyLinesAroundModuleBody:
         
     | 
| 
      
 101 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
      
 103 
     | 
    
         
            +
            # We thinks that's fine
         
     | 
| 
      
 104 
     | 
    
         
            +
            Layout/MultilineOperationIndentation:
         
     | 
| 
      
 105 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
            # We thinks that's fine
         
     | 
| 
      
 108 
     | 
    
         
            +
            Style/RegexpLiteral:
         
     | 
| 
      
 109 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
            # We think that's the developers choice
         
     | 
| 
      
 112 
     | 
    
         
            +
            Style/SymbolProc:
         
     | 
| 
      
 113 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
            # Probably later
         
     | 
| 
      
 116 
     | 
    
         
            +
            Style/GuardClause:
         
     | 
| 
      
 117 
     | 
    
         
            +
              Enabled: false
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
            # We thinks that's fine
         
     | 
| 
      
 120 
     | 
    
         
            +
            Style/SingleLineBlockParams:
         
     | 
| 
      
 121 
     | 
    
         
            +
              Enabled: false
         
     | 
    
        data/.travis.yml
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/Gemfile.lock
    ADDED
    
    | 
         @@ -0,0 +1,75 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            GEM
         
     | 
| 
      
 2 
     | 
    
         
            +
              remote: https://rubygems.org/
         
     | 
| 
      
 3 
     | 
    
         
            +
              specs:
         
     | 
| 
      
 4 
     | 
    
         
            +
                ast (2.4.1)
         
     | 
| 
      
 5 
     | 
    
         
            +
                byebug (11.1.3)
         
     | 
| 
      
 6 
     | 
    
         
            +
                coderay (1.1.3)
         
     | 
| 
      
 7 
     | 
    
         
            +
                commander (4.5.2)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  highline (~> 2.0.0)
         
     | 
| 
      
 9 
     | 
    
         
            +
                diff-lcs (1.4.4)
         
     | 
| 
      
 10 
     | 
    
         
            +
                equatable (0.6.1)
         
     | 
| 
      
 11 
     | 
    
         
            +
                highline (2.0.3)
         
     | 
| 
      
 12 
     | 
    
         
            +
                method_source (1.0.0)
         
     | 
| 
      
 13 
     | 
    
         
            +
                parallel (1.19.2)
         
     | 
| 
      
 14 
     | 
    
         
            +
                parser (2.7.1.4)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  ast (~> 2.4.1)
         
     | 
| 
      
 16 
     | 
    
         
            +
                pastel (0.7.4)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  equatable (~> 0.6)
         
     | 
| 
      
 18 
     | 
    
         
            +
                  tty-color (~> 0.5)
         
     | 
| 
      
 19 
     | 
    
         
            +
                pry (0.13.1)
         
     | 
| 
      
 20 
     | 
    
         
            +
                  coderay (~> 1.1)
         
     | 
| 
      
 21 
     | 
    
         
            +
                  method_source (~> 1.0)
         
     | 
| 
      
 22 
     | 
    
         
            +
                pry-byebug (3.9.0)
         
     | 
| 
      
 23 
     | 
    
         
            +
                  byebug (~> 11.0)
         
     | 
| 
      
 24 
     | 
    
         
            +
                  pry (~> 0.13.0)
         
     | 
| 
      
 25 
     | 
    
         
            +
                rainbow (3.0.0)
         
     | 
| 
      
 26 
     | 
    
         
            +
                regexp_parser (1.7.1)
         
     | 
| 
      
 27 
     | 
    
         
            +
                rexml (3.2.4)
         
     | 
| 
      
 28 
     | 
    
         
            +
                rspec (3.9.0)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  rspec-core (~> 3.9.0)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  rspec-expectations (~> 3.9.0)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  rspec-mocks (~> 3.9.0)
         
     | 
| 
      
 32 
     | 
    
         
            +
                rspec-core (3.9.2)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  rspec-support (~> 3.9.3)
         
     | 
| 
      
 34 
     | 
    
         
            +
                rspec-expectations (3.9.2)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  diff-lcs (>= 1.2.0, < 2.0)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  rspec-support (~> 3.9.0)
         
     | 
| 
      
 37 
     | 
    
         
            +
                rspec-mocks (3.9.1)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  diff-lcs (>= 1.2.0, < 2.0)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  rspec-support (~> 3.9.0)
         
     | 
| 
      
 40 
     | 
    
         
            +
                rspec-support (3.9.3)
         
     | 
| 
      
 41 
     | 
    
         
            +
                rubocop (0.89.0)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  parallel (~> 1.10)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  parser (>= 2.7.1.1)
         
     | 
| 
      
 44 
     | 
    
         
            +
                  rainbow (>= 2.2.2, < 4.0)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  regexp_parser (>= 1.7)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  rexml
         
     | 
| 
      
 47 
     | 
    
         
            +
                  rubocop-ast (>= 0.1.0, < 1.0)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  ruby-progressbar (~> 1.7)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  unicode-display_width (>= 1.4.0, < 2.0)
         
     | 
| 
      
 50 
     | 
    
         
            +
                rubocop-ast (0.3.0)
         
     | 
| 
      
 51 
     | 
    
         
            +
                  parser (>= 2.7.1.4)
         
     | 
| 
      
 52 
     | 
    
         
            +
                ruby-progressbar (1.10.1)
         
     | 
| 
      
 53 
     | 
    
         
            +
                tty-color (0.5.2)
         
     | 
| 
      
 54 
     | 
    
         
            +
                tty-command (0.9.0)
         
     | 
| 
      
 55 
     | 
    
         
            +
                  pastel (~> 0.7.0)
         
     | 
| 
      
 56 
     | 
    
         
            +
                tty-exit (0.1.0)
         
     | 
| 
      
 57 
     | 
    
         
            +
                tty-logger (0.3.0)
         
     | 
| 
      
 58 
     | 
    
         
            +
                  pastel (~> 0.7.0)
         
     | 
| 
      
 59 
     | 
    
         
            +
                unicode-display_width (1.7.0)
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
            PLATFORMS
         
     | 
| 
      
 62 
     | 
    
         
            +
              ruby
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
            DEPENDENCIES
         
     | 
| 
      
 65 
     | 
    
         
            +
              commander (~> 4.5, >= 4.5.2)
         
     | 
| 
      
 66 
     | 
    
         
            +
              pry
         
     | 
| 
      
 67 
     | 
    
         
            +
              pry-byebug
         
     | 
| 
      
 68 
     | 
    
         
            +
              rspec (~> 3.9)
         
     | 
| 
      
 69 
     | 
    
         
            +
              rubocop (~> 0.89.0)
         
     | 
| 
      
 70 
     | 
    
         
            +
              tty-command
         
     | 
| 
      
 71 
     | 
    
         
            +
              tty-exit
         
     | 
| 
      
 72 
     | 
    
         
            +
              tty-logger
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
            BUNDLED WITH
         
     | 
| 
      
 75 
     | 
    
         
            +
               2.1.4
         
     | 
    
        data/README.md
    ADDED
    
    | 
         @@ -0,0 +1,63 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # ccli
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Cryptopus Command Line Client
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            ## Installation
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            `sudo gem install ccli`
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            This will install the `cry` command including its dependencies
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            ## Features
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            - Fetch account data from Cryptopus
         
     | 
| 
      
 14 
     | 
    
         
            +
            - List accessable teams in Cryptopus
         
     | 
| 
      
 15 
     | 
    
         
            +
            - Sync Openshift/Kubernetes Secrets to Cryptopus
         
     | 
| 
      
 16 
     | 
    
         
            +
            - Sync Secrets from Cryptopus to Openshift/Kubernetes
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            ## Usage
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            ### Labeling secret to be synced
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            So that a secret even gets considered by the `ccli`, you have to add the `cryptopus-sync=true` label to your secret:
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
            **oc:** `oc label secret <secret-name> cryptopus-sync=true`
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            **kubectl:** `kubectl label secret <secret-name> cryptopus-sync=true`
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
            ### Commands
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            ```
         
     | 
| 
      
 32 
     | 
    
         
            +
              Command:           Summary:
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
              account            Fetches an account by the given id          
         
     | 
| 
      
 35 
     | 
    
         
            +
              folder             Selects the Cryptopus folder by id          
         
     | 
| 
      
 36 
     | 
    
         
            +
              help               Display global or [command] help documentation              
         
     | 
| 
      
 37 
     | 
    
         
            +
              k8s-secret-pull    Pulls secret from Kubectl to Cryptopus              
         
     | 
| 
      
 38 
     | 
    
         
            +
              k8s-secret-push    Pushes secret from Cryptopus to Kubectl             
         
     | 
| 
      
 39 
     | 
    
         
            +
              login              Logs in to the ccli         
         
     | 
| 
      
 40 
     | 
    
         
            +
              logout             Logs out of the ccli                
         
     | 
| 
      
 41 
     | 
    
         
            +
              ose-secret-pull    Pulls secret from Openshift to Cryptopus            
         
     | 
| 
      
 42 
     | 
    
         
            +
              ose-secret-push    Pushes secret from Cryptopus to Openshift           
         
     | 
| 
      
 43 
     | 
    
         
            +
              teams              Lists all available teams           
         
     | 
| 
      
 44 
     | 
    
         
            +
              use                Select the current folder   
         
     | 
| 
      
 45 
     | 
    
         
            +
            ```
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
            Show more specific documentation by calling `cry help <command>`
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            ## Development
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
            ### Prerequisites
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
            You will need the following things properly installed on your computer:
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            - [Git (Version Control System)](http://git-scm.com/)
         
     | 
| 
      
 57 
     | 
    
         
            +
            - [RVM (Ruby Version Manager)](http://rvm.io/)
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
            ### Setup
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
            - `rvm install 2.6.0`
         
     | 
| 
      
 62 
     | 
    
         
            +
            - `gem install bundler`
         
     | 
| 
      
 63 
     | 
    
         
            +
            - `bundle install`
         
     | 
    
        data/bin/cry
    ADDED
    
    
    
        data/ccli.gemspec
    ADDED
    
    | 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            lib = File.expand_path('lib', __dir__)
         
     | 
| 
      
 4 
     | 
    
         
            +
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            Gem::Specification.new do |s|
         
     | 
| 
      
 7 
     | 
    
         
            +
              s.name          = 'ccli'
         
     | 
| 
      
 8 
     | 
    
         
            +
              s.version       = '0.1.0'
         
     | 
| 
      
 9 
     | 
    
         
            +
              s.summary       = 'Command line client for the opensource password manager Cryptopus'
         
     | 
| 
      
 10 
     | 
    
         
            +
              s.authors       = ['Nils Rauch']
         
     | 
| 
      
 11 
     | 
    
         
            +
              s.email         = 'rauch@puzzle.ch'
         
     | 
| 
      
 12 
     | 
    
         
            +
              s.require_paths = ['lib']
         
     | 
| 
      
 13 
     | 
    
         
            +
              s.files         = `git ls-files -z`.split("\x0").reject do |f|
         
     | 
| 
      
 14 
     | 
    
         
            +
                f.match(%r{(^(test|spec|features)/)})
         
     | 
| 
      
 15 
     | 
    
         
            +
              end
         
     | 
| 
      
 16 
     | 
    
         
            +
              s.bindir        = 'bin'
         
     | 
| 
      
 17 
     | 
    
         
            +
              s.executables   = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
         
     | 
| 
      
 18 
     | 
    
         
            +
              s.required_ruby_version = Gem::Requirement.new('>= 2.0')
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              s.add_runtime_dependency 'commander', '~> 4.5', '>= 4.5.2'
         
     | 
| 
      
 21 
     | 
    
         
            +
              s.add_runtime_dependency 'tty-command'
         
     | 
| 
      
 22 
     | 
    
         
            +
              s.add_runtime_dependency 'tty-exit'
         
     | 
| 
      
 23 
     | 
    
         
            +
              s.add_runtime_dependency 'tty-logger'
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,70 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'tty-command'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            class ClusterSecretAdapter
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              CCLI_FLAG_LABEL = 'cryptopus-sync'
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              def fetch_secret(name)
         
     | 
| 
      
 10 
     | 
    
         
            +
                raise client_missing_error unless client_installed?
         
     | 
| 
      
 11 
     | 
    
         
            +
                raise client_not_logged_in_error unless client_logged_in?
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                begin
         
     | 
| 
      
 14 
     | 
    
         
            +
                  out, _err = cmd.run("#{client} get -o yaml secret --field-selector='metadata.name=#{name}' " \
         
     | 
| 
      
 15 
     | 
    
         
            +
                                      "-l #{CCLI_FLAG_LABEL}=true")
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  Psych.load(out)['items'].first.to_yaml
         
     | 
| 
      
 18 
     | 
    
         
            +
                rescue TTY::Command::ExitError
         
     | 
| 
      
 19 
     | 
    
         
            +
                  raise OpenshiftSecretNotFoundError
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              def fetch_all_secrets
         
     | 
| 
      
 24 
     | 
    
         
            +
                raise client_missing_error unless client_installed?
         
     | 
| 
      
 25 
     | 
    
         
            +
                raise client_not_logged_in_error unless client_logged_in?
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                secrets, _err = cmd.run("#{client} get secret -o yaml -l #{CCLI_FLAG_LABEL}=true")
         
     | 
| 
      
 28 
     | 
    
         
            +
                Psych.load(secrets)['items'].map do |secret|
         
     | 
| 
      
 29 
     | 
    
         
            +
                  secret.to_yaml
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              def insert_secret(secret)
         
     | 
| 
      
 34 
     | 
    
         
            +
                raise client_missing_error unless client_installed?
         
     | 
| 
      
 35 
     | 
    
         
            +
                raise client_not_logged_in_error unless client_logged_in?
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                File.open("/tmp/#{secret.name}.yml", 'w') do |file|
         
     | 
| 
      
 38 
     | 
    
         
            +
                  file.write secret.ose_secret
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                cmd.run("#{client} delete -f /tmp/#{secret.name}.yml --ignore-not-found=true")
         
     | 
| 
      
 42 
     | 
    
         
            +
                cmd.run("#{client} create -f /tmp/#{secret.name}.yml")
         
     | 
| 
      
 43 
     | 
    
         
            +
              end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
              private
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              def client_installed?
         
     | 
| 
      
 48 
     | 
    
         
            +
                cmd.run!("which #{client}").success?
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              def client_logged_in?
         
     | 
| 
      
 52 
     | 
    
         
            +
                cmd.run!("#{client} get secret").success?
         
     | 
| 
      
 53 
     | 
    
         
            +
              end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
              def cmd
         
     | 
| 
      
 56 
     | 
    
         
            +
                @cmd ||= TTY::Command.new(printer: :null)
         
     | 
| 
      
 57 
     | 
    
         
            +
              end
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
              def client
         
     | 
| 
      
 60 
     | 
    
         
            +
                raise 'implement in subclass'
         
     | 
| 
      
 61 
     | 
    
         
            +
              end
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
              def client_missing_error
         
     | 
| 
      
 64 
     | 
    
         
            +
                raise 'implement in subclass'
         
     | 
| 
      
 65 
     | 
    
         
            +
              end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
              def client_not_logged_in_error
         
     | 
| 
      
 68 
     | 
    
         
            +
                raise 'implement in subclass'
         
     | 
| 
      
 69 
     | 
    
         
            +
              end
         
     | 
| 
      
 70 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,100 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'singleton'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'net/http'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'json'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require 'base64'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            class CryptopusAdapter
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              def root_url
         
     | 
| 
      
 11 
     | 
    
         
            +
                raise SessionMissingError unless session_adapter.session_data[:url]
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                @root_url ||= "#{session_adapter.session_data[:url]}/api"
         
     | 
| 
      
 14 
     | 
    
         
            +
              end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              def get(path)
         
     | 
| 
      
 17 
     | 
    
         
            +
                uri = URI("#{root_url}/#{path}")
         
     | 
| 
      
 18 
     | 
    
         
            +
                request = new_request(:get, uri)
         
     | 
| 
      
 19 
     | 
    
         
            +
                send_request(request, uri)
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              def post(path, body)
         
     | 
| 
      
 23 
     | 
    
         
            +
                uri = URI("#{root_url}/#{path}")
         
     | 
| 
      
 24 
     | 
    
         
            +
                request = new_request(:post, uri)
         
     | 
| 
      
 25 
     | 
    
         
            +
                request.body = body
         
     | 
| 
      
 26 
     | 
    
         
            +
                send_request(request, uri)
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              def patch(path, body)
         
     | 
| 
      
 30 
     | 
    
         
            +
                uri = URI("#{root_url}/#{path}")
         
     | 
| 
      
 31 
     | 
    
         
            +
                request = new_request(:patch, uri)
         
     | 
| 
      
 32 
     | 
    
         
            +
                request.body = body
         
     | 
| 
      
 33 
     | 
    
         
            +
                send_request(request, uri)
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              def save_secret(secret)
         
     | 
| 
      
 37 
     | 
    
         
            +
                secret_account = secret.to_account
         
     | 
| 
      
 38 
     | 
    
         
            +
                secret_account.folder = session_adapter.selected_folder.id
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                persisted_secret = Account.find_by_name_and_folder_id(secret.name,
         
     | 
| 
      
 41 
     | 
    
         
            +
                                                                      session_adapter.selected_folder.id)
         
     | 
| 
      
 42 
     | 
    
         
            +
                if persisted_secret
         
     | 
| 
      
 43 
     | 
    
         
            +
                  patch("accounts/#{persisted_secret.id}", secret_account.to_json)
         
     | 
| 
      
 44 
     | 
    
         
            +
                else
         
     | 
| 
      
 45 
     | 
    
         
            +
                  post('accounts', secret_account.to_json)
         
     | 
| 
      
 46 
     | 
    
         
            +
                end
         
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
              def find_account_by_name(name)
         
     | 
| 
      
 50 
     | 
    
         
            +
                secret_account = Account.find_by_name_and_folder_id(name, session_adapter.selected_folder.id)
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                raise CryptopusAccountNotFoundError unless secret_account
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                secret_account
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
              def renewed_auth_token
         
     | 
| 
      
 58 
     | 
    
         
            +
                json = get("api_users/#{current_user_id}/token")
         
     | 
| 
      
 59 
     | 
    
         
            +
                JSON.parse(json)['token']
         
     | 
| 
      
 60 
     | 
    
         
            +
              end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
              private
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
              def current_user_id
         
     | 
| 
      
 65 
     | 
    
         
            +
                users = JSON.parse(get('api_users'), symbolize_names: true)
         
     | 
| 
      
 66 
     | 
    
         
            +
                users[:data].find do |user|
         
     | 
| 
      
 67 
     | 
    
         
            +
                  user[:attributes][:username] == session_adapter.session_data[:username]
         
     | 
| 
      
 68 
     | 
    
         
            +
                end[:id]
         
     | 
| 
      
 69 
     | 
    
         
            +
              end
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
              def session_adapter
         
     | 
| 
      
 72 
     | 
    
         
            +
                @session_adapter ||= SessionAdapter.new
         
     | 
| 
      
 73 
     | 
    
         
            +
              end
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
              def header_token
         
     | 
| 
      
 76 
     | 
    
         
            +
                Base64.strict_encode64(session_adapter.session_data[:token] || '')
         
     | 
| 
      
 77 
     | 
    
         
            +
              end
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
              def new_request(verb, uri)
         
     | 
| 
      
 80 
     | 
    
         
            +
                request = Object.const_get("Net::HTTP::#{verb.capitalize}").new(uri)
         
     | 
| 
      
 81 
     | 
    
         
            +
                request['Authorization-User'] = session_adapter.session_data[:username]
         
     | 
| 
      
 82 
     | 
    
         
            +
                request['Authorization-Password'] = header_token
         
     | 
| 
      
 83 
     | 
    
         
            +
                if [:post, :patch].include? verb
         
     | 
| 
      
 84 
     | 
    
         
            +
                  request['Content-Type'] = 'application/json'
         
     | 
| 
      
 85 
     | 
    
         
            +
                  request['Accept'] = 'application/vnd.api+json'
         
     | 
| 
      
 86 
     | 
    
         
            +
                end
         
     | 
| 
      
 87 
     | 
    
         
            +
                request
         
     | 
| 
      
 88 
     | 
    
         
            +
              end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
              def send_request(request, uri)
         
     | 
| 
      
 91 
     | 
    
         
            +
                is_ssl_connection = uri.port == 443
         
     | 
| 
      
 92 
     | 
    
         
            +
                response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: is_ssl_connection) do |http|
         
     | 
| 
      
 93 
     | 
    
         
            +
                  http.request(request)
         
     | 
| 
      
 94 
     | 
    
         
            +
                end
         
     | 
| 
      
 95 
     | 
    
         
            +
                raise UnauthorizedError if response.is_a?(Net::HTTPUnauthorized)
         
     | 
| 
      
 96 
     | 
    
         
            +
                raise ForbiddenError if response.is_a?(Net::HTTPForbidden)
         
     | 
| 
      
 97 
     | 
    
         
            +
             
     | 
| 
      
 98 
     | 
    
         
            +
                response.body
         
     | 
| 
      
 99 
     | 
    
         
            +
              end
         
     | 
| 
      
 100 
     | 
    
         
            +
            end
         
     |