chef-server-api 0.8.16 → 0.9.0.a3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,9 +6,9 @@
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
7
  # you may not use this file except in compliance with the License.
8
8
  # You may obtain a copy of the License at
9
- #
9
+ #
10
10
  # http://www.apache.org/licenses/LICENSE-2.0
11
- #
11
+ #
12
12
  # Unless required by applicable law or agreed to in writing, software
13
13
  # distributed under the License is distributed on an "AS IS" BASIS,
14
14
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -18,17 +18,17 @@
18
18
 
19
19
  require File.join("chef", "webui_user")
20
20
 
21
- class ChefServerApi::Users < ChefServerApi::Application
21
+ class Users < Application
22
22
  provides :json
23
-
23
+
24
24
  before :authenticate_every
25
-
25
+
26
26
  # GET to /users
27
27
  def index
28
- @user_list = Chef::WebUIUser.cdb_list
29
- display(@user_list.inject({}) { |r,n| r[n] = absolute_slice_url(:user, n); r })
30
- end
31
-
28
+ @user_list = Chef::WebUIUser.cdb_list
29
+ display(@user_list.inject({}) { |r,n| r[n] = absolute_url(:user, n); r })
30
+ end
31
+
32
32
  # GET to /users/:id
33
33
  def show
34
34
  begin
@@ -38,7 +38,7 @@ class ChefServerApi::Users < ChefServerApi::Application
38
38
  end
39
39
  display @user
40
40
  end
41
-
41
+
42
42
  # PUT to /users/:id
43
43
  def update
44
44
  begin
@@ -50,7 +50,7 @@ class ChefServerApi::Users < ChefServerApi::Application
50
50
  @user.cdb_save
51
51
  display(@user)
52
52
  end
53
-
53
+
54
54
  # POST to /users
55
55
  def create
56
56
  @user = params["inflated_object"]
@@ -60,18 +60,18 @@ class ChefServerApi::Users < ChefServerApi::Application
60
60
  @user.cdb_save
61
61
  self.status = 201
62
62
  else
63
- raise Conflict, "User already exists"
63
+ raise Conflict, "User already exists"
64
64
  end
65
- display({ :uri => absolute_slice_url(:user, @user.name) })
66
- end
67
-
65
+ display({ :uri => absolute_url(:user, @user.name) })
66
+ end
67
+
68
68
  def destroy
69
69
  begin
70
70
  @user = Chef::WebUIUser.cdb_load(params[:id])
71
- rescue Chef::Exceptions::CouchDBNotFound => e
71
+ rescue Chef::Exceptions::CouchDBNotFound => e
72
72
  raise NotFound, "Cannot load user #{params[:id]}"
73
73
  end
74
74
  @user.cdb_destroy
75
75
  display @user
76
- end
76
+ end
77
77
  end
@@ -6,9 +6,9 @@
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
7
  # you may not use this file except in compliance with the License.
8
8
  # You may obtain a copy of the License at
9
- #
9
+ #
10
10
  # http://www.apache.org/licenses/LICENSE-2.0
11
- #
11
+ #
12
12
  # Unless required by applicable law or agreed to in writing, software
13
13
  # distributed under the License is distributed on an "AS IS" BASIS,
14
14
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -17,66 +17,96 @@
17
17
  #
18
18
 
19
19
  module Merb
20
- module ChefServerApi
21
- module TarballHelper
20
+ module TarballHelper
22
21
 
23
- class FileParameterException < StandardError ; end
22
+ class FileParameterException < StandardError ; end
24
23
 
