Skip to content

Instantly share code, notes, and snippets.

@rlipscombe
Created December 4, 2015 19:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rlipscombe/bdd51d899c31aeb23e43 to your computer and use it in GitHub Desktop.
Save rlipscombe/bdd51d899c31aeb23e43 to your computer and use it in GitHub Desktop.
Listing chef nodes using Erlang
#!/usr/bin/env escript
%%! -pa deps/chef_authn/ebin deps/mochijson2/ebin
% Deps:
% https://github.com/chef/chef_authn
% https://github.com/electricimp/mochijson2
-record(opts, {
node_name,
client_key,
chef_server_url
}).
show_usage() ->
io:format("chef_list_nodes -node_name NAME -client_key KEYFILE -chef_server_url URL\n").
parse_args(["-node_name", NodeName | Rest], Opts) ->
parse_args(Rest, Opts#opts { node_name = NodeName });
parse_args(["-client_key", ClientKey | Rest], Opts) ->
parse_args(Rest, Opts#opts { client_key = ClientKey });
parse_args(["-chef_server_url", ServerUrl | Rest], Opts) ->
parse_args(Rest, Opts#opts { chef_server_url = ServerUrl });
parse_args([_|_] = Unexpected, _Opts) ->
io:format("Error: Unexpected ~p\n", [Unexpected]),
show_usage(),
erlang:halt(1);
parse_args([], Opts) ->
Opts.
parse_args([]) ->
show_usage(),
erlang:halt(1);
parse_args(Args) ->
parse_args(Args, #opts{}).
main(Args) ->
Opts = parse_args(Args),
{ok, _} = application:ensure_all_started(inets),
{ok, _} = application:ensure_all_started(ssl),
ClientKey = read_private_key(Opts#opts.client_key),
PathSuffix = "/nodes",
Url = Opts#opts.chef_server_url ++ PathSuffix,
{ok, {_Scheme, _UserInfo, _Host, _Port, Path, _Query}} = http_uri:parse(Url),
Method = <<"GET">>,
ExtraHeaders = chef_authn:sign_request(ClientKey, Opts#opts.node_name, Method, now, Path),
Headers = [{"Accept", "application/json"},
{"X-Chef-Version", "12.5.1"} | ExtraHeaders],
{ok, {{_, 200, _}, _, Body}} = httpc:request(get, {Url, Headers}, [], []),
{struct, Nodes} = mochijson2:decode(Body),
lists:foreach(fun({Node, NodeUrl}) ->
io:format("~s\t~s\n", [Node, NodeUrl])
end, Nodes),
ok.
%% @doc read a PEM-formatted key file.
read_private_key(Path) ->
{ok, Bytes} = file:read_file(Path),
[Entry] = public_key:pem_decode(Bytes),
public_key:pem_entry_decode(Entry).
%% vi:ft=erlang
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment