Skip to content
This repository was archived by the owner on May 9, 2020. It is now read-only.
1 change: 1 addition & 0 deletions chef/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from chef.client import Client
from chef.data_bag import DataBag, DataBagItem
from chef.exceptions import ChefError
from chef.cookbook import Cookbook
from chef.node import Node
from chef.role import Role
from chef.environment import Environment
Expand Down
15 changes: 13 additions & 2 deletions chef/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@ class ChefObject(six.with_metaclass(ChefObjectMeta, object)):

api_version = '0.9'

def __init__(self, name, api=None, skip_load=False):
def __init__(self, name, version='_latest', api=None, skip_load=False):
self.name = name
self.api = api or ChefAPI.get_global()
self._check_api_version(self.api)
self.url = self.__class__._build_url(name, version)

self.url = self.__class__.url + '/' + self.name
self.exists = False
data = {}
if not skip_load:
Expand Down Expand Up @@ -138,3 +138,14 @@ def _check_api_version(cls, api):
# serialization perhaps).
if api and cls.api_version_parsed > api.version_parsed:
raise ChefAPIVersionError("Class %s is not compatible with API version %s" % (cls.__name__, api.version))

@classmethod
def _build_url(cls, name, version):
"""Determine the url for the request"""
# Cookbooks need some special handling, and we default to the
# latest revision if version goes unspecified.
if cls.__name__ == 'Cookbook':
url = "{0}/{1}/{2}".format(cls.url, name, version)
else:
url = cls.url + '/' + name
return url
5 changes: 3 additions & 2 deletions chef/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def _populate(self, data):
if self.platform:
self.orgname = data.get('orgname')
self.validator = bool(data.get('validator', False))
self.public_key = data.get('certificate')
self.public_key = data.get('public_key')
self.admin = False
else:
self.admin = bool(data.get('admin', False))
Expand All @@ -31,7 +31,7 @@ def to_dict(self):
d.update({
'orgname': self.orgname,
'validator': self.validator,
'certificate': self.certificate,
'public_key': self.certificate,
'clientname': self.name,
})
else:
Expand All @@ -48,6 +48,7 @@ def create(cls, name, api=None, admin=False):
obj.admin = admin
d = api.api_request('POST', cls.url, data=obj)
obj.private_key = d['private_key']
obj.public_key = d['public_key']
return obj

def rekey(self, api=None):
Expand Down
30 changes: 30 additions & 0 deletions chef/cookbook.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from chef.base import ChefObject, ChefAPI
from chef.exceptions import ChefServerNotFoundError

class Cookbook(ChefObject):
"""A Chef Cookbook object."""

url = '/cookbooks'

attributes = {
'definitions': list,
'name': str,
'attributes': list,
'files': list,
'json_class': str,
'providers': list,
'metadata': dict,
'libraries': list,
'templates': list,
'resources': list,
'cookbook_name': str,
'version': str,
'recipes': list,
'root_files': list,
'chef_type': str,
}


def __getitem__(self, attr):

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is neither a good idea nor particularly helpful.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for reviewing the pull request. It's been awhile since I wrote this, but I recall writing this for use in generating a tabular cookbook report in which the column headers were environments and there was a single row per cookbook, with the fields mapping cookbook versions to each of the environments. Working with several environments, it was a quick way to ascertain what the version differences were and to quickly identify a few version issues (e.g. catching not having tied the "production" environment to a specific version, potentially a bad thing if uploading a newer version of a cookbook...). I might have used the versions method as part of that, but don't recall exactly if it was useful for my purposes or if I just threw it in...

return self.__dict__[attr]

2 changes: 1 addition & 1 deletion chef/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def test_basic(self):
def test_current_dir(self):
api = self.load('current_dir.rb')
path = os.path.join(os.path.dirname(__file__), 'configs', 'test_1')
self.assertEqual(api.client, path)
self.assertEqual(os.path.normpath(api.client), path)

def test_env_variables(self):
try:
Expand Down
5 changes: 2 additions & 3 deletions chef/tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,21 @@ def test_get(self):
self.assertTrue(client.certificate)
self.assertEqual(client.private_key, None)

@unittest2.skip('Unknown failure, skipping until tomorrow morning <NPK 2012-03-22>')
def test_create(self):
name = self.random()
client = Client.create(name)
self.register(client)
self.assertEqual(client.name, name)
#self.assertEqual(client.orgname, 'pycheftest') # See CHEF-2019
self.assertTrue(client.private_key)

self.assertTrue(client.public_key)
self.assertIn(name, Client.list())

client2 = Client(name)
client2.rekey()
self.assertEqual(client.public_key, client2.public_key)
self.assertNotEqual(client.private_key, client2.private_key)

@unittest2.skip('Unknown failure, skipping until tomorrow morning <NPK 2012-03-22>')
def test_delete(self):
name = self.random()
client = Client.create(name)
Expand Down