Skip to content

Instantly share code, notes, and snippets.

@irvingpop
Last active July 16, 2016 18:11
Show Gist options
  • Save irvingpop/a8188a111e1d641d4476 to your computer and use it in GitHub Desktop.
Save irvingpop/a8188a111e1d641d4476 to your computer and use it in GitHub Desktop.
Messing around with Chef Server admin functions beyond knife-opc

Connecting to your Chef server as an admin, via the API

# launch pry
/opt/opscode/embedded/bin/pry 
[1] pry(main)> require 'chef/rest'
=> true

# create a Chef::REST object pointed at localhost with the pivotal user and pivotal.pem (required for admin operations)
[2] pry(main)> chef_rest = Chef::REST.new('https://localhost/', 'pivotal', '/etc/opscode/pivotal.pem')
=> #<Chef::REST:0x00000002433b70
 @authenticator=
  #<Chef::HTTP::Authenticator:0x000000024325e0
   @auth_credentials=
    #<Chef::HTTP::AuthCredentials:0x00000002432400 @client_name="pivotal", @key=#<OpenSSL::PKey::RSA:0x00000002432428>>,
   @key=#<OpenSSL::PKey::RSA:0x00000002432428>,
   @raw_key=
    "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAmQ9VlWxEi10FS+k2tTl8zDkCt5l8YboqAiAhe4t6y3k/l9EU\nQOTBs79ej2oKWIyw1IyJkG9osqtejvxcLpMqjEGErJZSxFCgebJnkIHebs2eHmXy\nea7Gi3JtodoL3Pas3qMVLXmA1ePFbrz5psv73lICxMoUByknkCG224+x1gZPh+yV\ngCv/MssOQzqG7qf+28RaPF/qOypaqy7szh1ne3RpxdKP4yD+HU0oIXKriw2WYgWE\nNv7Rruu/EdeG7ZeSnxAE1dl6cVz62Vd1YNIUiu6TftCDyFEO3SYskuJtoky72IsU\noqESW9oJ+WZnsSanq14TNvt4iLL4h+lQe+xR3wIDAQABAoIBAAW+yZueQMRqbXR4\nAJG04rZXvX5eyIhykHkb86XLioRwvK5aLsRw0cSJfmcrt8+zGEAiNlexluB+BkKf\nvmYRKBuzqeNAkULFNADdbX3DIjJOjYzejsd6hAFf/jWBFcjpiXuh632VffyJXDPX\n7BcSuRWTRn9UhoPuS4nheherwSUjcKQhA8gtVFjTHy95KbiPay6L0i8KHMhXAmFI\npIfY8cybFr35FbdCxKU6snmfHQeLAcTBEeGB1bNlEjv5+r5KnLDME96h74aIrugV\nC0yIMIUGnJ3ief7FBj3jJVb5FaM5lLFAzV6z46l2CKJt64hgjYnE4LXseu6eR+Aw\nXU45VIECgYEAyLTejiaaKyfnB2sifCo0bjGH6TT6hVsMQPOIWwZKdURFUdcpxeBe\nGRdbco5PuVSsdL09Rp5F0S6TXhpkRDGTNaBpjtgyXUHWxRMGuEw9TbFChPDAzZKf\nuAkwJz7eusj5VkeKgsS67j+tHxc60Z5Q+NR6yNRZ44equ64qjfu7kJECgYEAwzod\ncIooCy5T/+n087GZ40vZS68eO2kWvbGCKn89wO9+qsL4U8HGPAWYqQ3EmHCm7ThC\nWM0zdwHuEBpk0yYFt80JC4/9DibC1Yn2eXtzXdOEwelRE70UTciT3SWOqn3Ucizx\nukupHvlzDCLXTCgOGFPuRYPO3YbxFXcRBhTv828CgYEAqtEMzQzbjzkxriWnPueo\nodQz6O32/UJlJm5eMaIkArPtD19BJTD0xQQVB2VJQuFmuSBKI20W3JZ4Q9HQXh2X\nPT/eNv2Xt7kOMcIkqPvx/MqNY5mHbi6JEtd3DR+77lqXoq/Wmb8XnSfCjsB1hevo\n3C3ypjPcoQJY88yiWR7THpECgYAVNCSqanb67+czrmdqaGm8ZCqPq89uyHUt2S+4\nCeXdJKXvSgnKnws2zazM/6/QlruqnCeomXDzhgQjP5qfzEtmsSBAXz0u4krbAocA\nnsXi9OxAW2Tw7eJcqGJW7JNYNR5z4CnJABq4QIOcV9RmcxtEzSjd5/j52oQovqvc\nqz18hQKBgF6yfwYTkgfoGc7KMm7t5tg3iG6k+XxokJVkdsU/T+1uPOkuoNdVyahV\n+7Nulib8QRVaUGGnMqMOS4PvFa/7KyxDvoHAWBt+lza6Z+PkQcj3VCOd2gOZoa1Q\nfS21zbvgnVinE4SJxLhqfQVhA46mAB0ss3Uz2sWX9JcY4PXY/Oux\n-----END RSA PRIVATE KEY-----",
   @sign_request=true,
   @signing_key_filename="/etc/opscode/pivotal.pem">,
 @decompressor=#<Chef::HTTP::Decompressor:0x00000002432838 @disable_gzip=false>,
 @default_headers={},
 @middlewares=
  [#<Chef::HTTP::JSONInput:0x00000002432388
    @opts={:client_name=>"pivotal", :signing_key_filename=>"/etc/opscode/pivotal.pem", :inflate_json_class=>true}>,
   #<Chef::HTTP::JSONToModelOutput:0x00000002432360 @inflate_json_class=true, @raw_output=nil>,
   #<Chef::HTTP::CookieManager:0x00000002432338 @cookies={}>,
   #<Chef::HTTP::Decompressor:0x00000002432838 @disable_gzip=false>,
   #<Chef::HTTP::Authenticator:0x000000024325e0
    @auth_credentials=
     #<Chef::HTTP::AuthCredentials:0x00000002432400 @client_name="pivotal", @key=#<OpenSSL::PKey::RSA:0x00000002432428>>,
    @key=#<OpenSSL::PKey::RSA:0x00000002432428>,
    @raw_key=
     "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAmQ9VlWxEi10FS+k2tTl8zDkCt5l8YboqAiAhe4t6y3k/l9EU\nQOTBs79ej2oKWIyw1IyJkG9osqtejvxcLpMqjEGErJZSxFCgebJnkIHebs2eHmXy\nea7Gi3JtodoL3Pas3qMVLXmA1ePFbrz5psv73lICxMoUByknkCG224+x1gZPh+yV\ngCv/MssOQzqG7qf+28RaPF/qOypaqy7szh1ne3RpxdKP4yD+HU0oIXKriw2WYgWE\nNv7Rruu/EdeG7ZeSnxAE1dl6cVz62Vd1YNIUiu6TftCDyFEO3SYskuJtoky72IsU\noqESW9oJ+WZnsSanq14TNvt4iLL4h+lQe+xR3wIDAQABAoIBAAW+yZueQMRqbXR4\nAJG04rZXvX5eyIhykHkb86XLioRwvK5aLsRw0cSJfmcrt8+zGEAiNlexluB+BkKf\nvmYRKBuzqeNAkULFNADdbX3DIjJOjYzejsd6hAFf/jWBFcjpiXuh632VffyJXDPX\n7BcSuRWTRn9UhoPuS4nheherwSUjcKQhA8gtVFjTHy95KbiPay6L0i8KHMhXAmFI\npIfY8cybFr35FbdCxKU6snmfHQeLAcTBEeGB1bNlEjv5+r5KnLDME96h74aIrugV\nC0yIMIUGnJ3ief7FBj3jJVb5FaM5lLFAzV6z46l2CKJt64hgjYnE4LXseu6eR+Aw\nXU45VIECgYEAyLTejiaaKyfnB2sifCo0bjGH6TT6hVsMQPOIWwZKdURFUdcpxeBe\nGRdbco5PuVSsdL09Rp5F0S6TXhpkRDGTNaBpjtgyXUHWxRMGuEw9TbFChPDAzZKf\nuAkwJz7eusj5VkeKgsS67j+tHxc60Z5Q+NR6yNRZ44equ64qjfu7kJECgYEAwzod\ncIooCy5T/+n087GZ40vZS68eO2kWvbGCKn89wO9+qsL4U8HGPAWYqQ3EmHCm7ThC\nWM0zdwHuEBpk0yYFt80JC4/9DibC1Yn2eXtzXdOEwelRE70UTciT3SWOqn3Ucizx\nukupHvlzDCLXTCgOGFPuRYPO3YbxFXcRBhTv828CgYEAqtEMzQzbjzkxriWnPueo\nodQz6O32/UJlJm5eMaIkArPtD19BJTD0xQQVB2VJQuFmuSBKI20W3JZ4Q9HQXh2X\nPT/eNv2Xt7kOMcIkqPvx/MqNY5mHbi6JEtd3DR+77lqXoq/Wmb8XnSfCjsB1hevo\n3C3ypjPcoQJY88yiWR7THpECgYAVNCSqanb67+czrmdqaGm8ZCqPq89uyHUt2S+4\nCeXdJKXvSgnKnws2zazM/6/QlruqnCeomXDzhgQjP5qfzEtmsSBAXz0u4krbAocA\nnsXi9OxAW2Tw7eJcqGJW7JNYNR5z4CnJABq4QIOcV9RmcxtEzSjd5/j52oQovqvc\nqz18hQKBgF6yfwYTkgfoGc7KMm7t5tg3iG6k+XxokJVkdsU/T+1uPOkuoNdVyahV\n+7Nulib8QRVaUGGnMqMOS4PvFa/7KyxDvoHAWBt+lza6Z+PkQcj3VCOd2gOZoa1Q\nfS21zbvgnVinE4SJxLhqfQVhA46mAB0ss3Uz2sWX9JcY4PXY/Oux\n-----END RSA PRIVATE KEY-----",
    @sign_request=true,
    @signing_key_filename="/etc/opscode/pivotal.pem">,
   #<Chef::HTTP::RemoteRequestID:0x000000024323b0>,
   #<Chef::HTTP::ValidateContentLength:0x000000024322e8>],
 @redirect_limit=10,
 @redirects_followed=0,
 @request_id=#<Chef::HTTP::RemoteRequestID:0x000000024323b0>,
 @sign_on_redirect=true,
 @url="https://localhost/">

# set SSL mode to :verify_none to prevent SSL errors
[7] pry(main)> Chef::Config[:ssl_verify_mode] = :verify_none
=> :verify_none

listing things

# NOTE on chef_rest methods:
#  get_rest = GET request for querying objects
#  post_rest = POST request for creating objects
#  put_rest = PUT request for updating objects
#  delete_rest = DELETE request for deleting objects

# list the orgs on the server
[8] pry(main)> chef_rest.get_rest('organizations')
=> {"ponyville"=>"https://localhost/organizations/ponyville", "wonderbolts"=>"https://localhost/organizations/wonderbolts"}

# list all of the users on the server (reminder:  users live "below" orgs and don't have implied access to any orgs, but they can create new orgs)
[13] pry(main)> chef_rest.get_rest('users')
=> {"pivotal"=>"https://localhost/users/pivotal",
 "rainbowdash"=>"https://localhost/users/rainbowdash",
 "fluttershy"=>"https://localhost/users/fluttershy",
 "applejack"=>"https://localhost/users/applejack",
 "pinkiepie"=>"https://localhost/users/pinkiepie",
 "twilightsparkle"=>"https://localhost/users/twilightsparkle",
 "rarity"=>"https://localhost/users/rarity",
 "spitfire"=>"https://localhost/users/spitfire",
 "soarin"=>"https://localhost/users/soarin",
 "rapidfire"=>"https://localhost/users/rapidfire",
 "fleetfoot"=>"https://localhost/users/fleetfoot"}

# list the users associated with one of the orgs
[9] pry(main)> chef_rest.get_rest('organizations/ponyville/users')
=> [{"user"=>{"username"=>"applejack"}},
 {"user"=>{"username"=>"fluttershy"}},
 {"user"=>{"username"=>"pinkiepie"}},
 {"user"=>{"username"=>"rainbowdash"}},
 {"user"=>{"username"=>"rarity"}},
 {"user"=>{"username"=>"twilightsparkle"}}]
 
 # list all of the groups in an org (note the guid named orgs are okay, they are USAGs)
[10] pry(main)> chef_rest.get_rest('organizations/ponyville/groups')
=> {"clients"=>"https://localhost/organizations/ponyville/groups/clients",
 "0000000000005254acc821ad1ae5d098"=>"https://localhost/organizations/ponyville/groups/0000000000005254acc821ad1ae5d098",
 "0000000000007742955ea8ed6b49ef07"=>"https://localhost/organizations/ponyville/groups/0000000000007742955ea8ed6b49ef07",
 "0000000000006088842ba8ecc2b1e8cf"=>"https://localhost/organizations/ponyville/groups/0000000000006088842ba8ecc2b1e8cf",
 "0000000000003895a36badc68dc5cbd1"=>"https://localhost/organizations/ponyville/groups/0000000000003895a36badc68dc5cbd1",
 "0000000000000dccfa66971ac89ca641"=>"https://localhost/organizations/ponyville/groups/0000000000000dccfa66971ac89ca641",
 "000000000000c177f4ad23895390cab6"=>"https://localhost/organizations/ponyville/groups/000000000000c177f4ad23895390cab6",
 "users"=>"https://localhost/organizations/ponyville/groups/users",
 "admins"=>"https://localhost/organizations/ponyville/groups/admins",
 "billing-admins"=>"https://localhost/organizations/ponyville/groups/billing-admins"}
 
# get a list of the users belonging to a group
[11] pry(main)> chef_rest.get_rest('organizations/ponyville/groups/admins')
=> {"actors"=>["pivotal", "rainbowdash", "fluttershy", "applejack", "pinkiepie", "twilightsparkle", "rarity"],
 "users"=>["pivotal", "rainbowdash", "fluttershy", "applejack", "pinkiepie", "twilightsparkle", "rarity"],
 "clients"=>[],
 "groups"=>[],
 "orgname"=>"ponyville",
 "name"=>"admins",
 "groupname"=>"admins"}

build a map of organizations and users associated to them

[62] pry(main)> org_user_map = {}

[63] pry(main)> chef_rest.get_rest('organizations').each_key { |orgname| org_user_map[orgname] = chef_rest.get_rest("organizations/#{orgname}/users").collect { |users| users['user']['username'] }  }

[65] pry(main)> org_user_map
=> {"ponyville"=>["applejack", "fluttershy", "pinkiepie", "rainbowdash", "rarity", "twilightsparkle"],
 "wonderbolts"=>["fleetfoot", "rapidfire", "soarin", "spitfire"]}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment