Top Banner

Click here to load reader

20

Chef on MongoDB and Pyramid

Jun 24, 2015

Download

Technology

Rick Copeland

DevOps is the new rage among system administrators, applying agile software development techniques to infrastructure configuration management. In the center of the DevOps movement is the open-source Chef tool, implemented in Ruby atop CouchDB. Unsatisfied with the performance of the open-source and/or hosted Chef server and needing better integration with our Python web application, we set out to build a new implementation in Python atop MongoDB. This talk will give you an overview of Chef, reasons for doing a new implementation, and lots of code examples of how we made it all work together to get a chef server that screams.

This talk is updated with the latest version of MongoPyChef, ported to run on Pyramid and open sourced at https://github.com/rick446/MongoPyChef
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Chef on MongoDB and Pyramid

Chef in Python and MongoDB

Rick Copeland @rick446Arborian Consulting, LLC

Page 2: Chef on MongoDB and Pyramid

What is Chef?

Infrastructure as Code

Resources & Providers

Cookbooks, Recipes, Clients, and Nodes

Page 3: Chef on MongoDB and Pyramid

Chef System Architecture

Chef Server (API)

RabbitMQRabbitMQRabbitMQ

CouchDB Solr

Solr Indexer

chef-clientknifeChef Server

(Web UI)

HTTP REST API

Page 4: Chef on MongoDB and Pyramid

Chef Deployment (chef-client)

Build, register, and authenticate the node

Synchronize cookbooks

Build resource collection (run the recipes in order)

Configure node (“converge”)

Run notification handlers

Page 5: Chef on MongoDB and Pyramid

Chef System Architecture

Chef Server (API)

RabbitMQRabbitMQRabbitMQ

CouchDB Solr

Solr Indexer

chef-clientknifeChef Server

(Web UI)

HTTP REST API

Ruby

RubyRub

y

Page 6: Chef on MongoDB and Pyramid

So What’s the Problem?

Chef assumes a bootstrapped node exists

Chef doesn’t keep release notes

Code and infrastructure are versioned differently

Solution: Web app to manage deployments & generate release notes

Page 7: Chef on MongoDB and Pyramid

Chef System Architecture (Revised)

MongoDB

Solr

Solr Indexer

chef-clientknife

HTTP REST API

MonQ

Chef Server (API + web)

Ruby

Python

Page 8: Chef on MongoDB and Pyramid

Why Change It?

Reduce # of processes & technologies

Don’t know Ruby well

Keep private keys out of the system

Integrate with existing authentication

Performance

Page 9: Chef on MongoDB and Pyramid

API Endpoints: Short and Sweet

/clients

/data

/roles

/nodes

/cookbooks

/environment

s

/sandboxes

/search

Page 10: Chef on MongoDB and Pyramid

Data Models

Mostly JSON almost BSON References to Ruby files stored

separately{ "name": "allura-0.0.1”,… "json_class": "Chef::CookbookVersion", "attributes": [ { "name": "default.rb", "url": "https://s3.amazonaws.com/opscode-platform-production-data/… "checksum": "749a3a328d6c47a32d134b336183981f", "path": "attributes/default.rb", "specificity": "default”…

Ruby files stored on S3

Page 11: Chef on MongoDB and Pyramid

Ming Models (Schema)

role = collection( 'chef.role', doc_session, Field('_id', S.ObjectId()), Field('account_id', S.ObjectId(if_missing=None)), Field('name', str), Field('description', str), Field('default_attributes', str), Field('override_attributes', str), Field('run_list', [ str ] ), Field('env_run_lists', { str: [ str ]}), Index('account_id', 'name', unique=True))  

MongoDB Validator

Shorthand with Python Types

Embedded Documents

Index Definitions

Page 12: Chef on MongoDB and Pyramid

Ming Models (Classes)

class Role(ModelBase):

def __name__(self): return self.name

def __json__(self): return dict( chef_type='role', json_class='Chef::Role', … default_attributes=loads(self.default_attributes), …)

def update(self, d): self.name = d['name'] … self.default_attributes = dumps(d['default_attributes']) self.override_attributes = dumps(d['override_attributes']) …

Models know where they live

Models can be turned into dict

(to be JSONified)

Models can be updated from

dict

Page 13: Chef on MongoDB and Pyramid

Declarative JSON Validation

class RoleSchema(JSONModelSchema):

model_class=CM.role

chef_type='role’

json_class='Chef::Role’

exclude_fields=['_id', 'account_id']

Page 14: Chef on MongoDB and Pyramid

RESTful URL Traversal

Find resource /foo/bar/baz Root()[‘foo’][‘bar’][‘baz’]

(Resource, method) view @view_config(context=Resource,

request_method=‘GET’, …)

Authorization @view_config(…, permission=‘read’, …)

Rendering @view_config(…, renderer=‘json’)

Page 15: Chef on MongoDB and Pyramid

RESTful URL Traversal

class ResourceCollection(object): __name__ = None __model__ = None key_property='name’

def allow_access(self, client, permission): return permission == 'read' or client.admin

def __getitem__(self, name): obj = self.account.get_object( self.__model__, **{ self.key_property: name }) if obj is None: raise exc.HTTPNotFound() obj.__parent__ = self return obj

Check auth

Traverse to find sub-objects

Page 16: Chef on MongoDB and Pyramid

RESTful URL Views

@view_config(context=Roles, renderer='json', request_method='GET’, permission='read')def list_roles(context, request): return dict( (n.name, request.resource_url(n)) for n in context.find())

@view_config(context=Roles, renderer='json', request_method='POST’, permission='create')def create_role(context, request): n = context.new_object() value = V.RoleSchema().to_python( request.json, None) n.update(value) …

Resources can be located

Convert and validate JSON

input

Page 17: Chef on MongoDB and Pyramid

Lessons Learned

Don’t trust the docs Don’t trust the docs▪ Don’t trust the docs

Use fat models

Framework support for REST & JSON

You’re gonna have to learn some Ruby anyway

JSON != BSON

Page 18: Chef on MongoDB and Pyramid

Next Steps

Port from homegrown framework to Pyramid

Better test coverage

Search support (SOLR / ElasticSearch)

More testing with real-world deployments

Finalize integration with deployment manager

Page 19: Chef on MongoDB and Pyramid

Questions?

Rick Copeland @rick446Arborian Consulting, LLC

Page 20: Chef on MongoDB and Pyramid

github.com/rick446/MongoPyChef

Rick Copeland @rick446Arborian Consulting, LLC