25
- def validate_file_parameter(cookbook_name, file_param)
26
- raise FileParameterException, "missing required parameter: file" unless file_param
27
- raise FileParameterException, "invalid parameter: file must be a File" unless file_param.respond_to?(:has_key?) && file_param[:tempfile].respond_to?(:read)
28
- tarball_path = file_param[:tempfile].path
29
- raise FileParameterException, "invalid tarball: (try creating with 'tar czf cookbook.tar.gz cookbook/')" unless system("tar", "tzf", tarball_path)
30
- entry_roots = `tar tzf #{tarball_path}`.split("\n").map{|e|(e.split('/')-['.']).first}.uniq
31
- raise FileParameterException, "invalid tarball: tarball root must contain #{cookbook_name}" unless entry_roots.include?(cookbook_name)
32
- end
24
+ def validate_file_parameter(cookbook_name, file_param)
25
+ raise FileParameterException, "missing required parameter: file" unless file_param
26
+ raise FileParameterException, "invalid parameter: file must be a File" unless file_param.respond_to?(:has_key?) && file_param[:tempfile].respond_to?(:read)
27
+ tarball_path = file_param[:tempfile].path
28
+ raise FileParameterException, "invalid tarball: (try creating with 'tar czf cookbook.tar.gz cookbook/')" unless system("tar", "tzf", tarball_path)
29
+ entry_roots = `tar tzf #{tarball_path}`.split("\n").map{|e|(e.split('/')-['.']).first}.uniq
30
+ raise FileParameterException, "invalid tarball: tarball root must contain #{cookbook_name}" unless entry_roots.include?(cookbook_name)
31
+ end
32
+
33
+ def sandbox_base
34
+ Chef::Config.sandbox_path
35
+ end
36
+
37
+ def sandbox_location(sandbox_guid)
38
+ File.join(sandbox_base, sandbox_guid)
39
+ end
40
+
41
+ def sandbox_checksum_location(sandbox_guid, checksum)
42
+ File.join(sandbox_location(sandbox_guid), checksum)
43
+ end
33
44
 
34
- def cookbook_base
35
- [Chef::Config.cookbook_path].flatten.first
36
- end
37
-
38
- def cookbook_location(cookbook_name)
39
- File.join(cookbook_base, cookbook_name)
40
- end
45
+ def checksum_base
46
+ Chef::Config.checksum_path
47
+ end
48
+
49
+ def checksum_location(checksum)
50
+ File.join(checksum_base, checksum[0..1], checksum)
51
+ end
52
+
53
+ def cookbook_base
54
+ [Chef::Config.cookbook_path].flatten.first
55
+ end
56
+
57
+ def cookbook_location(cookbook_name)
58
+ File.join(cookbook_base, cookbook_name)
59
+ end
60
+
61
+ def cookbook_base
62
+ [Chef::Config.cookbook_path].flatten.first
63
+ end
64
+
65
+ def cookbook_location(cookbook_name)
66
+ File.join(cookbook_base, cookbook_name)
67
+ end
41
68
 
42
- def cookbook_tarball_location(cookbook_name)
43
- File.join(Chef::Config.cookbook_tarball_path, "#{cookbook_name}.tar.gz")
44
- end
45
-
46
- def get_or_create_cookbook_tarball_location(cookbook_name)
47
- tarball_location = cookbook_tarball_location(cookbook_name)
48
- unless File.exists? tarball_location
49
- args = ["tar", "-C", cookbook_base, "-czf", tarball_location, cookbook_name]
50
- Chef::Log.debug("Tarball for #{cookbook_name} not found, so creating at #{tarball_location} with '#{args.join(' ')}'")
51
- FileUtils.mkdir_p(Chef::Config.cookbook_tarball_path)
52
- system(*args)
53
- end
54
- tarball_location
55
- end
69
+ def cookbook_location(cookbook_name)
70
+ File.join(cookbook_base, cookbook_name)
71
+ end
56
72
 
57
- def expand_tarball_and_put_in_repository(cookbook_name, file)
58
- # untar cookbook tarball into tempdir
59
- tempdir = File.join("#{file.path}.data")
60
- Chef::Log.debug("Creating #{tempdir} and untarring #{file.path} into it")
61
- FileUtils.mkdir_p(tempdir)
62
- raise "Could not untar file" unless system("tar", "xzf", file.path, "-C", tempdir)
63
-
64
- cookbook_path = cookbook_location(cookbook_name)
65
- tarball_path = cookbook_tarball_location(cookbook_name)
66
-
67
- # clear any existing cookbook components and move tempdir into the repository
68
- Chef::Log.debug("Moving #{tempdir} to #{cookbook_path}")
69
- FileUtils.rm_rf(cookbook_path)
70
- FileUtils.mkdir_p(cookbook_path)
71
- Dir[File.join(tempdir, cookbook_name, "*")].each{|e| FileUtils.mv(e, cookbook_path)}
73
+ def cookbook_tarball_location(cookbook_name)
74
+ File.join(Chef::Config.cookbook_tarball_path, "#{cookbook_name}.tar.gz")
75
+ end
72
76
 
