Git Product home page Git Product logo

puppet-pingdom's Introduction

puppet-pingdom

Puppet type and provider for the Pingdom API.

Status

Currently supports the Pingdom 2.1 API.

This module has no external dependencies, and should be widely-compatible and simple to install.

Please consider helping by submitting bug reports. Pull requests also welcome.


Types

pingdom_check pingdom_user pingdom_team [1] pingdom_settings

[1] Multi-user accounts only.

Check providers

dns http httpcustom imap ping pop3 smtp tcp udp


Example usage

Defaults:
Pingdom_team {
    account_email => Sensitive($pingdom_account_email),
    user_email    => Sensitive($pingdom_user_email),
    password      => Sensitive($pingdom_password),
    appkey        => $pingdom_appkey
}

Pingdom_user {
    account_email => Sensitive($pingdom_account_email),
    user_email    => Sensitive($pingdom_user_email),
    password      => Sensitive($pingdom_password),
    appkey        => $pingdom_appkey
}

Pingdom_check {
    account_email => Sensitive($pingdom_account_email),
    user_email    => Sensitive($pingdom_user_email),
    password      => Sensitive($pingdom_password),
    appkey        => $pingdom_appkey,
    probe_filters => ['NA']
}
Contacts:
pingdom_user { 'Steve Smith':
    ensure          => present,
    contact_targets => [
        { email  => '[email protected]' },
        { number => '555-123-1212', countrycode => '1' }
    ]
}

pingdom_user { 'DevOps Pager':
    ensure          => present,
    contact_targets => [
        { number => '555-123-1213', countrycode => '1' }
    ]
}
Teams:
pingdom_team { 'DevOps':
    ensure => present,
    users  => [
        'Steve Smith',
        'DevOps Pager'
    ]
}
HTTP check:
pingdom_check { "http://${facts['fqdn']}/check":
    ensure         => present,
    provider       => 'http',
    host           => $facts['fqdn'],
    url            => '/check',
    auth           => Sensitive("admin:p@ssw0rd"),
    resolution     => 5,
    requestheaders => {
        'Accept' => 'x-application/json'
    },
    postdata => Sensitive({
        'api_key'  => 'abcdef1234567890abcdef1234567890',
        'api_user' => 'automation'
    }),
    teams          => ['DevOps'],
    tags           => ['http']
}
DNS check:
pingdom_check { "dns://${facts['fqdn']}":
    ensure     => present,
    provider   => 'dns',
    host       => $facts['fqdn'],
    expectedip => '1.2.3.4',
    nameserver => '8.8.8.8',
    users      => ['DevOps Pager'],
    tags       => ['dns']
}
Ping check:
pingdom_check { "ping://${facts['fqdn']}":
    ensure   => present,
    provider => 'ping',
    host     => $facts['fqdn'],
    tags     => ['ping']
}
Settings:
pingdom_settings { 'Pingdom Settings':
    firstname   => 'Brad',
    lastname    => 'Brown',
    company     => 'Company, Inc.',
    email       => '[email protected]',
    cellphone   => '555-123-3333',
    description => 'This account is managed by Puppet.'
}
Hiera:
pingdom::account_email: [email protected]
pingdom::user_email: [email protected]
pingdom::password: ENC[PKCS7,EYAMLENCODEDPASSWORD]
pingdom::appkey: ABCDEF1234567890FEDCBA

pingdom::settings:
  'Pingdom Settings':
    firstname: Brad
    lastname: Brown
    company: Company, Inc.
    email: [email protected]
    cellphone: 555-123-3333
    description: This account is managed by Puppet.

pingdom::users:
  'Steve Smith':
    contact_targets:
    - email: [email protected]
    - number: 555-123-1234
      countrycode: 1

  'DevOps Pager':
    contact_targets:
    - number: 555-123-3214
      countrycode: 1

pingdom::teams:
  'DevOps':
    users:
    - Steve Smith
    - DevOps Pager

pingdom::checks:
  "http://%{facts.fqdn}/status":
    provider: http
    host: "%{facts.fqdn}"
    url: /status
    teams:
    - DevOps
    tags:
    - http

  "ping://%{facts.fqdn}":
    provider: ping
    host: "%{facts.fqdn}"
    users:
    - DevOps Pager
    tags:
    - ping

After configuring Hiera, simply include pingdom in your manifest:

class myclass {
    include pingdom
}

Installation

See instructions on PuppetForge.


Attention

This module utilizes a feature named autofilter [default: true]. Be aware that this feature will automatically tag your checks with a shortened SHA1 hash of the check's name property, and automatically set filter_tags to include this tag. This allows us to efficiently locate this check in the future. However, if you have existing checks, enabling autofilter will cause them to no longer be found (since they lack the requisite SHA1 tag in filter_tags).

To get around this, and have your existing checks tagged, set autofilter => 'bootstrap' and run Puppet on all your nodes. This will enable tagging, but not set filter_tags. If you have a lot of existing checks, this may be a slow Puppet run. Once the run has completed, set autofilter => true or simply remove the parameter altogether.


Known issues

  • puppet resource pingdom_check command will likely never work, since self.instances is a class method and doesn't have access to instantiation-time parameters such as credentials.
  • Users API is incomplete (can only manage contacts, not admins).
  • There's a difference in login requirements for Starter and Standard plans (specifically, these two levels lack multi-user login). I'm currently only able to test against Enterprise. If you have a Starter or Standard plan and have issues authenticating to Pingdom, reach out to me and we can get it working.
  • The Integrations API isn't documented, so we can't manage integrations yet.

puppet-pingdom's People

Contributors

cwells avatar

Watchers

 avatar  avatar

Forkers

downsj2

puppet-pingdom's Issues

contact_targets specified in Hiera constantly update

