Website Logo. Upload to /source/logo.png ; disable in /source/_includes/logo.html

Zuzur’s wobleg

technology, Internet, and a bit of this and that (with some dyslexia inside)

Notebook: Importing Existing Users From Chef

| Comments

I recently had (too much) fun trying to import a few existing chef users (opscode’s platform) to another chef server. There is currently no facility to export your existing users (‘clients’ if you are running your own server, ‘users’ on the opscode platform).

What i ended up doing involves a lot of manual typing, but i intend to automate that in the future.

The key is that there is no way you can export you users’ public keys without accessing the underlying CouchDB server, and as i’m pretty sure Opscode uses a multi-tenant CouchDB server, you can’t do that on their platform for obvious security concerns.

So i ended up:

  • creating the same users on my new chef server
  • use irb on the new chef server to overwrite every new users’ public key using some of chef’s internal methods

Some ranting on Opscode’s platform

knife doesn’t even know about users, as the chef server code on that platform makes the distinction between users (who can upload cookbooks, roles, etc …) and API clients (nodes trying to get their run lists and values stored in data bags). The chef backup script provided by jtimberman only exports roles and nodes, and even after massaging it it to dump clients as well, the public_key field is empty - as if the platform’s server removed it on purpose)

i didn’t find any documentation about the differences in the REST API between the hosted platform and the open source chef server. I suppose that the API is here but not exposed in the gem… i’ll look into that later.

With opscode not allowing to export the public_key of the client, meaning there is no way you can easily script that process, you have to go through the very tedious task of copy and paste every user’s public key and change your new users’ document with their respective public key …

Solution

  • quickly hack a chef-client.rb that would allow a client (knife or chef-client to connect using an existing API client that you will not modify during this process - doing so would be a nice way to shoot yourself in the foot :-P
  • display the user on opscode’s platform : https://manage.opscode.com/users/
  • copy the public key
  • on a console, connected to the chef server (we’re going to use Chef::ApiClient.cdb_load and Chef::ApiClient.cdb_save methods, which bypass Chef’s REST API, and need the same access as the chef server …)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
earzur@chef-server [16:30:51]
 /etc/chef $ irb
 irb(main):001:0> require 'rubygems'
 => true
 irb(main):002:0> require 'chef'
 => true
<...>
 irb(main):004:0> Chef::Config.from_file('chef-client.rb')
 => "none"
<...>
irb(main):007:0> u = Chef::ApiClient.cdb_load('earzur')
 => #<Chef::ApiClient:0x7f0f498a5188 @couchdb=#<Chef::CouchDB:0x7f0f498aaef8 @rest=#<Chef::REST:0x7f0f498aaea8 @redirects_followed=0, @auth_credentials=#<Chef::REST::AuthCredentials:0x7f0f498aadb8 @key_file=nil, @client_name=nil>, @cookies={}, @sign_request=true, @default_headers={}, @disable_gzip=false, @url="http://localhost:5984", @sign_on_redirect=true, @redirect_limit=10>, @db="chef">, @admin=true, @couchdb_id="f0f19583-00a9-4b60-887d-95f410821856", @couchdb_rev="3-f3ce3f9e58f6988636168f8bd611db8e", @private_key=nil, @index_id="f0f19583-00a9-4b60-887d-95f410821856", @public_key="-----BEGIN RSA PUBLIC KEY-----\n....DAQAB\n-----END RSA PUBLIC KEY-----", @name="earzur">
 irb(main):008:0> u.public_key("-----BEGIN RSA PUBLIC KEY-----\n...\n-----END RSA PUBLIC KEY-----")
 => "-----BEGIN RSA PUBLIC KEY-----\n...-----END RSA PUBLIC KEY-----\n"

 irb(main):010:0> u.cdb_save
 ~ Qrack::Queue#publish will be removed in Bunny 0.8. Use direct_exchange = bunny.exchange(''); direct_exchange.publish('message', key: queue.name) if you want to publish directly to one given queue. For more informations see https://github.com/ruby-amqp/bunny/issues/15 and for more theoretical explanation check http://bit.ly/nOF1CK
 => "4-ed15fba63937223e6690765809ef0e2c"

done … now repeat that for the other clients and they should be able to access both servers with the same certificates … this doesn’t scale well, but i’m not going to have to distribute another sets of certificates for this chef development server !

Comments