73
- # clear the existing tarball (if exists) and move the downloaded tarball to the cache
74
- Chef::Log.debug("Moving #{file.path} to #{tarball_path}")
77
+ def get_or_create_cookbook_tarball_location(cookbook_name)
78
+ tarball_location = cookbook_tarball_location(cookbook_name)
79
+ unless File.exists? tarball_location
80
+ args = ["tar", "-C", cookbook_base, "-czf", tarball_location, cookbook_name]
81
+ Chef::Log.debug("Tarball for #{cookbook_name} not found, so creating at #{tarball_location} with '#{args.join(' ')}'")
75
82
  FileUtils.mkdir_p(Chef::Config.cookbook_tarball_path)
76
- FileUtils.rm_f(tarball_path)
77
- FileUtils.mv(file.path, tarball_path)
83
+ system(*args)
78
84
  end
79
-
85
+ tarball_location
80
86
  end
87
+
88
+ def expand_tarball_and_put_in_repository(cookbook_name, file)
89
+ # untar cookbook tarball into tempdir
90
+ tempdir = File.join("#{file.path}.data")
91
+ Chef::Log.debug("Creating #{tempdir} and untarring #{file.path} into it")
92
+ FileUtils.mkdir_p(tempdir)
93
+ raise "Could not untar file" unless system("tar", "xzf", file.path, "-C", tempdir)
94
+
95
+ cookbook_path = cookbook_location(cookbook_name)
96
+ tarball_path = cookbook_tarball_location(cookbook_name)
97
+
98
+ # clear any existing cookbook components and move tempdir into the repository
99
+ Chef::Log.debug("Moving #{tempdir} to #{cookbook_path}")
100
+ FileUtils.rm_rf(cookbook_path)
101
+ FileUtils.mkdir_p(cookbook_path)
102
+ Dir[File.join(tempdir, cookbook_name, "*")].each{|e| FileUtils.mv(e, cookbook_path)}
103
+
104
+ # clear the existing tarball (if exists) and move the downloaded tarball to the cache
105
+ Chef::Log.debug("Moving #{file.path} to #{tarball_path}")
106
+ FileUtils.mkdir_p(Chef::Config.cookbook_tarball_path)
107
+ FileUtils.rm_f(tarball_path)
108
+ FileUtils.mv(file.path, tarball_path)
109
+ end
110
+
81
111
  end
82
112
  end
@@ -8,7 +8,7 @@
8
8
  %body
9
9
  #container
10
10
  #header
11
- %h1= link_to "Chef REST API", absolute_slice_url(:top)
11
+ %h1= link_to "Chef REST API", absolute_url(:top)
12
12
  #main-navigation
13
13
  .clear
14
14
  #wrapper