pingdom::users:
  'SRE PagerDuty':
    contact_targets:
      - email: [email protected]
      - number: 555-123-1212
        countrycode: 1
Notice: /Stage[main]/Pingdom/Pingdom_user[SRE PagerDuty]/contact_targets: contact_targets changed

[{'email' => '[email protected]', 'id' => '2786428', 'severity' => 'HIGH'}, 
{'countrycode' => '1', 'id' => '2786431', 'number' => '555-123-1212', 'severity' => 'HIGH'}] 

to 

'{"email"=>"[email protected]", :severitylevel=>"HIGH"} 
{"number"=>"555-123-1212", "countrycode"=>1, :severitylevel=>"HIGH"}'

Not sure why, as the insync? method deals with the differences seen above.

Doesn't appear to happen with puppet apply. Figures.

Do something about init.pp

It's barely enough to get hiera support. Make it smarter. Needs at least the ability to merge hashes and take parameters.

Add autofilter feature

Consider the following hypothetical construct:

Pingdom_check {
    autofilter => true
}

pingdom_check { "http://${facts['fqdn']}/check":
   type => 'http',
   url  => "http://${facts['fqdn']}/check",
   tags => ['http']
}

This would automatically inject a semi-unique tag (most likely "puppet-#{Digest::SHA1.hexdigest(fqdn)[0..5]}") and a corresponding filter_tags value to increase performance. The above has the same effect as the following, except applied to all pingdom_check resources in the manifest:

$filter_tag = 'puppet-' + sha1('encode', $facts['fqdn'])[0,5]

pingdom_check { "http://${facts['fqdn']}/check":
   type        => 'http',
   url         => "http://${facts['fqdn']}/check",
   tags        => [$filter_tag, 'http'],
   filter_tags => [$filter_tag]
}

Having this as the default would ensure that people get good performance without any effort. The only potential issue is API-enforced tag-length restrictions. Whatever restrictions there are, they have been kept secret, so much testing will need to ensue.

2.1 API code can't set 'paused' property on users

Dunno. For some reason Pingdom implemented this differently for users than they did for checks. The API accepts paused: NO, but doesn't seem set the property. Trying true or false resulted in rejected API calls.

notifywhenbackup is ignored by Pingdom API

Possibly because no userids are provided. I notice the web UI doesn't save that setting when there's no users assigned. Need to test this, and then reject resource definitions that specify notifywhenbackup but no userids.

Updating of tags sometimes causes tag count to increase

Doesn't seem to hurt anything, but wtf. Appears to be a "feature" of the Pingdom API, although I'm not sure what purpose it serves, and I'd prefer it didn't do that.

[update] It only happens when new tags are added: existing tags get their counter increased by one.

Remove extra call to get_check_details

Currently, after we create or update a check, we make an additional call to get_check_details in order to update the local copy of the check. However, this is probably unnecessary. Puppet fails or succeeds on the result of the create/update, not by comparing the state of the check variable.

Extra API calls is a bug.

Provide credentials file option

Allow a credentials file to be passed. E.g. read credentials in YAML from /etc/pingdom/credentials.yml or similar. This will at least be useful for testing. It might also make it possible for puppet resource pingdom_check to work, and someone might care about that.

Pingdom_check { 
    auth_file => '/etc/pingdom/credentials.yml',
    require   => File['/etc/pingdom/credentials.yml']
}   

Teams API is only available on multi-user accounts

Apparently Teams Account is a different level of account, and only this level provides the Teams API and requires the account_email parameter.

Will need to allow for not setting account_email and maybe try to disable Team API if we can detect it's not available.

Fix contact_targets.insync?

API always returns severity, which means that unless severity is specified in the manifest, we'll be trying to update this property on every run.

httpcustom can't update additionalurls property

Request:

{
    :host=>"portable-evil.T-mobile.com",
    :paused=>:true,
    :tags=>"http,puppet-managed",
    :additionalurls=>"www.domain1.com;www.domain2.com",
    :auth=>"super:secret",
    :url=>"/status/pingdom.xml",
    :name=>"http://portable-evil.T-mobile.com/status",
    :use_legacy_notifications=>:true,
    :type=>:httpcustom
}

Response:

{"error":{
    "statuscode":400,
    "statusdesc":"Bad Request",
    "errormessage":"Invalid parameter value => additionalurls"
}}

It says parameter value, so I'm presuming that the parameter itself is being accepted. According to the documentation, the value should be a semicolon-separated list of hosts, e.g. host1.domain.com;host2.domain.com, however PingdomLib source code comment suggests that the delimiter is colon. In any case, neither works and results in an HTTP 400 error.

Something weird with LOW severity contact_targets

We can correctly update severity to LOW, and the correct results are returned when we query the API, but the UI doesn't show the LOW severity targets. This is either due to missing a parameter to control the feature controlled by the checkbox labeled 'Use same alerting regardless of check importance', or an actual bug in the API.

base_tags feature

Allow user to specify a set of base tags to be appended to all resources, e.g.

Pingdom_check { 
    base_tags => ['puppet-managed'],
    filter_tags  => ['puppet-managed']
}

pingdom_check { "foo":
    tags => [ 'foo', 'bar'] # actually => ['foo', 'bar', 'puppet-managed']
}

Using these two tags together in the defaults ensures that the module only manages a specific subset of resources.

Can't access users API endpoint

{"statuscode"=>403, "statusdesc"=>"Forbidden", "errormessage"=>"Forbidden"}

Will probably need to contact Pingdom support to figure this one out.

Unsanitary tags must be rejected

Apparently there's acceptable character filters in place for tags. Trying to set a tag to e.g. $facts['fqdn'] will cause the API call to fail. We need to trap this and raise a meaningful exception.

Unclear as to what constitutes an acceptable character. Will need to investigate.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.