chef-server-api 0.8.16 → 0.9.0.a3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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