Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds new plan_outputs functionality to allow configuring what to do with plans #156

Merged
merged 13 commits into from
Jan 7, 2018

Conversation

ross
Copy link
Contributor

@ross ross commented Dec 2, 2017

  • Plumbing for plan_output support, configurable from the config file
  • Port existing logger output to a plan_output ^
  • Create a Markdown plan_output
  • Create a HTML plan_output

/cc @wrouesnel
/cc Fixes #155

@ross ross self-assigned this Dec 2, 2017
Mostly works, but doesn't yet dump out the values
@ross
Copy link
Contributor Author

ross commented Dec 2, 2017

The config for these work just work like the providers, e.g.:

---
manager:
  include_meta: true
  max_workers: 4
  plan_outputs:
    logger:
      class: octodns.provider.plan.PlanLogger
      level: 'info'
    markdown:
      class: octodns.provider.plan.PlanMarkdown

And just like providers you can use arbitrary modules/classes you have on the python path so it's trivial to hook something custom in, e.g. PlanGitHubComment. If I was writing that I'd have it inherit from PlanMarkdown, override run, call super, and pass in a StringIO as fh. That'd give you the output which you could turn around and submit as a comment on the GitHub PR.

What follows is an example of where the markdown outout is right now. The main bit blocking it from being a real solution is that there's not a good/easy way to stringify the value/values of the various records types. The existing `repr stuff is what's currently used for the log output, but that a pretty specific setup targeted at the existing logging. Not ideal for markdown and other outputs. I will circle back and think about what makes sense to wrap that up.

Fwiw, HTML would probably be a better output format for GitHub comments as you could fancier tables. In general open to thoughts/suggestions on the best formatting for the output

githubtest.net.

powerdns

Name Type Existing TTL New TTL Existing Value New Value Source
A 300 300 todo todo config
cname CNAME 300 300 todo todo config

Summary: Creates=0, Updates=2, Deletes=0, Existing Records=17

@ross
Copy link
Contributor Author

ross commented Dec 2, 2017

Pushed an update with the following format. I'm relatively happy with it. Seems to be about the best I can manage with markdown tables.

githubtest.net.

powerdns

Operation Name Type TTL Value Source
Update A 300 1.2.3.5; 1.2.3.6
300 2.2.3.5; 2.2.3.6; NA-US: 5.5.5.5, 6.6.6.6 config
Delete aaaa AAAA 600 2601:644:500:e210:62f8:1dff:feb8:947a
Update mx MX 300 '10 smtp-4.githubtest.net.'; '20 smtp-2.githubtest.net.'; '30 smtp-3.githubtest.net.'; '40 smtp-1.githubtest.net.'
300 '100 smtp-4.githubtest.net.'; '200 smtp-2.githubtest.net.'; '300 smtp-3.githubtest.net.'; '400 smtp-1.githubtest.net.' config
Update cname CNAME 300 githubtest.net.
600 githubtest.net. config
Create cx A 3600 1.2.3.4 config

Summary: Creates=1, Updates=3, Deletes=1, Existing Records=17

@ross
Copy link
Contributor Author

ross commented Dec 3, 2017

Added a PlanHtml that outputs the following. I think the values are a bit easier to read and the colspan support is nice.

githubtest.net.

powerdns

Operation Name Type TTL Value Source
Update A 300 1.2.3.5
1.2.3.6
300 2.2.3.5
2.2.3.6
NA-US: 5.5.5.5, 6.6.6.6
config
Delete aaaa AAAA 600 2601:644:500:e210:62f8:1dff:feb8:947a
Update mx MX 300 '10 smtp-4.githubtest.net.'
'20 smtp-2.githubtest.net.'
'30 smtp-3.githubtest.net.'
'40 smtp-1.githubtest.net.'
300 '100 smtp-4.githubtest.net.'
'200 smtp-2.githubtest.net.'
'300 smtp-3.githubtest.net.'
'400 smtp-1.githubtest.net.'
config
Update cname CNAME 300 githubtest.net.
600 githubtest.net. config
Create cx A 3600 1.2.3.4 config
Summary: Creates=1, Updates=3, Deletes=1, Existing Records=17

@wrouesnel
Copy link

wrouesnel commented Dec 3, 2017

These look reasonably nice - certainly an improvement over trying to pipe the summary into the GH comment.

The framework being extensible should allow enough customization - for our in-house application I would probably make it a lot simpler or a more paragraphing style, but it's not a fully formed thought yet.

I'm basically planning to deploy this branch Monday inhouse for us to see how it goes.

@ross
Copy link
Contributor Author

ross commented Dec 9, 2017

octoDNS Plan for 12deadbeef34

githubtest.net.

powerdns

Operation Name Type TTL Value Source
Update A 300 2.2.3.5
2.2.3.6
300 1.2.3.5
1.2.3.6
config
Summary: Creates=0, Updates=1, Deletes=0, Existing Records=17

Automatically generated by PlanGitHubPr

@ross
Copy link
Contributor Author

ross commented Dec 9, 2017

Comment above was auto generated and attached to this issue with a wrapper around the html plan. I'll probably turn it into a standalone thing published separate from octoDNS.

@ross ross merged commit de4dc76 into master Jan 7, 2018
@ross ross deleted the plan-outputs branch January 7, 2018 01:04
@xt0rted
Copy link
Contributor

xt0rted commented Mar 18, 2018

@ross was PlanGitHubPr published anywhere? This looks to do exactly what I'm trying to setup right now.

@ross
Copy link
Contributor Author

ross commented Mar 18, 2018

I haven't, but here's all the code that was involved in the quick test/POC.

#
#
#

from __future__ import absolute_import, division, print_function, \
    unicode_literals

from StringIO import StringIO
from github import Github
from logging import getLogger
from octodns.provider.plan import PlanHtml
from os import environ


class PlanGitHubPr(PlanHtml):
    NEEDLE = '<!--- octodns/plan --->'

    log = getLogger('PlanGitHubPr')

    def run(self, plans, *args, **kwargs):
        try:
            access_token = environ['OCTODNS_PLAN_ACCESS_TOKEN']
            repo_name = environ['OCTODNS_PLAN_REPO']
            pull_number = int(environ['OCTODNS_PLAN_PULL'])
            sha = environ['OCTODNS_PLAN_SHA']
        except KeyError as e:
            self.log.warn('missing required env var %s', e.args[0])
            return

        github = Github(access_token)
        repo = github.get_repo(repo_name, lazy=True)
        pull = repo.get_pull(pull_number)

        buf = StringIO()
        super(PlanGitHubPr, self).run(plans, fh=buf, *args, **kwargs)

        for comment in pull.get_issue_comments():
            if self.NEEDLE in comment.body:
                break

        body = '''{needle}

## octoDNS Plan for {sha}

{plan}

Automatically generated by {klass}
'''.format(needle=self.NEEDLE, sha=sha, plan=buf.getvalue(),
           klass=self.__class__.__name__)

        if comment and self.NEEDLE in comment.body:
            # update this one
            self.log.info('%s/pull/%d plan updated', repo_name, pull_number)
            comment.edit(body)
        else:
            # create a new one
            self.log.info('%s/pull/%d plan created', repo_name, pull_number)
            pull.create_issue_comment(body)

There'll likely be full/formal support in the future, but there's no timeline on that so I wouldn't recommend waiting if it's something you're looking for.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants