Skip to content

Instantly share code, notes, and snippets.

@kmf
Forked from paulmooring/api-curl.sh
Created February 23, 2021 07:55
Show Gist options
  • Save kmf/024c14c7e783fe2ac63d5c4295abaf16 to your computer and use it in GitHub Desktop.
Save kmf/024c14c7e783fe2ac63d5c4295abaf16 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment