pe_rbac 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/.gitignore +10 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +58 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/example.rb +57 -0
- data/exe/pe_rbac +55 -0
- data/lib/pe_rbac.rb +240 -0
- data/lib/pe_rbac/version.rb +3 -0
- data/pe_rbac.gemspec +27 -0
- metadata +114 -0
    
        checksums.yaml
    ADDED
    
    | @@ -0,0 +1,7 @@ | |
| 1 | 
            +
            ---
         | 
| 2 | 
            +
            SHA1:
         | 
| 3 | 
            +
              metadata.gz: 003e9ccdbe211c50b4025335831bcaab7c77d4cf
         | 
| 4 | 
            +
              data.tar.gz: 40d72b46ffd84a8b9976d81eba7bf93f23e92e65
         | 
| 5 | 
            +
            SHA512:
         | 
| 6 | 
            +
              metadata.gz: 5c05146edfa1e4d4eb2392f774699c834388d836d546b34d1aebef2e638f2375b6e3799e317013de34d9dd511b372c95b5730bc12061ba225bee42c26712ed1c
         | 
| 7 | 
            +
              data.tar.gz: fec01c7aae9f104627bc7bd02ba77fa87544a2d53b6d44306adb96010d1060046d40071d96cdf3a7fe927e0d6c431daa3ed07e621b469fac48a7e5fbf0bf162f
         | 
    
        data/.gitignore
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/LICENSE.txt
    ADDED
    
    | @@ -0,0 +1,21 @@ | |
| 1 | 
            +
            The MIT License (MIT)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Copyright (c) 2016 Geoff Williams
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Permission is hereby granted, free of charge, to any person obtaining a copy
         | 
| 6 | 
            +
            of this software and associated documentation files (the "Software"), to deal
         | 
| 7 | 
            +
            in the Software without restriction, including without limitation the rights
         | 
| 8 | 
            +
            to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
         | 
| 9 | 
            +
            copies of the Software, and to permit persons to whom the Software is
         | 
| 10 | 
            +
            furnished to do so, subject to the following conditions:
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            The above copyright notice and this permission notice shall be included in
         | 
| 13 | 
            +
            all copies or substantial portions of the Software.
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
         | 
| 16 | 
            +
            IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
         | 
| 17 | 
            +
            FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
         | 
| 18 | 
            +
            AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
         | 
| 19 | 
            +
            LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
         | 
| 20 | 
            +
            OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
         | 
| 21 | 
            +
            THE SOFTWARE.
         | 
    
        data/README.md
    ADDED
    
    | @@ -0,0 +1,58 @@ | |
| 1 | 
            +
            # PeRbac
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/pe_rbac`. To experiment with that code, run `bin/console` for an interactive prompt.
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            TODO: Delete this and the text above, and describe your gem
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            ## Installation
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            Add this line to your application's Gemfile:
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            ```ruby
         | 
| 12 | 
            +
            gem 'pe_rbac'
         | 
| 13 | 
            +
            ```
         | 
| 14 | 
            +
             | 
| 15 | 
            +
            And then execute:
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                $ bundle
         | 
| 18 | 
            +
             | 
| 19 | 
            +
            Or install it yourself as:
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                $ gem install pe_rbac
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            ## Usage
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            ### Setting up code manager on the command line
         | 
| 26 | 
            +
            ```
         | 
| 27 | 
            +
            pe_rbac  code_manager --password t0ps3cret
         | 
| 28 | 
            +
            ```
         | 
| 29 | 
            +
            Right now, the command line just provides a means to setup code manager.  If you
         | 
| 30 | 
            +
            want to do more then this, you must use the Ruby API
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            ### Ruby API
         | 
| 33 | 
            +
            An *IN FLUX* Ruby API exists, see code for more info.  This WILL change (well it 
         | 
| 34 | 
            +
            will if I do any more development work on this...) - expect module names, 
         | 
| 35 | 
            +
            functions, etc. to change.  In particular, I'm planning:
         | 
| 36 | 
            +
            * Sub-modules/file reorgs
         | 
| 37 | 
            +
            * tests!
         | 
| 38 | 
            +
             | 
| 39 | 
            +
            ## Development
         | 
| 40 | 
            +
             | 
| 41 | 
            +
            ### Debugging
         | 
| 42 | 
            +
            ```
         | 
