Managing Pingdom Check Contact Info
Hello and good morning to you and your family!
I Made This A Long Time Ago
This is an overview of some old code and some other comments about things of that nature.
Throughout this document I refer to this section in apology for not having the better sense to write the code better in the first place.
Junk Becoming and Code Overview
The Python code here is about four years old and isn't what I would call "good", or "secure"; however, it is what I would call, "junk". Honestly, it's probably better for your health to avoid using the code, but I can't stop you... You're too powerful.
If it's junk, why keep it?
Well, yeah! Right?! you're totally right! I should just delete it!
Look, I get it, I'm sure this kind of junk seems verrrry static, in the sense that it may appear to be nothing more than inanimate, slivers of a past frame of mind - an incorrect one at that; so moved-on from that it's rarely thought of, if not forgotten entirely. Revived only in context to how it can be learned from, it's thrashed though cycles of revival, wasteful analysis and re-use. How can junk be anything other than static?
Junk Becoming
I'm sentimental lil' froggy, and I'm imaginative too! I love the idea that the things I hold onto are powerful fibres of embodiment - past, current and future; slivers - cleaned and combed, becoming the yarn through which my cognition is weaved into a body; my body, which is sewn in thread of the same yarn. This is not static junk, it's just as becoming as I am! It's part of me, yet it's distinct from me - becoming in its own right; as the Python junk code and myself are compositional wholes. That is, I am a whole, of which - in part, is comprised of this junk; and this junk, is also a whole, which - in part, is comprised of me.
Are the junk and myself compositional to something else? in turn compositionally whole? Absolutely! or, probably, at least. ¯\_(ツ)_/¯
Okay, buddy...
Maybe it's cheezy2u but ^that's^ really how I feeL!!
Also, ummmmm I initially made this gist public and updated the README because I would repeatedly come across this code, as it was stored in a secret gist, named README.md. This was more than enough to entice me to open it, every. single. time. and either feel nostalgic about
how much fun I had writing this small automation, or anxious at how many
problems there were with it.
Eventually, I decided to update the gist so that I'll always know what it is, just by looking at the name.
Eventuallyier, I decided to update the gist so that this README appeared above the code and I figured while I'm at it, why not share a little about myself?
So what does the code does?
Well, this here code was built to automate the rotation of a Pingdom alert's contact. The code is a Python 2 script, which executes the following:
- Reads a configuration file for a list of Pingdom alert & contact information
- Retrieving the first contact in the list
- Updates the Pingdom alert with the retrieved contact information
- Moves the retrieved contact to the end of the list
Why does it do what it does?
The script was created to be run periodically, with the goal of implementing the concept of an on-call roster.
Alternatively, the script can be used in an ad-hoc fashion to simply replace a Pingdom alert's contact with another contact.
Configuration
Let's talk about how this thing is configured, or was it how to configure this thing? I can't remember :0
config.yaml
auth:
account-email: ’someone@email.com'
app-key: ‘1234567890'
credentials: '01234567890123456789012345678901234567890123456789012345'
check_id: '1234567'
contacts:
- id: '123456'
name: 'Ikey Battistonm'
- id: '123457'
name: 'Mikey Battiston'
- id: '123458'
name: 'Bikey Mattiston'
This Script Modifies Your Configuration File
Whether you use a different configuration path or use the default location for your configuration file, this script will modify the file.
After the script updates the contact information for a Pingdom Check,
it remove the contact from the sequence of mappings in the configuration file and re-add it to the end of the sequence.
Using your own config
You may pass in your own configuration file with the -c
option but you don't need to, as by default, the script will try to read ./config.yaml for it's configuration.
Configuration Attributes
This describes the configuration itself and what it represents for
an example of the configuration, see config.yaml.
The script expects that the configuration is specified in a Yaml file.
The Yaml file must consist of the following top-level mappings:
-
auth: Represents the authentication information used by the script to connect to Pingdom.
auth maps a set of three mappings, which are:
- account-email: Your Pingdom account's email address
- app-key: One of your Pingdom account's app-keys
- credentials: The secret key to the app-key you used in auth.app-key
check_id: Represents which represents the ID of the Pingdom Check you want to manage the contact information of.
-
contacts: Represents the contact information to be used, by the script, to modify the contact information of the Pingdom Check specified by check_id.
contacts maps to a sequence of mappings, each mapping in the sequence maps to:
- id: A string which represents a contact's ID.
- name: A string which represents the name of a contact. The contact who's name is specified should have an ID which matches the ID which is specified in the same mapping as the contact's name. Confusing, I'm sorry :)
Code
This is what the main junk pile looks like
update_pingdom_contact.py
__author__ = 'Mikey B'
__version__ = '0.0.1'
__purpose__ = 'Automating the rotation of contacts for pingdom alerts'
print (__purpose__)
import json
import yaml
import urllib
import urllib2
import argparse
parser = argparse.ArgumentParser(description='')
parser.add_argument('-o', '--config_file', nargs='?', const='config.yaml', default='config.yaml', required=False)
args = parser.parse_args()
config_file = args.config_file
def get_config():
print "Attempting to open %s for reading" % config_file
with open("%s" % (config_file), 'r') as config_file_stream:
config = yaml.load(config_file_stream)
return config
def modify_contact_in_pingdom_check(options):
url = options['url']
app_key = options['app-key']
check_id = options['check_id']
contact_id = options['contact_id']
credentials = options['credentials']
account_email = options['account-email']
try:
print "Making request to modify contact in check: %s" % options['check_id']
opener = urllib2.build_opener(urllib2.HTTPSHandler)
data = {
'contactids' : "%s" % contact_id
}
data = urllib.urlencode(data)
headers = {
'App-Key' : app_key,
'Account-Email' : account_email,
'Authorization' : 'Basic %s' % credentials
}
request = urllib2.Request(url, data=data, headers=headers)
request.get_method = lambda: 'PUT'
response = opener.open(request)
return {
"body" : response.read(),
"code" : response.getcode()
}
except urllib2.HTTPError, e:
return {
"body" : e.read(),
"code" : e.getcode()
}
def cycle_contacts():
print "Attempting to open %s for writing" % config_file
with open("%s" % (config_file), 'r') as config_file_stream:
config = yaml.load(config_file_stream)
contact_to_rotate = config['contacts'].pop(0)
config['contacts'].append(contact_to_rotate)
with open("%s" % (config_file), 'w') as config_file_stream:
yaml.dump(config, config_file_stream, default_flow_style=False)
contact = config['contacts'][0]
return contact
if __name__ == "__main__":
print "Getting config from %s" % config_file
try:
config = get_config()
print "Done."
print ""
except Exception as e:
print "Error: Unable to retrieve config from %s" % config_file
print e.message, e.args
exit(1)
print "Getting next contact..."
try:
contact = config['contacts'][0]
print "Done. Next contact is %s, id: %s" % (contact['name'],contact['id'])
print ""
except Exception as e:
print "Error: Unable to retrieve contact"
print e.message, e.args
exit(1)
print "Getting check id..."
try:
check_id = config['check_id']
print "Done. Updating check: %s" % check_id
print ""
except Exception as e:
print "Error: Unable to retrieve check_id"
print e.message, e.args
exit(1)
options = {
'url' : "https://api.pingdom.com/api/2.0/checks/%s" % check_id,
'check_id' : check_id,
'contact_id' : contact['id'],
'credentials' : config['auth']['credentials'],
'app-key' : config['auth']['app-key'],
'account-email' : config['auth']['account-email']
}
response = modify_contact_in_pingdom_check(options)
if response['code'] is not 200:
print "Error: %s" % response;
exit(1)
else:
print "Success: %s" % response;
print ""
print "Rotating contacts..."
try:
next_contact = cycle_contacts()
print "Done. Next contact will be %s, id: %s" % (next_contact['name'],next_contact['id'])
except Exception as e:
print "Error: Unable to rotate contacts in %s" % config_file
print e.message, e.args
exit(1)
exit(0)
Usage
If you want to use the script, here's how to do it and what to expect...
Put The Top Down 4 Some Ventilation
Touchscreen Navigate to config.yaml and download that
config!Touchscreen Navigate to
update_pingdom_contact.py and
download that script!
Do it now!
Chuck In Your Own Config Values
Please, if any part of you still loves me, do as I say...
Open your new config.yaml file in your least fav editor
Overwrite the values for each of the three mappings in the auth mapping
Overwrite the value of the check_id mapping
Overwrite the values for each of the two mappings within each of the three sequence elements in the contacts mapping
Okay, one last favour :0 please save your work ;) Thank me later (;
But Don't Use Python 3
This script probably won't work with Python 3 (please believe and understand,
I Made This A Long Time Ago)
Executing The Script
Simply run python update_contact_in_pingdom_check.py
in your terminal.
Or, if you're passing in a config file, try:
python update_contact_in_pingdom_check.py -c /path/to/config.yaml
in your terminal.
When The Script Fails
If the update fails, in any way, it will not rotate any contacts it hasn't already rotated. How confusing and annoying!
Output
While you'll probably observe some differences, like:
- Contact IDs
- Contact Names
- Check ID
You should see something like following text in the output of the Python script
Automating the rotation of a contacts for pingdom alerts
Getting config from config.yaml
Attempting to open config.yaml for reading
Done.
Getting next contact...
Done. Next contact is Mike Mudstone , id: 420666
Getting check id...
Done. Updating check: 6966669
Making request to modify contact in check: 6966669
Success: {'body': '{"message":"Modification of check was successful!"}',
'code': 200}
Rotating contacts...
Attempting to open config.yaml for writing
Done. Next contact will be Steven Robinson ASE, editor of First Contact;
Not to be confused with this script, which is merely the editor of...
The first contact... of your config.yaml ;)
Oh yeah, id: 123457
Please Like and Subscribe
Thank you for your time and the grace of your loving energy
A Word From My Sponsors
May your neighbours respect you,
Trouble neglect you,
Angels protect you,
And heaven accept you.
- Drake
GoodBye
Love From
Mikey B
Top comments (0)