data/bin/chef-server ADDED
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # ./chef-server - Serving up piping hot infrastructure!
4
+ #
5
+ # Author:: Adam Jacob (<adam@opscode.com>)
6
+ # Copyright:: Copyright (c) 2008 Opscode, Inc.
7
+ # License:: Apache License, Version 2.0
8
+ #
9
+ # Licensed under the Apache License, Version 2.0 (the "License");
10
+ # you may not use this file except in compliance with the License.
11
+ # You may obtain a copy of the License at
12
+ #
13
+ # http://www.apache.org/licenses/LICENSE-2.0
14
+ #
15
+ # Unless required by applicable law or agreed to in writing, software
16
+ # distributed under the License is distributed on an "AS IS" BASIS,
17
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18
+ # See the License for the specific language governing permissions and
19
+ # limitations under the License.
20
+
21
+ # Based on the 'merb' command, by Ezra
22
+
23
+ require "rubygems"
24
+ require "merb-core"
25
+
26
+ # Load chef and chef-server-api from source rather than gem, if present
27
+ $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../../chef/lib/'))
28
+ $:.unshift(File.expand_path(File.dirname(__FILE__) + '/../lib'))
29
+
30
+ require 'chef'
31
+ require 'chef-server-api'
32
+
33
+ # Ensure the chef gem we load is the same version as the chef server
34
+ unless defined?(Chef)
35
+ gem "chef", "=" + CHEF_SERVER_VERSION
36
+ require 'chef'
37
+ end
38
+
39
+ # Print the help message if our argv looks fishy
40
+ if ARGV[0] && ARGV[0] =~ /^[^-]/
41
+ ARGV.push "-H"
42
+ end
43
+
44
+ # Default to thin
45
+ unless %w[-a --adapter -i --irb-console -r --script-runner].any? { |o| ARGV.index(o) }
46
+ ARGV.push *%w[-a thin]
47
+ end
48
+
49
+ # Tell merb where to root
50
+ ARGV.push *[ "-m", CHEF_SERVER_API_ROOT]
51
+
52
+ # attempt to find the user and group that this process will become. Fixes CHEF-1015
53
+ if (index = ARGV.index("-u"))
54
+ Chef::Config[:signing_ca_user] = ARGV[index+1]
55
+ end
56
+ if (index = ARGV.index("-G"))
57
+ Chef::Config[:signing_ca_group] = ARGV[index+1]
58
+ end
59
+
60
+ # Find and load the config
61
+ if index = ARGV.index("-C")
62
+ config = ARGV[index+1]
63
+ ARGV.delete("-C")
64
+ ARGV.delete(config)
65
+ Chef::Config.from_file(File.expand_path(config))
66
+ else
67
+ Chef::Config.from_file(
68
+ File.join("/etc", "chef", "server.rb")
69
+ )
70
+ end
71
+
72
+ Chef::Log.init(Chef::Config[:log_location])
73
+ Chef::Log.level = Chef::Config[:log_level]
74
+
75
+ Merb.start
@@ -0,0 +1,6 @@
1
+ Merb::Config.use do |c|
2
+ c[:exception_details] = true
3
+ c[:reload_classes] = true
4
+ end
5
+
6
+ Merb.logger.level = :debug
data/config/init.rb CHANGED
@@ -1,19 +1,19 @@
1
1
  #
2
2
  # ==== Standalone Chefserver configuration
3
- #
4
- # This configuration/environment file is only loaded by bin/slice, which can be
3
+ #
4
+ # This configuration/environment file is only loaded by bin/slice, which can be
5
5
  # used during development of the slice. It has no effect on this slice being
6
6
  # loaded in a host application. To run your slice in standalone mode, just
7
7
  # run 'slice' from its directory. The 'slice' command is very similar to
8
- # the 'merb' command, and takes all the same options, including -i to drop
8
+ # the 'merb' command, and takes all the same options, including -i to drop
9
9
  # into an irb session for example.
10
10
  #
11
11
  # The usual Merb configuration directives and init.rb setup methods apply,
12
12
  # including use_orm and before_app_loads/after_app_loads.
13
13
  #
14
- # If you need need different configurations for different environments you can
14
+ # If you need need different configurations for different environments you can
15
15
  # even create the specific environment file in config/environments/ just like
16
- # in a regular Merb application.
16
+ # in a regular Merb application.
17
17
  #
18
18
  # In fact, a slice is no different from a normal # Merb application - it only
19
19
  # differs by the fact that seamlessly integrates into a so called 'host'
@@ -21,25 +21,68 @@
21
21
  # code and views.
22
22
  #
23
23
 
24
- $: << File.join(File.dirname(__FILE__), "..", "..", "chef", "lib")
24
+ require 'merb-assets'
25
+ require 'merb-helpers'
26
+ require 'merb-param-protection'
27
+
28
+ require 'bunny'
29
+ require 'uuidtools'
30
+ require 'ohai'
31
+ require 'openssl'
32
+
25
33
  require 'chef'