| 43 | 
            +
            RESTCLIENT_LOG=stdout bundle exec pe_rbac
         | 
| 44 | 
            +
            ```
         | 
| 45 | 
            +
             | 
| 46 | 
            +
            After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
         | 
| 49 | 
            +
             | 
| 50 | 
            +
            ## Contributing
         | 
| 51 | 
            +
             | 
| 52 | 
            +
            Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/pe_rbac.
         | 
| 53 | 
            +
             | 
| 54 | 
            +
             | 
| 55 | 
            +
            ## License
         | 
| 56 | 
            +
             | 
| 57 | 
            +
            The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
         | 
| 58 | 
            +
             | 
    
        data/Rakefile
    ADDED
    
    
    
        data/bin/console
    ADDED
    
    | @@ -0,0 +1,14 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require "bundler/setup"
         | 
| 4 | 
            +
            require "pe_rbac"
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            # You can add fixtures and/or initialization code here to make experimenting
         | 
| 7 | 
            +
            # with your gem easier. You can also use a different console, if you like.
         | 
| 8 | 
            +
             | 
| 9 | 
            +
            # (If you use this, don't forget to add pry to your Gemfile!)
         | 
| 10 | 
            +
            # require "pry"
         | 
| 11 | 
            +
            # Pry.start
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            require "irb"
         | 
| 14 | 
            +
            IRB.start
         | 
    
        data/bin/setup
    ADDED
    
    
    
        data/example.rb
    ADDED
    
    | @@ -0,0 +1,57 @@ | |
| 1 | 
            +
            require 'pe_rbac'
         | 
| 2 | 
            +
            begin
         | 
| 3 | 
            +
              # get all users
         | 
| 4 | 
            +
              resp = PeRbac::get_users
         | 
| 5 | 
            +
              puts resp
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              # get user by ID
         | 
| 8 | 
            +
              resp = PeRbac::get_user('4765c077-3675-4a2d-85c0-0c76b82d15cb')
         | 
| 9 | 
            +
              puts resp
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              # Lookup the ID for a user
         | 
| 12 | 
            +
              resp = PeRbac::get_user_id('admin')
         | 
| 13 | 
            +
              puts "FOUND: " + resp
         | 
| 14 | 
            +
             | 
| 15 | 
            +
              # get all roles
         | 
| 16 | 
            +
              resp = PeRbac::get_roles
         | 
| 17 | 
            +
              puts resp
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              # get role by ID
         | 
| 20 | 
            +
              resp = PeRbac::get_role(1)
         | 
| 21 | 
            +
              puts resp
         | 
| 22 | 
            +
             | 
| 23 | 
            +
              # create user (works - commented out to preven conflict error)
         | 
| 24 | 
            +
              #resp = PeRbac::create_user('test','test@test.com', 'mr test test')
         | 
| 25 | 
            +
              #puts resp
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              # update user
         | 
| 28 | 
            +
              resp = PeRbac::update_user('test','test@test.com.au', 'mrs test test')
         | 
| 29 | 
            +
              puts resp.code
         | 
| 30 | 
            +
             | 
| 31 | 
            +
              # change password
         | 
| 32 | 
            +
              resp = PeRbac::change_password('test','12345678')
         | 
| 33 | 
            +
              puts resp.code
         | 
| 34 | 
            +
             | 
| 35 | 
            +
              # get an API token
         | 
| 36 | 
            +
              resp = PeRbac::token('test', '12345678')
         | 
| 37 | 
            +
              puts resp
         | 
| 38 | 
            +
              
         | 
| 39 | 
            +
              # create or update a user with role access and write a token
         | 
| 40 | 
            +
              role_ids = PeRbac::get_role_ids('Code Deployers')
         | 
| 41 | 
            +
              perms = {
         | 
| 42 | 
            +
                "objectType" => "tokens",
         | 
| 43 | 
            +
                "action"     => "override_lifetime",
         | 
| 44 | 
            +
                "instance"   => nil,
         | 
| 45 | 
            +
              }
         | 
| 46 | 
            +
              PeRbac::update_role('Code Deployers', permissions=perms)
         | 
| 47 | 
            +
              PeRbac::ensure_user('psquared', 'root@localhost', 'psquared', 'changeme', role_ids)
         | 
| 48 | 
            +
              PeRbac::login('psquared', 'changeme', '10y')
         | 
| 49 | 
            +
             | 
| 50 | 
            +
              # what permissions are there?
         | 
| 51 | 
            +
              resp = PeRbac::get_permissions
         | 
| 52 | 
            +
              puts resp.body
         | 
| 53 | 
            +
             | 
| 54 | 
            +
            rescue Exception => e
         | 
| 55 | 
            +
              puts e.message
         | 
| 56 | 
            +
              puts e.backtrace
         | 
| 57 | 
            +
            end
         | 
    
        data/exe/pe_rbac
    ADDED
    
    | @@ -0,0 +1,55 @@ | |
| 1 | 
            +
            #!/usr/bin/env ruby
         | 
| 2 | 
            +
            require 'pe_rbac'
         | 
| 3 | 
            +
            require 'escort'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            Escort::App.create do |app|
         | 
| 6 | 
            +
              app.version "0.0.1"
         | 
| 7 | 
            +
              app.summary "pe_rbac"
         | 
| 8 | 
            +
              app.description "create RBAC users and install tokens"
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              app.command :code_manager do |command|
         | 
| 11 | 
            +
                command.summary "Setup a code manager"
         | 
| 12 | 
            +
                command.description "Create a deploy user for use with code manager and install token"
         | 
| 13 | 
            +
                command.action do |options, arguments|
         | 
| 14 | 
            +
                  role      = 'Code Deployers'
         | 
| 15 | 
            +
                  cmd       = :code_manager # FIXME obtain this automatically
         | 
| 16 | 
            +
                  lifetime  = options[:global][:commands][cmd][:options][:lifetime]
         | 
| 17 | 
            +
                  username  = options[:global][:commands][cmd][:options][:username]
         | 
| 18 | 
            +
                  password  = options[:global][:commands][cmd][:options][:password]
         | 
| 19 | 
            +
                  email     = options[:global][:commands][cmd][:options][:email]
         | 
| 20 | 
            +
                  role_ids = PeRbac::get_role_ids(role)
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                  perms = {
         | 
| 23 | 
            +
                    "objectType" => "tokens",
         | 
| 24 | 
            +
                    "action"     => "override_lifetime",
         | 
| 25 | 
            +
                    "instance"   => nil,
         | 
| 26 | 
            +
                  }
         | 
| 27 | 
            +
                  PeRbac::update_role(role, permissions=perms)
         | 
| 28 | 
            +
                  PeRbac::ensure_user(username, email, username, password, role_ids)
         | 
| 29 | 
            +
                  PeRbac::login(username, password, lifetime)     
         | 
| 30 | 
            +
                end
         | 
| 31 | 
            +
                command.options do |opts|
         | 
| 32 | 
            +
                  opts.opt(:username,
         | 
| 33 | 
            +
                    'Username for deploy user',
         | 
| 34 | 
            +
                    :long    => '--username',
         | 
| 35 | 
            +
                    :default => 'deploy'
         | 
| 36 | 
            +
                  )
         | 
| 37 | 
            +
                  opts.opt(:password,
         | 
| 38 | 
            +
                    'Initial password for deploy user',
         | 
| 39 | 
            +
                    :long    => '--password',
         | 
| 40 | 
            +
                    :default => 'changeme'
         | 
| 41 | 
            +
                  )
         | 
| 42 | 
            +
                  opts.opt(:email,
         | 
| 43 | 
            +
                    'Email address',
         | 
| 44 | 
            +
                    :long    => '--email',
         | 
| 45 | 
            +
                    :default => 'root@localhost'
         | 
| 46 | 
            +
                  )
         | 
| 47 | 
            +
                  opts.opt(:lifetime,
         | 
| 48 | 
            +
                    'Token validity length',
         | 
| 49 | 
            +
                    :long    => '--lifetime',
         | 
| 50 | 
            +
                    :default => '10y'
         | 
| 51 | 
            +
                  )
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
             | 
| 55 | 
            +
            end
         | 
    
        data/lib/pe_rbac.rb
    ADDED
    
    | @@ -0,0 +1,240 @@ | |
| 1 | 
            +
            require "pe_rbac/version"
         | 
| 2 | 
            +
            require 'restclient'
         | 
| 3 | 
            +
            require 'socket'
         | 
| 4 | 
            +
            require 'json'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module PeRbac
         | 
| 7 | 
            +
              ssldir = '/etc/puppetlabs/puppet/ssl'
         | 
| 8 | 
            +
              CONF = {
         | 
| 9 | 
            +
                host: Socket.gethostname,
         | 
| 10 | 
            +
                port: 4433,
         | 
| 11 | 
            +
                cert: ssldir + '/certs/pe-internal-orchestrator.pem',
         | 
| 12 | 
            +
                key: ssldir + '/private_keys/pe-internal-orchestrator.pem',
         | 
| 13 | 
            +
                cacert: ssldir + '/certs/ca.pem'
         | 
| 14 | 
            +
              }
         | 
| 15 | 
            +
             | 
| 16 | 
            +
              BASE_URI = '/rbac-api/v1'
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              #
         | 
| 19 | 
            +
              # user
         | 
| 20 | 
            +
              # 
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              def self.get_users
         | 
| 23 | 
            +
                JSON.parse(_request(:get, '/users').body)
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              # get the user id for a login or false if missing
         | 
| 27 | 
            +
              # eg 'admin' => '42bf351c-f9ec-40af-84ad-e976fec7f4bd'
         | 
| 28 | 
            +
              def self.get_user_id(login)
         | 
| 29 | 
            +
                users = get_users
         | 
| 30 | 
            +
                id = false
         | 
| 31 | 
            +
                i = 0
         | 
| 32 | 
            +
                while !id and i < users.length do
         | 
| 33 | 
            +
                  if users[i]['login'] == login
         | 
| 34 | 
            +
                    id = users[i]['id']
         | 
| 35 | 
            +
                  end
         | 
| 36 | 
            +
                  i += 1
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
                id
         | 
| 39 | 
            +
              end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
              def self.get_user(id)
         | 
| 42 | 
            +
                JSON.parse(_request(:get, "/users/#{id}").body)
         | 
| 43 | 
            +
              end
         | 
| 44 | 
            +
             | 
| 45 | 
            +
              def self.ensure_user(login, email, display_name, password=nil, role_ids=[])
         | 
| 46 | 
            +
                if get_user_id(login)
         | 
| 47 | 
            +
                  # existing user
         | 
| 48 | 
            +
                  update_user(login, email, display_name, role_ids)
         | 
| 49 | 
            +
                  if password
         | 
| 50 | 
            +
                    change_password(login, password)
         | 
| 51 | 
            +
                  end
         | 
| 52 | 
            +
                else
         | 
| 53 | 
            +
                  # new user
         | 
| 54 | 
            +
                  create_user(login, email, display_name, password, role_ids)
         | 
| 55 | 
            +
                end
         | 
| 56 | 
            +
             | 
| 57 | 
            +
              end
         | 
| 58 | 
            +
             | 
| 59 | 
            +
              def self.create_user(login, email, display_name, password=nil, role_ids=[])
         | 
| 60 | 
            +
                # completely different to what the PE console sends... :/
         | 
| 61 | 
            +
                user={
         | 
| 62 | 
            +
                  "login"         => login,
         | 
| 63 | 
            +
                  "email"         => email,
         | 
| 64 | 
            +
                  "display_name"  => display_name,
         | 
| 65 | 
            +
                  "role_ids"      => role_ids,
         | 
| 66 | 
            +
                }
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                if password
         | 
| 69 | 
            +
                  user["password"] = password
         | 
| 70 | 
            +
                end
         | 
| 71 | 
            +
             | 
| 72 | 
            +
                _request(:post, '/users', user)
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
              def self.update_user(login, email=nil, display_name=nil, role_ids=nil, is_revoked=nil)
         | 
| 76 | 
            +
                user = get_user(get_user_id(login))
         | 
| 77 | 
            +
                if ! user['remote']
         | 
| 78 | 
            +
                  # trade-off for auto id lookup is that you cant change logins...
         | 
| 79 | 
            +
                  user['login'] = login ? login : user['login']
         | 
| 80 | 
            +
                  user['email'] = email ? email : user['email']
         | 
| 81 | 
            +
                  user['display_name'] = display_name ? display_name : user['display_name']
         | 
| 82 | 
            +
                end
         | 
| 83 | 
            +
                user['role_ids'] = role_ids ? role_ids : user['role_ids']  
         | 
| 84 | 
            +
                user['is_revoked'] = (! is_revoked.nil?) ? is_revoked : user['is_revoked'] 
         | 
| 85 | 
            +
             | 
| 86 | 
            +
                _request(:put, "/users/#{user['id']}", user)
         | 
| 87 | 
            +
              end
         | 
| 88 | 
            +
             | 
| 89 | 
            +
              def self.change_password(login, new_password)
         | 
| 90 | 
            +
                token = _request(:post, "/users/#{get_user_id(login)}/password/reset").body
         | 
| 91 | 
            +
             | 
| 92 | 
            +
                reset = {
         | 
| 93 | 
            +
                  "token"     => token,
         | 
| 94 | 
            +
                  "password"  => new_password,
         | 
| 95 | 
            +
                }
         | 
| 96 | 
            +
             | 
| 97 | 
            +
                _request(:post, '/auth/reset', reset)
         | 
| 98 | 
            +
              end
         | 
| 99 | 
            +
              
         | 
| 100 | 
            +
              #
         | 
| 101 | 
            +
              # role
         | 
| 102 | 
            +
              #
         | 
| 103 | 
            +
              def self.get_roles
         | 
| 104 | 
            +
                JSON.parse(_request(:get, "/roles").body)
         | 
| 105 | 
            +
              end
         | 
| 106 | 
            +
             | 
| 107 | 
            +
              def self.get_role(id)
         | 
| 108 | 
            +
                JSON.parse(_request(:get, "/roles/#{id}").body)
         | 
| 109 | 
            +
              end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
              def self.get_role_id(display_name)
         | 
| 112 | 
            +
                i=0
         | 
| 113 | 
            +
                found=false
         | 
| 114 | 
            +
                roles = get_roles()
         | 
| 115 | 
            +
                while !found and i < roles.length do
         | 
| 116 | 
            +
                  if roles[i]['display_name'] == display_name
         | 
| 117 | 
            +
                    found = roles[i]['id']
         | 
| 118 | 
            +
                  end
         | 
| 119 | 
            +
                  i+=1
         | 
| 120 | 
            +
                end
         | 
| 121 | 
            +
                found
         | 
| 122 | 
            +
              end
         | 
| 123 | 
            +
             | 
| 124 | 
            +
              
         | 
| 125 | 
            +
              # get the role id for a display name
         | 
| 126 | 
            +
              # eg ['Code Deployers', 'blah'] => [4,8]
         | 
| 127 | 
            +
              def self.get_role_ids(display_names)
         | 
| 128 | 
            +
                if ! display_names.is_a? Array
         | 
| 129 | 
            +
                  display_names = [display_names]
         | 
| 130 | 
            +
                end
         | 
| 131 | 
            +
                roles = get_roles
         | 
| 132 | 
            +
                ids = []
         | 
| 133 | 
            +
                display_names.each { |display_name|
         | 
| 134 | 
            +
                  found=get_role_id(display_name)
         | 
| 135 | 
            +
                  if !found
         | 
| 136 | 
            +
                    raise("RBAC role '#{display_name}' not found")
         | 
| 137 | 
            +
                  end
         | 
| 138 | 
            +
                  ids.push(found)
         | 
| 139 | 
            +
                }
         | 
| 140 | 
            +
                ids
         | 
| 141 | 
            +
              end
         | 
| 142 | 
            +
             | 
| 143 | 
            +
              # CREATE
         | 
| 144 | 
            +
              def self.ensure_role(display_name, description, permissions=[], users=[])
         | 
| 145 | 
            +
                if get_role_id(display_name)
         | 
| 146 | 
            +
                  update_role(display_name, description, permissions, users)
         | 
| 147 | 
            +
                else
         | 
| 148 | 
            +
                  create_role(display_name, description, permissions, users)
         | 
| 149 | 
            +
                end
         | 
| 150 | 
            +
              end
         | 
| 151 | 
            +
              
         | 
| 152 | 
            +
              def self.create_role(display_name, description, permissions=[], users=[])
         | 
| 153 | 
            +
                role = {
         | 
| 154 | 
            +
                  "display_name"  => display_name,
         | 
| 155 | 
            +
                  "description"   => description,
         | 
| 156 | 
            +
                  "permissions"   => permissions,
         | 
| 157 | 
            +
                  "user_ids"      => users,
         | 
| 158 | 
            +
                  "group_ids"     => [], # doesn't seem to be used yet
         | 
| 159 | 
            +
                }
         | 
| 160 | 
            +
                _request(:post, '/roles', role)
         | 
| 161 | 
            +
              end
         | 
| 162 | 
            +
             | 
| 163 | 
            +
              def self.update_role(display_name, description=nil, permissions=nil, user_ids=nil, group_ids=nil)
         | 
| 164 | 
            +
                role_id = get_role_id(display_name)
         | 
| 165 | 
            +
                if role_id 
         | 
| 166 | 
            +
                  role = get_role(role_id)
         | 
| 167 | 
            +
                  role['display_name'] = display_name ? display_name : role['display_name']
         | 
| 168 | 
            +
                  role['description'] = description ? display_name : role['description']
         | 
| 169 | 
            +
                  role['permissions'] = permissions ? display_name : role['permissions']
         | 
| 170 | 
            +
                  role['user_ids'] = user_ids ? display_name : role['user_ids']
         | 
| 171 | 
            +
                  role['group_ids'] = group_ids ? display_name : role['group_ids']
         | 
| 172 | 
            +
             | 
| 173 | 
            +
                  _request(:put, "/roles/#{role_id}", role)
         | 
| 174 | 
            +
                else
         | 
| 175 | 
            +
                  raise("No such role exists: #{display_name} create it first or use ensure_role")
         | 
| 176 | 
            +
                end
         | 
| 177 | 
            +
              end
         | 
| 178 | 
            +
              
         | 
| 179 | 
            +
             | 
| 180 | 
            +
              #
         | 
| 181 | 
            +
              # Permissions
         | 
| 182 | 
            +
              #
         | 
| 183 | 
            +
              def self.get_permissions()
         | 
| 184 | 
            +
                _request(:get, "/types")
         | 
| 185 | 
            +
              end
         | 
| 186 | 
            +
             | 
| 187 | 
            +
             | 
| 188 | 
            +
              #
         | 
| 189 | 
            +
              # Token
         | 
| 190 | 
            +
              #
         | 
| 191 | 
            +
              def self.token(login, password, lifetime=false)
         | 
| 192 | 
            +
                payload = {
         | 
| 193 | 
            +
                  "login"     => login,
         | 
| 194 | 
            +
                  "password"  => password,
         | 
| 195 | 
            +
                }
         | 
| 196 | 
            +
                
         | 
| 197 | 
            +
                # see https://docs.puppet.com/pe/latest/rbac_token_auth.html#setting-a-token-specific-lifetime
         | 
| 198 | 
            +
                if lifetime
         | 
| 199 | 
            +
                  payload["lifetime"] = lifetime
         | 
| 200 | 
            +
                end
         | 
| 201 | 
            +
             | 
| 202 | 
            +
                JSON.parse(_request(:post, '/auth/token', payload))['token']
         | 
| 203 | 
            +
              end
         | 
| 204 | 
            +
             | 
| 205 | 
            +
              def self.login(login, password, lifetime=false)
         | 
| 206 | 
            +
                dirname = Dir.home + '/.puppetlabs'
         | 
| 207 | 
            +
                tokenfile = dirname + '/token'
         | 
| 208 | 
            +
                if ! Dir.exist?(dirname)
         | 
| 209 | 
            +
                  Dir.mkdir(dirname, 0700)
         | 
| 210 | 
            +
                end
         | 
| 211 | 
            +
                File.write(tokenfile, token(login, password, lifetime))
         | 
| 212 | 
            +
                File.chmod(0600, tokenfile)
         | 
| 213 | 
            +
              end
         | 
| 214 | 
            +
             | 
| 215 | 
            +
              private
         | 
| 216 | 
            +
             | 
| 217 | 
            +
              def self._request(method, path, payload=nil, raw=false)
         | 
| 218 | 
            +
                url = "https://#{CONF[:host]}:#{CONF[:port]}#{BASE_URI}#{path}"
         | 
| 219 | 
            +
                if payload
         | 
| 220 | 
            +
                  if raw
         | 
| 221 | 
            +
                    _payload=payload
         | 
| 222 | 
            +
                  else
         | 
| 223 | 
            +
                    _payload=payload.to_json
         | 
| 224 | 
            +
                  end
         | 
| 225 | 
            +
                else
         | 
| 226 | 
            +
                  _payload=nil
         | 
| 227 | 
            +
                end
         | 
| 228 | 
            +
                RestClient::Request.execute(
         | 
| 229 | 
            +
                  method: method, 
         | 
| 230 | 
            +
                  url: url,
         | 
| 231 | 
            +
                  ssl_ca_file: CONF[:cacert],
         | 
| 232 | 
            +
                  ssl_client_cert: OpenSSL::X509::Certificate.new(File.read(CONF[:cert])),
         | 
| 233 | 
            +
                  ssl_client_key: OpenSSL::PKey::RSA.new(File.read(CONF[:key])),
         | 
| 234 | 
            +
                  ssl_version: :TLSv1,
         | 
| 235 | 
            +
                  headers: {:content_type => :json, :accept => :json},
         | 
| 236 | 
            +
                  payload: _payload,
         | 
| 237 | 
            +
                )
         | 
| 238 | 
            +
              end
         | 
| 239 | 
            +
             | 
| 240 | 
            +
            end
         | 
    
        data/pe_rbac.gemspec
    ADDED
    
    | @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            # coding: utf-8
         | 
| 2 | 
            +
            lib = File.expand_path('../lib', __FILE__)
         | 
| 3 | 
            +
            $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
         | 
| 4 | 
            +
            require 'pe_rbac/version'
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            Gem::Specification.new do |spec|
         | 
| 7 | 
            +
              spec.name          = "pe_rbac"
         | 
| 8 | 
            +
              spec.version       = PeRbac::VERSION
         | 
| 9 | 
            +
              spec.authors       = ["Geoff Williams"]
         | 
| 10 | 
            +
              spec.email         = ["geoff@geoffwilliams.me.uk"]
         | 
| 11 | 
            +
             | 
| 12 | 
            +
              spec.summary       = %q{Ruby API for Puppet Enterprise RBAC}
         | 
| 13 | 
            +
              spec.description   = %q{Programatically do stuff with Puppet Enterprise RBAC}
         | 
| 14 | 
            +
              spec.homepage      = "https://github.com/geoffwilliams/pe_rbac"
         | 
| 15 | 
            +
              spec.license       = "MIT"
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              spec.files         = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
         | 
| 18 | 
            +
              spec.bindir        = "exe"
         | 
| 19 | 
            +
              spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
         | 
| 20 | 
            +
              spec.require_paths = ["lib"]
         | 
| 21 | 
            +
             | 
| 22 | 
            +
              spec.add_development_dependency "bundler", "~> 1.12"
         | 
| 23 | 
            +
              spec.add_development_dependency "rake", "~> 10.0"
         | 
| 24 | 
            +
             | 
| 25 | 
            +
              spec.add_runtime_dependency "rest-client", "2.0.0"
         | 
| 26 | 
            +
              spec.add_runtime_dependency "escort", "0.4.0"
         | 
| 27 | 
            +
            end
         | 
    
        metadata
    ADDED
    
    | @@ -0,0 +1,114 @@ | |
| 1 | 
            +
            --- !ruby/object:Gem::Specification
         | 
| 2 | 
            +
            name: pe_rbac
         | 
| 3 | 
            +
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            +
              version: 0.1.0
         | 
| 5 | 
            +
            platform: ruby
         | 
| 6 | 
            +
            authors:
         | 
| 7 | 
            +
            - Geoff Williams
         | 
| 8 | 
            +
            autorequire: 
         | 
| 9 | 
            +
            bindir: exe
         | 
| 10 | 
            +
            cert_chain: []
         | 
| 11 | 
            +
            date: 2016-09-21 00:00:00.000000000 Z
         | 
| 12 | 
            +
            dependencies:
         | 
| 13 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 14 | 
            +
              name: bundler
         | 
| 15 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 | 
            +
                requirements:
         | 
| 17 | 
            +
                - - "~>"
         | 
| 18 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 19 | 
            +
                    version: '1.12'
         | 
| 20 | 
            +
              type: :development
         | 
| 21 | 
            +
              prerelease: false
         | 
| 22 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 | 
            +
                requirements:
         | 
| 24 | 
            +
                - - "~>"
         | 
| 25 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 26 | 
            +
                    version: '1.12'
         | 
| 27 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 28 | 
            +
              name: rake
         | 
| 29 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 30 | 
            +
                requirements:
         | 
| 31 | 
            +
                - - "~>"
         | 
| 32 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 33 | 
            +
                    version: '10.0'
         | 
| 34 | 
            +
              type: :development
         | 
| 35 | 
            +
              prerelease: false
         | 
| 36 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 37 | 
            +
                requirements:
         | 
| 38 | 
            +
                - - "~>"
         | 
| 39 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 40 | 
            +
                    version: '10.0'
         | 
| 41 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 42 | 
            +
              name: rest-client
         | 
| 43 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 44 | 
            +
                requirements:
         | 
| 45 | 
            +
                - - '='
         | 
| 46 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 47 | 
            +
                    version: 2.0.0
         | 
| 48 | 
            +
              type: :runtime
         | 
| 49 | 
            +
              prerelease: false
         | 
| 50 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 51 | 
            +
                requirements:
         | 
| 52 | 
            +
                - - '='
         | 
| 53 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 54 | 
            +
                    version: 2.0.0
         | 
| 55 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 56 | 
            +
              name: escort
         | 
| 57 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 58 | 
            +
                requirements:
         | 
| 59 | 
            +
                - - '='
         | 
| 60 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 61 | 
            +
                    version: 0.4.0
         | 
| 62 | 
            +
              type: :runtime
         | 
| 63 | 
            +
              prerelease: false
         | 
| 64 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 65 | 
            +
                requirements:
         | 
| 66 | 
            +
                - - '='
         | 
| 67 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 68 | 
            +
                    version: 0.4.0
         | 
| 69 | 
            +
            description: Programatically do stuff with Puppet Enterprise RBAC
         | 
| 70 | 
            +
            email:
         | 
| 71 | 
            +
            - geoff@geoffwilliams.me.uk
         | 
| 72 | 
            +
            executables:
         | 
| 73 | 
            +
            - pe_rbac
         | 
| 74 | 
            +
            extensions: []
         | 
| 75 | 
            +
            extra_rdoc_files: []
         | 
| 76 | 
            +
            files:
         | 
| 77 | 
            +
            - ".gitignore"
         | 
| 78 | 
            +
            - Gemfile
         | 
| 79 | 
            +
            - LICENSE.txt
         | 
| 80 | 
            +
            - README.md
         | 
| 81 | 
            +
            - Rakefile
         | 
| 82 | 
            +
            - bin/console
         | 
| 83 | 
            +
            - bin/setup
         | 
| 84 | 
            +
            - example.rb
         | 
| 85 | 
            +
            - exe/pe_rbac
         | 
| 86 | 
            +
            - lib/pe_rbac.rb
         | 
| 87 | 
            +
            - lib/pe_rbac/version.rb
         | 
| 88 | 
            +
            - pe_rbac.gemspec
         | 
| 89 | 
            +
            homepage: https://github.com/geoffwilliams/pe_rbac
         | 
| 90 | 
            +
            licenses:
         | 
| 91 | 
            +
            - MIT
         | 
| 92 | 
            +
            metadata: {}
         | 
| 93 | 
            +
            post_install_message: 
         | 
| 94 | 
            +
            rdoc_options: []
         | 
| 95 | 
            +
            require_paths:
         | 
| 96 | 
            +
            - lib
         | 
| 97 | 
            +
            required_ruby_version: !ruby/object:Gem::Requirement
         | 
| 98 | 
            +
              requirements:
         | 
| 99 | 
            +
              - - ">="
         | 
| 100 | 
            +
                - !ruby/object:Gem::Version
         | 
| 101 | 
            +
                  version: '0'
         | 
| 102 | 
            +
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 103 | 
            +
              requirements:
         | 
| 104 | 
            +
              - - ">="
         | 
| 105 | 
            +
                - !ruby/object:Gem::Version
         | 
| 106 | 
            +
                  version: '0'
         | 
| 107 | 
            +
            requirements: []
         | 
| 108 | 
            +
            rubyforge_project: 
         | 
| 109 | 
            +
            rubygems_version: 2.4.6
         | 
| 110 | 
            +
            signing_key: 
         | 
| 111 | 
            +
            specification_version: 4
         | 
| 112 | 
            +
            summary: Ruby API for Puppet Enterprise RBAC
         | 
| 113 | 
            +
            test_files: []
         | 
| 114 | 
            +
            has_rdoc: 
         |