katello-foreman-engine 0.0.1

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.
data/Rakefile ADDED
@@ -0,0 +1,90 @@
1
+ ENGINE_DIR = File.expand_path('..', __FILE__)
2
+ KATELLO_DIR = 'test/katello_app'
3
+ require 'fileutils'
4
+
5
+ namespace :test do
6
+ desc "Download latest katello devel source and install dependencies"
7
+ task :katello_prepare do
8
+ katello_repo = 'https://github.com/Katello/katello.git'
9
+ katello_gemfile = File.join(KATELLO_DIR, "Gemfile")
10
+ unless File.exists?(katello_gemfile)
11
+ puts "Katello source code is not present at #{KATELLO_DIR}"
12
+ puts "Downloading latest Katello development branch into #{KATELLO_DIR}..."
13
+ FileUtils.mkdir_p(KATELLO_DIR)
14
+
15
+ unless system("git clone #{katello_repo} #{KATELLO_DIR}")
16
+ puts "Error while getting latest Katello code from #{katello_repo} into #{KATELLO_DIR}"
17
+ fail
18
+ end
19
+ end
20
+
21
+ gemfile_content = File.read(katello_gemfile)
22
+ unless gemfile_content.include?('KATELLO_GEMFILE')
23
+ puts 'Preparing Gemfile'
24
+ gemfile_content.gsub!('__FILE__', 'KATELLO_GEMFILE')
25
+ gemfile_content.insert(0, "KATELLO_GEMFILE = __FILE__ unless defined? KATELLO_GEMFILE\n")
26
+ File.open(katello_gemfile, 'w') { |f| f << gemfile_content }
27
+ end
28
+
29
+ settings_file = "#{KATELLO_DIR}/config/katello.yml"
30
+ unless File.exists?(settings_file)
31
+ puts 'Preparing settings file'
32
+ File.open(settings_file, "w") { |f| f << <<SETTINGS }
33
+ common:
34
+ foreman:
35
+ url: https://localhost/foreman/
36
+
37
+ SETTINGS
38
+ end
39
+
40
+ ["#{ENGINE_DIR}/.bundle/config", "#{KATELLO_DIR}/.bundle/config"].each do |bundle_file|
41
+ unless File.exists?(bundle_file)
42
+ FileUtils.mkdir_p(File.dirname(bundle_file))
43
+ puts 'Preparing bundler configuration'
44
+ File.open(bundle_file, 'w') { |f| f << <<FILE }
45
+ BUNDLE_WITHOUT: assets:checking:debugging:development_boost:optional
46
+ FILE
47
+ end
48
+ end
49
+
50
+ puts 'Installing dependencies...'
51
+ unless system('bundle install')
52
+ fail
53
+ end
54
+ end
55
+
56
+ task :db_prepare do
57
+ unless File.exists?(KATELLO_DIR)
58
+ puts <<MESSAGE
59
+ Katello source code not prepared. Run
60
+
61
+ rake test:katello_prepare
62
+
63
+ to download katello source and its dependencies
64
+ MESSAGE
65
+ fail
66
+ end
67
+
68
+ # once we are Ruby19 only, switch to block variant of cd
69
+ pwd = FileUtils.pwd
70
+ FileUtils.cd(KATELLO_DIR)
71
+ unless system('rake db:test:prepare RAILS_ENV=test')
72
+ puts "Migrating database first"
73
+ system('rake db:create db:migrate db:schema:dump db:test:prepare RAILS_ENV=test') || fail
74
+ end
75
+ FileUtils.cd(pwd)
76
+ end
77
+
78
+ task :set_loadpath do
79
+ %w[lib test].each do |dir|
80
+ $:.unshift(File.expand_path(dir, ENGINE_DIR))
81
+ end
82
+ end
83
+
84
+ task :all => [:db_prepare, :set_loadpath] do
85
+ Dir.glob('test/**/*_test.rb') { |f| require f.sub('test/','') unless f.include? '/katello_app/' }
86
+ end
87
+
88
+ end
89
+
90
+ task :test => 'test:all'
@@ -0,0 +1,17 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = "katello-foreman-engine"
3
+ s.version = "0.0.1"
4
+
5
+ s.authors = ["Katello"]
6
+ s.date = "2013-04-19"
7
+ s.description = "Foreman specific parts in Katello"
8
+ s.email = "katello-devel@redhat.com"
9
+ s.files = `git ls-files`.split("\n")
10
+ s.homepage = "http://github.com/katello/katello-foreman-engine"
11
+ s.licenses = ["GPL-2"]
12
+ s.require_paths = ["lib"]
13
+ s.add_dependency "foreman_api"
14
+ s.add_dependency "deface", "~> 0.7.2"
15
+ s.add_dependency "dynflow"
16
+ s.summary = "Foreman specific parts of Katello"
17
+ end
@@ -0,0 +1,2 @@
1
+ require 'deface'
2
+ require 'katello_foreman_engine'
@@ -0,0 +1,25 @@
1
+ module KatelloForemanEngine
2
+ module Actions
3
+ class ContentViewDemote < Dynflow::Action
4
+
5
+ def self.subscribe
6
+ Katello::Actions::ContentViewDemote
7
+ end
8
+
9
+ def plan(content_view, from_env)
10
+ if foreman_env = Bindings.environment_find(content_view.organization.label,
11
+ from_env.label, content_view.label)
12
+ plan_self 'foreman_env_id' => foreman_env['environment']['id']
13
+ end
14
+ end
15
+
16
+ input_format do
17
+ param :foreman_env_id, Integer
18
+ end
19
+
20
+ def run
21
+ Bindings.environment_destroy(input['foreman_env_id'])
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,28 @@
1
+ module KatelloForemanEngine
2
+ module Actions
3
+ class ContentViewPromote < Dynflow::Action
4
+
5
+ def self.subscribe
6
+ Katello::Actions::ContentViewPromote
7
+ end
8
+
9
+ def plan(*args)
10
+ unless Bindings.environment_find(input['organization_label'], input['to_env_label'], input['label'])
11
+ plan_self input
12
+ end
13
+ end
14
+
15
+ input_format do
16
+ param :id, Integer
17
+ param :label, String
18
+ param :organization_label, String
19
+ param :from_env_label, String
20
+ param :to_env_label, String
21
+ end
22
+
23
+ def run
24
+ Bindings.environment_create(input['id'], input['organization_label'], input['to_env_label'], input['label'])
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,26 @@
1
+ module KatelloForemanEngine
2
+ module Actions
3
+ class EnvironmentCreate < Dynflow::Action
4
+
5
+ def self.subscribe
6
+ Katello::Actions::EnvironmentCreate
7
+ end
8
+
9
+ def plan(env)
10
+ unless env.library?
11
+ plan_self 'org_label' => env.organization.label, 'label' => env.label, 'content_view_id' => 'env'
12
+ end
13
+ end
14
+
15
+ input_format do
16
+ param :org_label, String
17
+ param :label, String
18
+ param :content_view_id, String
19
+ end
20
+
21
+ def run
22
+ Bindings.environment_create(input['content_view_id'], input['org_label'], input['label'])
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ module KatelloForemanEngine
2
+ module Actions
3
+ class EnvironmentDestroy < Dynflow::Action
4
+
5
+ input_format do
6
+ param :foreman_id, String
7
+ end
8
+
9
+ def self.subscribe
10
+ Katello::Actions::EnvironmentDestroy
11
+ end
12
+
13
+ def plan(env)
14
+ if !env.library? && foreman_env = Bindings.environment_find(env.organization.label, env.label)
15
+ env.content_views.each do |content_view|
16
+ plan_action(ContentViewDemote, content_view, env)
17
+ end
18
+ plan_self 'foreman_id' => foreman_env['environment']['id']
19
+ end
20
+ end
21
+
22
+ def run
23
+ Bindings.environment_destroy(input['foreman_id'])
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,14 @@
1
+ module KatelloForemanEngine
2
+ module Actions
3
+ class OrgCreate < Dynflow::Action
4
+
5
+ def self.subscribe
6
+ Headpin::Actions::OrgCreate
7
+ end
8
+
9
+ def run
10
+ Bindings.organization_create("KT-[#{input['label']}]")
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,24 @@
1
+ module KatelloForemanEngine
2
+ module Actions
3
+ class OrgDestroy < Dynflow::Action
4
+
5
+ input_format do
6
+ param :foreman_id, String
7
+ end
8
+
9
+ def self.subscribe
10
+ Headpin::Actions::OrgDestroy
11
+ end
12
+
13
+ def plan(org)
14
+ if foreman_org = Bindings.organization_find("KT-[#{input['label']}]")
15
+ plan_self('foreman_id' => foreman_org['organization']['id'])
16
+ end
17
+ end
18
+
19
+ def run
20
+ Bindings.organization_destroy(input['foreman_id'])
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ module KatelloForemanEngine
2
+ module Actions
3
+ class UserCreate < Dynflow::Action
4
+
5
+ def self.subscribe
6
+ Headpin::Actions::UserCreate
7
+ end
8
+
9
+ def plan(user)
10
+ if !user.hidden? && !Bindings.user_find(input['username'])
11
+ plan_self input
12
+ end
13
+ end
14
+
15
+ def run
16
+ Bindings.user_create(input['username'], input['email'])
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,24 @@
1
+ module KatelloForemanEngine
2
+ module Actions
3
+ class UserDestroy < Dynflow::Action
4
+
5
+ def self.subscribe
6
+ Headpin::Actions::UserDestroy
7
+ end
8
+
9
+ def plan(user)
10
+ if foreman_user = Bindings.user_find(input['username'])
11
+ plan_self 'foreman_user_id' => foreman_user['user']['id']
12
+ end
13
+ end
14
+
15
+ input_format do
16
+ param :foreman_user_id, String
17
+ end
18
+
19
+ def run
20
+ Bindings.user_destroy(input['foreman_user_id'])
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,101 @@
1
+ require 'foreman_api'
2
+
3
+ module KatelloForemanEngine
4
+ module Bindings
5
+
6
+ class << self
7
+
8
+ def client_config
9
+ {
10
+ :base_url => Settings['foreman_url'],
11
+ :enable_validations => false,
12
+ :oauth => {
13
+ :consumer_key => Settings['oauth_consumer_key'],
14
+ :consumer_secret => Settings['oauth_consumer_secret']
15
+ },
16
+ }
17
+ end
18
+
19
+ def base
20
+ resource(ForemanApi::Base)
21
+ end
22
+
23
+ def environment
24
+ resource(ForemanApi::Resources::Environment)
25
+ end
26
+
27
+ def user(username = nil)
28
+ user_resource = resource(ForemanApi::Resources::User)
29
+ if username && User.current.username == username
30
+ # this means the first user is created: use the predefined
31
+ # Foreman admin user for this cases.
32
+ user_resource.client.options[:headers][:foreman_user] = 'admin'
33
+ end
34
+ return user_resource
35
+ end
36
+
37
+ def resource(resource_class)
38
+ client = resource_class.new(client_config)
39
+ client.client.options[:headers][:foreman_user] = User.current.username
40
+ return client
41
+ end
42
+
43
+ def organization_find(name)
44
+ orgs, _ = base.http_call('get', '/api/organizations', 'search' => "name = #{name}")
45
+ return orgs.first
46
+ end
47
+
48
+ def organization_create(name)
49
+ base.http_call('post', '/api/organizations',
50
+ :organization => {:name => name,
51
+ :ignore_types => %w[User SmartProxy Subnet ComputeResource Medium ConfigTemplate Domain Environment] })
52
+ end
53
+
54
+ def organization_destroy(id)
55
+ base.http_call('delete', "/api/organizations/#{id}")
56
+ end
57
+
58
+
59
+ def environment_find(org_label, env_label, content_view_label = nil)
60
+ env, _ = base.http_call('get', '/foreman_katello_engine/api/environments/show',
61
+ {:org => org_label, :env => env_label, :content_view => content_view_label})
62
+ return env
63
+ rescue RestClient::ResourceNotFound => e
64
+ return nil
65
+ end
66
+
67
+ def environment_create(content_view_id, org_label, env_label, content_view_label = nil)
68
+ params = {:org => org_label, :env => env_label, :content_view => content_view_label, :content_view_id => content_view_id}
69
+ if foreman_org = organization_find("KT-[#{org_label}]")
70
+ params[:org_id] = foreman_org['organization']['id']
71
+ end
72
+ base.http_call('post', '/foreman_katello_engine/api/environments', params)
73
+ end
74
+
75
+ def environment_destroy(id)
76
+ environment.destroy('id' => id)
77
+ end
78
+
79
+ def user_find(username)
80
+ users, _ = user(username).index('search' => "login = #{username}")
81
+ return users.first
82
+ end
83
+
84
+ def user_create(username, email)
85
+ user(username).create({ 'user' => {
86
+ 'login' => username,
87
+ 'mail' => email,
88
+ 'password' => Password.generate_random_string(25),
89
+ 'auth_source_id' => 1}})
90
+ end
91
+
92
+ def user_destroy(id)
93
+ user.destroy('id' => id)
94
+ end
95
+
96
+ end
97
+ end
98
+
99
+ end
100
+
101
+
@@ -0,0 +1,14 @@
1
+ module KatelloForemanEngine
2
+ #Inherit from the Rails module of the parent app (Foreman), not the plugin.
3
+ #Thus, inhereits from ::Rails::Engine and not from Rails::Engine
4
+ class Engine < ::Rails::Engine
5
+
6
+ config.after_initialize do
7
+ require 'katello_foreman_engine/settings'
8
+ Settings.initialize_settings
9
+ require 'katello_foreman_engine/bindings'
10
+ Dir[File.expand_path('../actions/*.rb', __FILE__)].each { |f| require f }
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,21 @@
1
+ module KatelloForemanEngine
2
+ class Settings
3
+
4
+ def self.initialize_settings
5
+ @settings = {
6
+ 'foreman_url' => Katello.config.foreman.url.sub(/\/+\Z/,''),
7
+ 'oauth_consumer_key' => Katello.config.foreman.oauth_key,
8
+ 'oauth_consumer_secret' => Katello.config.foreman.oauth_secret
9
+ }
10
+ end
11
+
12
+ def self.[](key)
13
+ @settings[key.to_s]
14
+ end
15
+
16
+ def self.[]=(key, value)
17
+ @settings[key.to_s] = value
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,5 @@
1
+ module KatelloForemanEngine
2
+ if defined?(Rails) && Rails::VERSION::MAJOR == 3
3
+ require 'katello_foreman_engine/engine'
4
+ end
5
+ end
data/script/rails ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
5
+ ENGINE_PATH = File.expand_path('../../lib/os_preference/engine', __FILE__)
6
+
7
+ require 'rails/all'
8
+ require 'rails/engine/commands'
@@ -0,0 +1,32 @@
1
+ require 'test_helper'
2
+
3
+ module KatelloForemanEngine
4
+ module Actions
5
+ class EnvCreateTest < ActiveSupport::TestCase
6
+
7
+ test "doesn't run for library" do
8
+ org = Organization.new(:label => 'org')
9
+ env = KTEnvironment.new(:label => 'dev')
10
+ env.organization = org
11
+
12
+ env.library = false
13
+ plan = prepare_plan(EnvCreate, {}, env)
14
+ step = plan.run_steps.first
15
+ assert_equal EnvCreate, step.action_class
16
+ assert_equal step.input['org_label'], 'org'
17
+ assert_equal step.input['label'], 'dev'
18
+ assert_equal step.input['cv_id'], 'env'
19
+
20
+ env.library = true
21
+ plan = prepare_plan(EnvCreate, {}, env)
22
+ assert_equal [], plan.run_steps
23
+ end
24
+
25
+ test 'calls bindings to create environment' do
26
+ Bindings.expects(:environment_create).with('env', 'org', 'dev')
27
+ EnvCreate.new('org_label' => 'org', 'label' => 'dev', 'cv_id' => 'env').run
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,38 @@
1
+ require 'test_helper'
2
+
3
+ module KatelloForemanEngine
4
+ module Actions
5
+ class EnvDestroyTest < ActiveSupport::TestCase
6
+
7
+ test "runs only when the env is present in Foreman and it's not library" do
8
+ org = Organization.new(:label => 'org')
9
+ env = KTEnvironment.new(:label => 'dev')
10
+ env.organization = org
11
+
12
+ foreman_env = { 'environment' => { 'id' => '123' } }
13
+ Bindings.expects(:environment_find).with('org', 'dev').returns(foreman_env)
14
+
15
+ env.library = false
16
+ plan = prepare_plan(EnvDestroy,{}, env)
17
+ step = plan.run_steps.first
18
+ assert_equal EnvDestroy, step.action_class
19
+ assert_equal step.input['foreman_id'], '123'
20
+
21
+ env.library = true
22
+ plan = prepare_plan(EnvDestroy, {}, env)
23
+ assert_equal [], plan.run_steps
24
+
25
+ env.library = false
26
+ Bindings.expects(:environment_find).returns(nil)
27
+ plan = prepare_plan(EnvDestroy, {}, env)
28
+ assert_equal [], plan.run_steps
29
+ end
30
+
31
+ test 'calls bindings to destroy environment' do
32
+ Bindings.expects(:environment_destroy).with('123')
33
+ EnvDestroy.new('foreman_id' => '123').run
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,14 @@
1
+ require 'test_helper'
2
+
3
+ module KatelloForemanEngine
4
+ module Actions
5
+ class OrgCreateTest < ActiveSupport::TestCase
6
+
7
+ test 'calls bindings to create organization' do
8
+ Bindings.expects(:organization_create). with('KT-[ACME]')
9
+ OrgCreate.new('label' => 'ACME').run
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,27 @@
1
+ require 'test_helper'
2
+
3
+ module KatelloForemanEngine
4
+ module Actions
5
+ class OrgDestroyTest < ActiveSupport::TestCase
6
+
7
+ test "runs only when the org is present in Foreman" do
8
+ foreman_org = { 'organization' => { 'id' => '123' } }
9
+ Bindings.expects(:organization_find).with('KT-[test]').returns(foreman_org)
10
+ plan = prepare_plan(OrgDestroy, {'label' => 'test'}, nil)
11
+ step = plan.run_steps.first
12
+ assert_equal OrgDestroy, step.action_class
13
+ assert_equal step.input['foreman_id'], '123'
14
+
15
+ Bindings.expects(:organization_find).returns(nil)
16
+ plan = prepare_plan(OrgDestroy, {'label' => 'test'}, nil)
17
+ assert_equal [], plan.run_steps
18
+ end
19
+
20
+ test 'calls bindings to destroy organization' do
21
+ Bindings.expects(:organization_destroy).with('123')
22
+ OrgDestroy.new('foreman_id' => '123').run
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ require 'test_helper'
2
+ require 'mocha/setup'
3
+
4
+ class BindingsTest < ActiveSupport::TestCase
5
+
6
+ def setup
7
+ KatelloForemanEngine::Settings.initialize_settings
8
+ end
9
+
10
+ test 'client lib setting' do
11
+ KatelloForemanEngine::Settings['foreman_url'] = 'https://example.com/foreman'
12
+ KatelloForemanEngine::Settings['oauth_consumer_key'] = 'key'
13
+ KatelloForemanEngine::Settings['oauth_consumer_secret'] = 'secret'
14
+ User.current = User.new(:username => 'test')
15
+ env_resource = KatelloForemanEngine::Bindings.environment
16
+ config = env_resource.config
17
+ assert_equal 'https://example.com/foreman', config[:base_url]
18
+ assert_equal 'key', config[:oauth][:consumer_key]
19
+ assert_equal 'secret', config[:oauth][:consumer_secret]
20
+ assert_equal 'test', env_resource.client.options[:headers][:foreman_user]
21
+ end
22
+
23
+ end
@@ -0,0 +1,10 @@
1
+ require 'test_helper'
2
+
3
+ class SettingsTest < ActiveSupport::TestCase
4
+
5
+ test "katello specific settings" do
6
+ KatelloForemanEngine::Settings.initialize_settings
7
+ assert_equal 'https://localhost/foreman', KatelloForemanEngine::Settings['foreman_url']
8
+ end
9
+
10
+ end
@@ -0,0 +1,20 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ ENV["RAILS_ENV"] ||= 'test'
5
+ require File.join("katello_app/config/environment.rb")
6
+
7
+ require 'test/unit'
8
+ require 'katello-foreman-engine'
9
+ require 'rails/test_help'
10
+ require 'mocha/setup'
11
+
12
+ Rails.backtrace_cleaner.remove_silencers!
13
+
14
+ # returns the execution plan for given action, given
15
+ # input from parent action and *args for plan method
16
+ def prepare_plan(action_class, input, *args)
17
+ action = action_class.new(input)
18
+ action.plan(*args)
19
+ return action.execution_plan
20
+ end