34
+ require 'chef/role'
35
+ require 'chef/data_bag'
36
+ require 'chef/data_bag_item'
37
+ require 'chef/api_client'
38
+ require 'chef/webui_user'
39
+ require 'chef/certificate'
40
+ require 'chef/data_bag'
41
+ require 'chef/data_bag_item'
42
+ require 'chef/cookbook_version'
43
+ require 'chef/sandbox'
44
+ require 'chef/checksum'
26
45
 
27
- merb_gems_version = " > 1.0"
28
- dependency "merb-assets", merb_gems_version
29
- dependency "merb-helpers", merb_gems_version
30
- dependency "chef", :immediate=>true unless defined?(Chef)
46
+ require 'mixlib/authentication'
31
47
 
32
- require 'rubygems'
48
+ Mixlib::Authentication::Log.logger = Ohai::Log.logger = Chef::Log.logger
49
+
50
+ # Only used for the error page when visiting with a browser...
51
+ use_template_engine :haml
33
52
 
34
53
  Merb::Config.use do |c|
35
54
  c[:session_id_key] = '_chef_server_session_id'
36
55
  c[:session_secret_key] = Chef::Config.manage_secret_key
37
56
  c[:session_store] = 'cookie'
38
57
  c[:exception_details] = true
39
- c[:reload_classes] = true
58
+ c[:reload_classes] = true
40
59
  c[:log_level] = Chef::Config[:log_level]
41
60
  if Chef::Config[:log_location].kind_of?(String)
42
61
  c[:log_file] = Chef::Config[:log_location]
43
62
  end
44
63
  end
45
64
 
65
+ unless Merb::Config.environment == "test"
66
+ # create the couch design docs for nodes, roles, and databags
67
+ Chef::CouchDB.new.create_id_map
68
+ Chef::Node.create_design_document
69
+ Chef::Role.create_design_document
70
+ Chef::DataBag.create_design_document
71
+ Chef::ApiClient.create_design_document
72
+ Chef::WebUIUser.create_design_document
73
+ Chef::CookbookVersion.create_design_document
74
+ Chef::Sandbox.create_design_document
75
+ Chef::Checksum.create_design_document
76
+
77
+ # Create the signing key and certificate
78
+ Chef::Certificate.generate_signing_ca
79
+
80
+ # Generate the validation key
81
+ Chef::Certificate.gen_validation_key
82
+
83
+ # Generate the Web UI Key
84
+ Chef::Certificate.gen_validation_key(Chef::Config[:web_ui_client_name], Chef::Config[:web_ui_key], true)
85
+
86
+ Chef::Log.info('Loading roles')
87
+ Chef::Role.sync_from_disk_to_couchdb
88
+ end
data/config/rack.rb ADDED
@@ -0,0 +1,5 @@
1
+ # Correctly set a content length.
2
+ use Rack::ContentLength
3
+
4
+ # this is our main merb application
5
+ run Merb::Rack::Application.new
data/config/router.rb CHANGED
@@ -1,6 +1,82 @@
1
- # This file is here so slice can be testing as a stand alone application.
1
+ Merb::Router.prepare do
2
+ resources :users
2
3
 
