Skip to content

Instantly share code, notes, and snippets.

@paulmooring
Last active February 23, 2021 07:55
Show Gist options
  • Save paulmooring/4946229 to your computer and use it in GitHub Desktop.
Save paulmooring/4946229 to your computer and use it in GitHub Desktop.
curl request script for Chef servers
#!/usr/bin/env bash
# Author:: Paul Mooring (<paul@opscode.com>)
# Author:: Steven Danna (<steve@opscode.com>)
# Copyright:: Copyright (c) 2013 Opscode, Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
## Default values ##
verb=0
chef_server='api.opscode.com'
#####################
help_msg(){
cat << EOF
usage: ${0} [options] <request body>
Options:
-q Quiet
-v Verbose
-h Help
-p Private Chef server (must provide -o <org>)
-o <org> Organization name (Hosted/Private Chef only)
-c <client> Name of requesting client (assumes key is named ${client_name}.pem)
-s <server> Chef server (host name or IP address)
EOF
}
debug(){
if [ -z $2 ] ; then
lvl=0
else
lvl=$2
fi
if [ $verb -gt $lvl ] ; then
echo $1
fi
}
while getopts ":vqho:c:s:" opt; do
case $opt in
h)
help_msg
exit 0
;;
v)
verb=$(expr $verb + 1)
;;
q)
verb=$(expr $verb - 1)
;;
p)
opc="true"
;;
o)
org_name=${OPTARG}
;;
c)
client_name=${OPTARG}
;;
s)
chef_server=${OPTARG}
;;
\?)
echo "Invalid option: -$OPTARG" >&2
help_msg
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
help_msg
exit 1
;;
esac
done
body=$1
chomp(){
# helper function to remove newlines
awk '{printf "%s", $0}'
}
chef_dir(){
# Use the argument if provided
if [ ! -z $1 ] ; then
echo -n $1
return
# otherwise, look for the '.chef' directory
elif [ "$PWD" = "/" ]; then
if [ -d ".chef" ]; then
echo -n "/.chef"
elif [ -d "$HOME/.chef" ]; then
echo -n "$HOME/.chef"
fi
else
if [ -d '.chef' ];then
echo -n "${PWD}/.chef"
else
(cd ..; chef_dir)
fi
fi
}
chef_server_path(){
if (echo $chef_server | grep -q "\.opscode\.com") || [ ! -z $opc ] ; then
echo -n "https://${chef_server}/organizations/${org_name}"
else
echo -n "https://${chef_server}"
fi
}
hash_string(){
echo -n $(echo -n $1 | openssl dgst -sha1 -binary | openssl enc -base64)
}
timestamp(){
echo -n $(date -u "+%Y-%m-%dT%H:%M:%SZ")
}
# takes method, hashed_path, hashed_body and client_name
canonical_request(){
echo -n "Method:${1}\n\
Hashed Path:${2}\n\
X-Ops-Content-Hash:${3}\n\
X-Ops-Timestamp:$(timestamp)\n\
X-Ops-UserId:${4}"
}
# takes hashed_body, client_name
headers(){
echo -n "-H X-Ops-Timestamp:$(timestamp) \
-H X-Ops-Userid:${2} \
-H X-Chef-Version:0.10.4 \
-H Accept:application/json \
-H X-Ops-Content-Hash:${1} \
-H X-Ops-Sign:version=1.0"
}
auth_headers(){
full_uri=$(hash_string $(chef_server_path))
req_body=$(hash_string ${body})
echo -n $(canonical_request "GET" $full_uri $req_body $client_name | \
openssl rsautl -sign -inkey "$(chef_dir)/${client_name}.pem" | \
openssl enc -base64 | \
chomp | \
awk '{ll=int(length/60);i=0; while (i<=ll) {
printf " -H X-Ops-Authorization-%s:%s", i+1, substr($0,i*60+1,60);i=i+1
}}')
}
hdrs=$(headers $(hash_string $body) $client_name)
auth_hdrs=$(auth_headers)
path=$(chef_server_path)
curl_command="curl $hdrs $auth_hdrs $path"
$curl_command
@tolleiv
Copy link

tolleiv commented Jul 8, 2014

Thanks for providing that in a Gist. If anyone runs into "runaway regular expression /60)" errors with this script, please make sure to install the Gnu AWK (gawk) packages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment