-
Notifications
You must be signed in to change notification settings - Fork 40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add onesecgroup provider #179
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
# Opennebula onesecgroup provider for Security Groups | ||
# | ||
# License: APLv2 | ||
# | ||
# Authors: | ||
# Based upon initial work from Ken Barber | ||
# Modified by Martin Alfke | ||
# | ||
# Copyright | ||
# initial provider had no copyright | ||
# Deutsche Post E-POST Development GmbH - 2014, 2015 | ||
# | ||
|
||
require 'rubygems' | ||
require 'nokogiri' | ||
|
||
Puppet::Type.type(:onesecgroup).provide(:cli) do | ||
desc "onesecgroup provider" | ||
|
||
has_command(:onesecgroup, "onesecgroup") do | ||
environment :HOME => '/root', :ONE_AUTH => '/var/lib/one/.one/one_auth' | ||
end | ||
|
||
mk_resource_methods | ||
|
||
# Create a security group with onesecgroup by passing in a temporary secgroup definition file. | ||
def create | ||
file = Tempfile.new("onesecgroup-#{resource[:name]}-create.xml") | ||
builder = Nokogiri::XML::Builder.new do |xml| | ||
xml.TEMPLATE do | ||
xml.NAME resource[:name] | ||
xml.DESCRIPTION resource[:description] | ||
resource[:rules].each do |rule| | ||
xml.RULE do | ||
rule.each do |k, v| | ||
xml.send(k.upcase, v) | ||
end | ||
end | ||
end if resource[:rules] | ||
end | ||
end | ||
tempfile = builder.to_xml | ||
file.write(tempfile) | ||
file.close | ||
self.debug "Creating secgroup using #{tempfile}" | ||
onesecgroup('create', file.path) | ||
file.delete | ||
@property_hash[:ensure] = :present | ||
end | ||
|
||
# Delete a secgroup using onesecgroup delete | ||
def destroy | ||
onesecgroup('delete', resource[:name]) | ||
@property_hash.clear | ||
end | ||
|
||
# Check if a secgroup exists by scanning the onesecgroup list | ||
def exists? | ||
@property_hash[:ensure] == :present | ||
end | ||
|
||
# Return the full hash of all existing secgroups | ||
def self.instances | ||
secgroups = Nokogiri::XML(onesecgroup('list', '-x')).root.xpath('/SECURITY_GROUP_POOL/SECURITY_GROUP') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please check whether the following command works and delivers expected results: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that does return correctly: [oneadmin@vagrant-one ~]$ puppet resource onesecgroup --modulepath /vagrant/modules |
||
secgroups.collect do |secgroup| | ||
rules=[] | ||
secgroup.xpath('./TEMPLATE/RULE').collect do |rule| | ||
ruleitems={} | ||
rule.xpath('*').collect do |item| | ||
ruleitems[item.name.downcase] = item.text.upcase | ||
end | ||
rules << ruleitems | ||
end | ||
new( | ||
:name => secgroup.xpath('./NAME').text, | ||
:ensure => :present, | ||
:description => secgroup.xpath('./TEMPLATE/DESCRIPTION').text, | ||
:rules => rules | ||
) | ||
end | ||
end | ||
|
||
def self.prefetch(resources) | ||
secgroups = instances | ||
resources.keys.each do |name| | ||
if provider = secgroups.find{ |secgroup| secgroup.name == name } | ||
resources[name].provider = provider | ||
end | ||
end | ||
end | ||
|
||
# Write out changes to a security group with onesecgroup update | ||
def flush | ||
file = Tempfile.new("onesecgroup-#{resource[:name]}-update.xml") | ||
builder = Nokogiri::XML::Builder.new do |xml| | ||
xml.TEMPLATE do | ||
xml.DESCRIPTION resource[:description] | ||
resource[:rules].each do |rule| | ||
xml.RULE do | ||
rule.each do |k, v| | ||
xml.send(k.upcase, v) | ||
end | ||
end | ||
end if resource[:rules] | ||
end | ||
end | ||
tempfile = builder.to_xml | ||
file.write(tempfile) | ||
file.close | ||
self.debug "Updating secgroup using #{tempfile}" | ||
onesecgroup('update', resource[:name], file.path) unless @property_hash.empty? | ||
file.delete | ||
end | ||
|
||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# Opennebula onesecgroup type for Security Groups | ||
# | ||
# License: APLv2 | ||
# | ||
# Authors: | ||
# Based upon initial work from Ken Barber | ||
# Modified by Martin Alfke | ||
# | ||
# Copyright | ||
# initial provider had no copyright | ||
# Deutsche Post E-POST Development GmbH - 2014, 2015 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. author and copyright? |
||
# | ||
|
||
Puppet::Type.newtype(:onesecgroup) do | ||
@doc = "Type for managing security groups in OpenNebula using the" + | ||
"onesecgroup wrapper command." | ||
|
||
ensurable | ||
|
||
# Capacity Section | ||
newparam(:name, :namevar => true) do | ||
desc "Name of security group." | ||
validate do |value| | ||
fail("Invalid name: #{value}") unless value =~ /^([A-Za-z]).*/ | ||
end | ||
end | ||
|
||
newproperty(:description) do | ||
desc "Description of the security group." | ||
validate do |value| | ||
fail("Invalid description: #{value}") unless value =~ /^([A-Za-z]).*/ | ||
end | ||
end | ||
|
||
newproperty(:rules, :array_matching => :all) do | ||
desc "An array of hashes, each defining a rule for the security group." | ||
defaultto [] | ||
validate do |value| | ||
if value.is_a?( Hash) | ||
# TODO: validate each key | ||
valid_keys = [ | ||
'protocol', | ||
'rule_type', | ||
'ip', | ||
'size', | ||
'range', | ||
'icmp_type', | ||
] | ||
fail "#{(value.keys - valid_keys).join(' and ')} is not one of #{valid_keys.join(' or ')}" unless (value.keys - valid_keys).empty? | ||
end | ||
end | ||
munge do |value| | ||
if ! value.is_a?(Hash) | ||
fail 'each rule should be a hash' | ||
else | ||
value | ||
end | ||
end | ||
end | ||
|
||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
require 'spec_helper_acceptance' | ||
|
||
describe 'onesecgroup type' do | ||
before :all do | ||
pp =<<-EOS | ||
class { 'one': | ||
oned => true, | ||
one_version => '4.12', | ||
} | ||
EOS | ||
apply_manifest(pp, :catch_failures => true) | ||
end | ||
|
||
describe 'when creating secgroup' do | ||
it 'should idempotently run' do | ||
pp =<<-EOS | ||
onesecgroup { 'secgroup1': | ||
ensure => present, | ||
description => 'Description.', | ||
rules => [{'protocol' => 'ALL', 'rule_type' => 'OUTBOUND'}], | ||
} | ||
EOS | ||
|
||
apply_manifest(pp, :catch_failures => true) | ||
end | ||
end | ||
|
||
describe 'when updating a fixed secgroup' do | ||
it 'should idempotently run' do | ||
pp =<<-EOS | ||
onesecgroup { 'secgroup1': | ||
ensure => present, | ||
description => 'Description.', | ||
rules => [{'protocol' => 'ALL', 'rule_type' => 'OUTBOUND'}], | ||
} | ||
EOS | ||
|
||
apply_manifest(pp, :catch_changes => true) | ||
end | ||
end | ||
|
||
describe 'when deleting a Security Group' do | ||
it 'should idempotently run' do | ||
pp =<<-EOS | ||
onesecgroup { 'secgroup1': | ||
ensure => absent, | ||
} | ||
EOS | ||
|
||
apply_manifest(pp, :catch_failures => true) | ||
apply_manifest(pp, :catch_changes => true) | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
#!/usr/bin/env rspec | ||
|
||
require 'spec_helper' | ||
|
||
provider_class = Puppet::Type.type(:onesecgroup).provider(:onesecgroup) | ||
describe provider_class do | ||
let(:resource ) { | ||
Puppet::Type::onesecgroup.new({ | ||
:name => 'new_secgroup', | ||
}) | ||
} | ||
|
||
let(:provider) { | ||
@provider = provider_class.new(@resource) | ||
} | ||
|
||
it 'should exist' do | ||
@provider | ||
end | ||
|
||
context 'when checking if resource exists' do | ||
it 'should return true if resource exists' do | ||
skip('needs test to verify existance') | ||
end | ||
it 'should return false if reosurce does not exists' do | ||
skip('needs test to verify absence') | ||
end | ||
end | ||
context 'when creating' do | ||
it 'should create tempfile with proper values' do | ||
skip('needs tests to verify creation') | ||
end | ||
end | ||
context 'when deleting' do | ||
it 'should run onesecgroup delete <name>' do | ||
skip('needs test to verify removal') | ||
end | ||
end | ||
context 'when updating' do | ||
skip('update needs all tests') | ||
end | ||
|
||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
#!/usr/bin/env rspec | ||
|
||
require 'spec_helper' | ||
|
||
res_type_name = :onesecgroup | ||
res_type = Puppet::Type.type(res_type_name) | ||
|
||
describe res_type do | ||
let(:provider) { | ||
prov = stub 'provider' | ||
prov.stubs(:name).returns(res_type_name) | ||
prov | ||
} | ||
let(:res_type) { | ||
val = res_type | ||
val.stubs(:defaultprovider).returns provider | ||
val | ||
} | ||
# let(:resource) { | ||
# res_type.new({:name => 'test'}) | ||
# } | ||
|
||
before :each do | ||
@secgroup = res_type.new(:name => 'test') | ||
end | ||
|
||
it 'should have :name be its namevar' do | ||
res_type.key_attributes.should == [:name] | ||
end | ||
|
||
parameters = [] | ||
|
||
parameters.each do |params| | ||
it "should have a #{params} parameter" do | ||
expect(described_class.attrtype(params)).to eq :param | ||
end | ||
end | ||
|
||
properties = [:description, :rules] | ||
|
||
properties.each do |property| | ||
it "should have a #{property} property" do | ||
described_class.attrclass(property).ancestors.should be_include(Puppet::Property) | ||
end | ||
|
||
it "should have documentation for its #{property} property" do | ||
described_class.attrclass(property).doc.should be_instance_of(String) | ||
end | ||
end | ||
|
||
it 'should have property :description' do | ||
@secgroup[:description] = 'This is a description.' | ||
@secgroup[:description].should == 'This is a description.' | ||
end | ||
|
||
it 'should have property :rules' do | ||
@secgroup[:rules] = [{'protocol' => 'ALL', 'rule_type' => 'OUTBOUND'}, {'protocol' => 'ALL', 'rule_type' => 'INBOUND'}] | ||
@secgroup[:rules].should == [{'protocol' => 'ALL', 'rule_type' => 'OUTBOUND'}, {'protocol' => 'ALL', 'rule_type' => 'INBOUND'}] | ||
end | ||
|
||
parameter_tests = { | ||
:name => { | ||
:valid => ["test", "foo"], | ||
:default => "test", | ||
:invalid => ["0./fouzb&$", "&fr5"], | ||
}, | ||
} | ||
it_should_behave_like "a puppet type", parameter_tests, res_type_name | ||
|
||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe you want to update the Copyright and author.