3
- #Merb::Router.prepare do
4
- # resources :roles
5
- # ...
6
- #end
4
+ # Nodes
5
+ resources :nodes, :id => /[^\/]+/
6
+ match('/nodes/:id/cookbooks',
7
+ :id => /[^\/]+/,
8
+ :method => 'get').
9
+ to(:controller => "nodes", :action => "cookbooks")
10
+ # Roles
11
+ resources :roles
12
+
13
+ # Status
14
+ match("/status").to(:controller => "status", :action => "index").name(:status)
15
+
16
+ # Clients
17
+ match("/clients", :method=>"post").to(:controller=>'clients', :action=>'create')
18
+ match("/clients", :method=>"get").to(:controller=>'clients', :action=>'index').name(:clients)
19
+ match("/clients/:id", :id => /[\w\.-]+/, :method=>"get").to(:controller=>'clients', :action=>'show').name(:client)
20
+ match("/clients/:id", :id => /[\w\.-]+/, :method=>"put").to(:controller=>'clients', :action=>'update')
21
+ match("/clients/:id", :id => /[\w\.-]+/, :method=>"delete").to(:controller=>'clients', :action=>'destroy')
22
+
23
+ # Search
24
+ resources :search
25
+ match('/search/reindex', :method => 'post').to(:controller => "search", :action => "reindex")
26
+
27
+ # Cookbooks
28
+ match('/nodes/:id/cookbooks', :method => 'get').to(:controller => "nodes", :action => "cookbooks")
29
+
30
+ match("/cookbooks",
31
+ :method => 'get'
32
+ ).to(:controller => "cookbooks", :action => "index")
33
+
34
+ match("/cookbooks/:cookbook_name/:cookbook_version",
35
+ :method => 'put',
36
+ :cookbook_name => /[\w\.]+/,
37
+ :cookbook_version => /\d+\.\d+\.\d+/
38
+ ).to(:controller => "cookbooks", :action => "update")
39
+
40
+ match("/cookbooks/:cookbook_name/:cookbook_version",
41
+ :method => 'get',
42
+ :cookbook_name => /[\w\.]+/,
43
+ :cookbook_version => /(\d+\.\d+\.\d+|_latest)/
44
+ ).to(:controller => "cookbooks", :action => "show")
45
+
46
+ match("/cookbooks/:cookbook_name/:cookbook_version",
47
+ :method => 'delete',
48
+ :cookbook_name => /[\w\.]+/,
49
+ :cookbook_version => /(\d+\.\d+\.\d+|_latest)/
50
+ ).to(:controller => "cookbooks", :action => "destroy")
51
+
52
+ match("/cookbooks/:cookbook_name",
53
+ :method => 'get',
54
+ :cookbook_name => /[\w\.]+/
55
+ ).to(:controller => "cookbooks", :action => "show_versions").name(:cookbook)
56
+
57
+ match("/cookbooks/:cookbook_name/:cookbook_version/files/:checksum",
58
+ :cookbook_name => /[\w\.]+/,
59
+ :cookbook_version => /(\d+\.\d+\.\d+|_latest)/
60
+ ).to(
61
+ :controller => "cookbooks",
62
+ :action => "show_file"
63
+ ).name(:cookbook_file)
64
+
65
+ # Sandbox
66
+ match('/sandboxes', :method => 'get').to(:controller => "sandboxes", :action => "index").name(:sandboxes)
67
+ match('/sandboxes', :method => 'post').to(:controller => "sandboxes", :action => "create")
68
+ match('/sandboxes/:sandbox_id', :method => 'get', :sandbox_id => /[\w\.]+/).to(:controller => "sandboxes", :action => "show").name(:sandbox)
69
+ match('/sandboxes/:sandbox_id', :method => 'put', :sandbox_id => /[\w\.]+/).to(:controller => "sandboxes", :action => "update")
70
+ match('/sandboxes/:sandbox_id/:checksum', :method => 'put', :sandbox_id => /[\w\.]+/, :checksum => /[\w\.]+/).to(:controller => "sandboxes", :action => "upload_checksum").name(:sandbox_checksum)
71
+ match('/sandboxes/:sandbox_id/:checksum', :method => 'get', :sandbox_id => /[\w\.]+/, :checksum => /[\w\.]+/).to(:controller => "sandboxes", :action => "download_checksum")
72
+
73
+ # Data
74
+ match("/data/:data_bag_id/:id", :method => 'get').to(:controller => "data_item", :action => "show").name("data_bag_item")
75
+ match("/data/:data_bag_id", :method => 'post').to(:controller => "data_item", :action => "create").name("create_data_bag_item")
76
+ match("/data/:data_bag_id/:id", :method => 'put').to(:controller => "data_item", :action => "update").name("update_data_bag_item")
77
+ match("/data/:data_bag_id/:id", :method => 'delete').to(:controller => "data_item", :action => "destroy").name("destroy_data_bag_item")
78
+ resources :data, :controller => "data_bags"
79
+
80
+ match('/').to(:controller => 'main', :action =>'index').name(:top)
81
+
82
+ end