Skip to content

Commit

Permalink
Merge pull request #20 from marianitadn/add-command-to-add-new-resource
Browse files Browse the repository at this point in the history
Add hammer command to represent a new resource as a JSON file in the Git repo
  • Loading branch information
maria committed Nov 23, 2014
2 parents b0e1b9a + 6fffeeb commit e994b4c
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 27 deletions.
9 changes: 7 additions & 2 deletions lib/foreman/api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ def initialize(settings)
# Returns a hash
# {:resource_name => array_of_resources_downloaded}
def download_resources(resources=nil)

resources = get_resources_to_download(resources)
foreman_resources = Hash.new

Expand All @@ -47,7 +46,13 @@ def download_resources(resources=nil)

def call_action(name, action, data)
name = name.to_sym if name.is_a? String
action = action.to_sym if action.is_a? String

if action.is_a? String
action = action.to_sym
elsif action.is_a? Array
action = action[0].to_sym
end

@api.call(name, action, data)
end

Expand Down
1 change: 1 addition & 0 deletions lib/hammer_cli_foregit.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module HammerCLIForegit

require 'foregit'
require 'hammer_cli_foregit/add'
require 'hammer_cli_foregit/pull'
require 'hammer_cli_foregit/push'
require 'hammer_cli_foregit/abstract_command'
Expand Down
33 changes: 33 additions & 0 deletions lib/hammer_cli_foregit/add.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
require 'hammer_cli_foregit/abstract_command'

module HammerCLIForegit

class Add < HammerCLIForegit::AbstractCommand

option ['-r', '--resource'], 'RESOURCE', 'The Foreman resource type',
:format => String
option ['-f', '--file'], 'FILE', 'A JSON or YAML file to define resource attributes',
:format => HammerCLI::Options::Normalizers::JSONInput.new
option ['-a', '--attributes'], 'ATTRIBUTES', 'A string of resource attributes described as key=value pairs, ex: -a "name=i382,hosts=[]"',
:format => HammerCLI::Options::Normalizers::KeyValueList.new

validate_options do
option(:option_resource).required
any(:option_file, :option_attributes).required
end

def execute
super
puts "Creating JSON representation of #{option_resource} resource in Git repo..."
@talk.add option_resource, option_file || option_attributes
@git_manager.commit("Sync #{option_resource}.")
puts 'Done!'
HammerCLI::EX_OK
end
end

end

HammerCLI::MainCommand.subcommand 'add',
'Create a new JSON file in the Git repository for a specific resource, where its attributes are set from a file or key=value pairs',
HammerCLIForegit::Add
2 changes: 1 addition & 1 deletion lib/hammer_cli_foregit/pull.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def execute
super
puts "Sync from Foreman #{option_resources || 'all'} resources to Git repository..."
@talk.pull option_resources
@git_manager.commit("Sync #{option_resources || 'all'} resources")
@git_manager.commit("Sync #{option_resources || 'all'} resources.")
puts 'Done!'
HammerCLI::EX_OK
end
Expand Down
6 changes: 6 additions & 0 deletions lib/hammer_cli_foregit/push.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ def execute
super
puts "Syncing from Git repository #{option_resources || 'all'} resources to Foreman..."
@talk.push option_resources

tag = Time.now.to_i.to_s
@git_manager.commit("Sync #{option_resources}. Tag: #{tag}")
@git_manager.git.add_tag(tag)
puts("Tagged repository with #{tag}.")

puts 'Done!'
HammerCLI::EX_OK
end
Expand Down
53 changes: 34 additions & 19 deletions lib/talk_commands.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
- download(settings[resources])
- file manager
=end
require 'active_support/inflector'
require 'json'

require 'file_manager'
require 'git_manager'
Expand All @@ -24,16 +26,9 @@ def initialize(settings, binding=nil, file_manager=nil, git_manager=nil)
# Download resources from Foreman and save them as files in the Git repo
def pull(foreman_resources=nil)
resources = @binding.download_resources(foreman_resources)

resources.each do |resource_type, resources_content|
resources_content.each do |resource_content|

resource = {:type => resource_type.to_s,
:name => "#{resource_content["id"].to_s}_#{resource_content["name"].to_s}",
:content => resource_content
}

@file_manager.dump_object_as_file(resource)
dump_resource_as_file(resource_type, resource_content)
end
end
end
Expand Down Expand Up @@ -67,24 +62,44 @@ def push(foreman_resources=nil)
data = @file_manager.load_file_as_json(change[:file])
end

begin
puts("#{resource_action.capitalize} #{resource_type} with #{data}...")
@binding.call_action(resource_type, resource_action, data)
rescue Exception => e
puts "Error while calling action to Foreman: #{e}."
call_action_for_resource_content(resource_type, resource_action, data)
end
end

# Create resource in Foreman with the given configuration.
# Pull changes in theGit repository after.
def add resource_type, attributes

if attributes.has_key? "id"
if !@binding.call_action(resource_type, :show, {:id => attributes["id"]}).nil?
puts "Resource with given id #{attributes["id"]} exists. Update attribute or remove it."
return
end
end

puts "Changes were synced."
tag = Time.now.to_i.to_s
@git_manager.commit("Commit existent changes. Tag: #{tag}")
@git_manager.git.add_tag(tag)
puts("Tagged repository with #{tag}.")

call_action_for_resource_content(resource_type, :create, {ActiveSupport::Inflector.singularize(resource_type) => attributes})
pull resource_type
end

private

def call_action_for_resource_content(resource_type, resource_action, data)
begin
puts("#{resource_action.capitalize} #{resource_type} with #{data}...")
@binding.call_action(resource_type, resource_action, data)
rescue Exception => e
puts "Error while calling action to Foreman: #{e}."
return
end
end

def dump_resource_as_file(resource_type, resource_content)
parsed_resource = {:type => resource_type.to_s,
:name => "#{resource_content['id']}_#{resource_content['name']}",
:content => resource_content}
@file_manager.dump_object_as_file(parsed_resource)
end

def get_action_based_on_change(type)
if type == 'D'
return :destroy
Expand Down
9 changes: 4 additions & 5 deletions spec/unit/file_manager_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@

context 'dumping a valid JSON in an existent file' do

it 'the file should contain the resource content' do
it 'should contain the resource content' do
file = 'test.json'
file_path = File.join(@repo_path, file)
File.open(file_path, 'w') {}
Expand All @@ -95,14 +95,14 @@
}

@manager.dump_object_as_file(resource, file)
expect(File.read(file_path)).to match(resource[:content].to_json)
expect(JSON.parse(File.read(file_path))).to match(JSON.parse(resource[:content].to_json))

end
end

context 'dumping a valid JSON in an inexistent file' do

it 'the file should contain the resource content after is created' do
it 'should contain the resource content after is created' do
architectures = build(:architectures)
resource = {
:type => 'architectures',
Expand All @@ -112,8 +112,7 @@

@manager.dump_object_as_file(resource)
file_path = @manager.find_file('architectures/' + architectures.name + '.json')

expect(File.read(file_path)).to match(resource[:content].to_json)
expect(JSON.parse(File.read(file_path))).to match(JSON.parse(resource[:content].to_json))

end
end
Expand Down

0 comments on commit e994b4c

Please sign in to comment.