diff --git a/install.sh b/install.sh index faed35b173..a7d8670fed 100755 --- a/install.sh +++ b/install.sh @@ -601,6 +601,7 @@ BIN_FILES="src/nebula/oned \ src/cli/onezone \ src/cli/oneflow \ src/cli/oneflow-template \ + src/cli/onesecgroup \ src/onedb/onedb \ src/mad/utils/tty_expect \ share/scripts/one" @@ -1258,6 +1259,8 @@ RUBY_OPENNEBULA_LIB_FILES="src/oca/ruby/opennebula/acl_pool.rb \ src/oca/ruby/opennebula/image.rb \ src/oca/ruby/opennebula/pool_element.rb \ src/oca/ruby/opennebula/pool.rb \ + src/oca/ruby/opennebula/security_group_pool.rb \ + src/oca/ruby/opennebula/security_group.rb \ src/oca/ruby/opennebula/system.rb \ src/oca/ruby/opennebula/template_pool.rb \ src/oca/ruby/opennebula/template.rb \ @@ -1420,7 +1423,8 @@ ONE_CLI_LIB_FILES="src/cli/one_helper/onegroup_helper.rb \ src/cli/one_helper/onedatastore_helper.rb \ src/cli/one_helper/onecluster_helper.rb \ src/cli/one_helper/onezone_helper.rb \ - src/cli/one_helper/oneacct_helper.rb" + src/cli/one_helper/oneacct_helper.rb \ + src/cli/one_helper/onesecgroup_helper.rb" CLI_BIN_FILES="src/cli/onevm \ src/cli/onehost \ @@ -1435,7 +1439,8 @@ CLI_BIN_FILES="src/cli/onevm \ src/cli/onezone \ src/cli/oneflow \ src/cli/oneflow-template \ - src/cli/oneacct" + src/cli/oneacct \ + src/cli/onesecgroup" CLI_CONF_FILES="src/cli/etc/onegroup.yaml \ src/cli/etc/onehost.yaml \ @@ -1448,7 +1453,8 @@ CLI_CONF_FILES="src/cli/etc/onegroup.yaml \ src/cli/etc/onedatastore.yaml \ src/cli/etc/onecluster.yaml \ src/cli/etc/onezone.yaml \ - src/cli/etc/oneacct.yaml" + src/cli/etc/oneacct.yaml \ + src/cli/etc/onesecgroup.yaml" #----------------------------------------------------------------------------- # Sunstone files @@ -1793,6 +1799,7 @@ MAN_FILES="share/man/oneacct.1.gz \ share/man/onezone.1.gz \ share/man/oneflow.1.gz \ share/man/oneflow-template.1.gz \ + share/man/onesecgroup.1.gz \ share/man/econe-allocate-address.1.gz \ share/man/econe-associate-address.1.gz \ share/man/econe-attach-volume.1.gz \ diff --git a/share/man/SConstruct b/share/man/SConstruct index 3749fb557d..92ddb7db42 100644 --- a/share/man/SConstruct +++ b/share/man/SConstruct @@ -61,6 +61,9 @@ env.Man('onevnet') env.Man('onegroup') env.Man('onezone') +# TODO +#env.Man('onesecgroup') + env.Man('oneflow') env.Man('oneflow-template') diff --git a/src/cli/cli_helper.rb b/src/cli/cli_helper.rb index fc1eb07891..86976ff252 100644 --- a/src/cli/cli_helper.rb +++ b/src/cli/cli_helper.rb @@ -211,7 +211,7 @@ module CLIHelper pool=@data.keys.first return print_table(nil, options) if !pool - element=pool.split('_').first + element=pool.split('_')[0..-2].join('_') pool_data=@data.dsearch("#{pool}/#{element}") pool_data=[pool_data].flatten if pool_data diff --git a/src/cli/etc/onesecgroup.yaml b/src/cli/etc/onesecgroup.yaml new file mode 100644 index 0000000000..1c4f5bd4ed --- /dev/null +++ b/src/cli/etc/onesecgroup.yaml @@ -0,0 +1,25 @@ +--- +:ID: + :desc: ONE identifier for the Security Group + :size: 4 + +:NAME: + :desc: Name of the Security Group + :size: 27 + :left: true + +:USER: + :desc: Username of the Security Group owner + :size: 15 + :left: true + +:GROUP: + :desc: Group of the Security Group + :size: 15 + :left: true + +:default: +- :ID +- :USER +- :GROUP +- :NAME diff --git a/src/cli/one_helper/onesecgroup_helper.rb b/src/cli/one_helper/onesecgroup_helper.rb new file mode 100644 index 0000000000..dc7a6e6877 --- /dev/null +++ b/src/cli/one_helper/onesecgroup_helper.rb @@ -0,0 +1,96 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +require 'one_helper' + +class OneSecurityGroupHelper < OpenNebulaHelper::OneHelper + def self.rname + "SECURITY_GROUP" + end + + def self.conf_file + "onesecgroup.yaml" + end + + def format_pool(options) + config_file = self.class.table_conf + + table = CLIHelper::ShowTable.new(config_file, self) do + column :ID, "ONE identifier for the Security Group", :size=>4 do |d| + d["ID"] + end + + column :NAME, "Name of the Security Group", :left, :size=>27 do |d| + d["NAME"] + end + + column :USER, "Username of the Security Group owner", :left, + :size=>15 do |d| + helper.user_name(d, options) + end + + column :GROUP, "Group of the Security Group", :left, :size=>15 do |d| + helper.group_name(d, options) + end + + default :ID, :USER, :GROUP, :NAME + end + + table + end + + private + + def factory(id=nil) + if id + OpenNebula::SecurityGroup.new_with_id(id, @client) + else + xml=OpenNebula::SecurityGroup.build_xml + OpenNebula::SecurityGroup.new(xml, @client) + end + end + + def factory_pool(user_flag=-2) + OpenNebula::SecurityGroupPool.new(@client, user_flag) + end + + def format_resource(secgroup, options = {}) + str="%-15s: %-20s" + str_h1="%-80s" + + CLIHelper.print_header( + str_h1 % "SECURITY GROUP #{secgroup['ID']} INFORMATION") + puts str % ["ID", secgroup.id.to_s] + puts str % ["NAME", secgroup.name] + puts str % ["USER", secgroup['UNAME']] + puts str % ["GROUP", secgroup['GNAME']] + + CLIHelper.print_header(str_h1 % "PERMISSIONS",false) + + ["OWNER", "GROUP", "OTHER"].each { |e| + mask = "---" + mask[0] = "u" if secgroup["PERMISSIONS/#{e}_U"] == "1" + mask[1] = "m" if secgroup["PERMISSIONS/#{e}_M"] == "1" + mask[2] = "a" if secgroup["PERMISSIONS/#{e}_A"] == "1" + + puts str % [e, mask] + } + puts + + CLIHelper.print_header(str_h1 % "TEMPLATE CONTENTS",false) + puts secgroup.template_str + end +end diff --git a/src/cli/onesecgroup b/src/cli/onesecgroup new file mode 100755 index 0000000000..5c0fae20db --- /dev/null +++ b/src/cli/onesecgroup @@ -0,0 +1,198 @@ +#!/usr/bin/env ruby + +# -------------------------------------------------------------------------- # +# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + +ONE_LOCATION=ENV["ONE_LOCATION"] + +if !ONE_LOCATION + RUBY_LIB_LOCATION="/usr/lib/one/ruby" +else + RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" +end + +$: << RUBY_LIB_LOCATION +$: << RUBY_LIB_LOCATION+"/cli" + +require 'command_parser' +require 'one_helper/onesecgroup_helper' + +cmd=CommandParser::CmdParser.new(ARGV) do + usage "`onesecgroup` [] []" + version OpenNebulaHelper::ONE_VERSION + + helper = OneSecurityGroupHelper.new + + before_proc do + helper.set_client(options) + end + + ######################################################################## + # Global Options + ######################################################################## + set :option, CommandParser::OPTIONS+OpenNebulaHelper::CLIENT_OPTIONS + + list_options = CLIHelper::OPTIONS + list_options << OpenNebulaHelper::XML + list_options << OpenNebulaHelper::NUMERIC + list_options << OpenNebulaHelper::DESCRIBE + + ######################################################################## + # Formatters for arguments + ######################################################################## + set :format, :groupid, OpenNebulaHelper.rname_to_id_desc("GROUP") do |arg| + OpenNebulaHelper.rname_to_id(arg, "GROUP") + end + + set :format, :userid, OpenNebulaHelper.rname_to_id_desc("USER") do |arg| + OpenNebulaHelper.rname_to_id(arg, "USER") + end + + set :format, :secgroupid, OneSecurityGroupHelper.to_id_desc do |arg| + helper.to_id(arg) + end + + set :format, :secgroupid_list, OneSecurityGroupHelper.list_to_id_desc do |arg| + helper.list_to_id(arg) + end + + set :format, :filterflag, OneSecurityGroupHelper.filterflag_to_i_desc do |arg| + helper.filterflag_to_i(arg) + end + + ######################################################################## + # Commands + ######################################################################## + + create_desc = <<-EOT.unindent + Creates a new Security Group from the given description + EOT + + command :create, create_desc, :file do + helper.create_resource(options) do |obj| + begin + template = File.read(args[0]) + + obj.allocate(template) + rescue => e + STDERR.puts e.messsage + exit -1 + end + end + end + + clone_desc = <<-EOT.unindent + Creates a new Security Group from an existing one + EOT + + command :clone, clone_desc, :secgroupid, :name do + helper.perform_action(args[0],options,"cloned") do |obj| + res = obj.clone(args[1]) + + if !OpenNebula.is_error?(res) + puts "ID: #{res}" + else + puts res.message + end + end + end + + delete_desc = <<-EOT.unindent + Deletes the given Security Group + EOT + + command :delete, delete_desc, [:range, :secgroupid_list] do + helper.perform_actions(args[0],options,"deleted") do |obj| + obj.delete + end + end + + chgrp_desc = <<-EOT.unindent + Changes the Security Group's group + EOT + + command :chgrp, chgrp_desc,[:range, :secgroupid_list], :groupid do + helper.perform_actions(args[0],options,"Group changed") do |obj| + obj.chown(-1, args[1].to_i) + end + end + + chown_desc = <<-EOT.unindent + Changes the Security Group's owner and group + EOT + + command :chown, chown_desc, [:range, :secgroupid_list], :userid, + [:groupid,nil] do + gid = args[2].nil? ? -1 : args[2].to_i + helper.perform_actions(args[0],options,"Owner/Group changed") do |obj| + obj.chown(args[1].to_i, gid) + end + end + + chmod_desc = <<-EOT.unindent + Changes the Security Group permissions + EOT + + command :chmod, chmod_desc, [:range, :secgroupid_list], :octet do + helper.perform_actions(args[0],options, "Permissions changed") do |t| + t.chmod_octet(args[1]) + end + end + + update_desc = <<-EOT.unindent + Update the template contents. If a path is not provided the editor will + be launched to modify the current content. + EOT + + command :update, update_desc, :secgroupid, [:file, nil], + :options=>OpenNebulaHelper::APPEND do + helper.perform_action(args[0],options,"modified") do |obj| + if options[:append] + str = OpenNebulaHelper.append_template(args[0], obj, args[1]) + else + str = OpenNebulaHelper.update_template(args[0], obj, args[1]) + end + + obj.update(str, options[:append]) + end + end + + rename_desc = <<-EOT.unindent + Renames the Security Group + EOT + + command :rename, rename_desc, :secgroupid, :name do + helper.perform_action(args[0],options,"renamed") do |o| + o.rename(args[1]) + end + end + + list_desc = <<-EOT.unindent + Lists Security Group in the pool + EOT + + command :list, list_desc, [:filterflag, nil], :options=>list_options do + helper.list_pool(options, false, args[0]) + end + + show_desc = <<-EOT.unindent + Shows information for the given Security Group + EOT + + command :show, show_desc, :secgroupid, :options=>OpenNebulaHelper::XML do + helper.show_resource(args[0],options) + end +end diff --git a/src/oca/ruby/opennebula.rb b/src/oca/ruby/opennebula.rb index f540e90a81..4265ab7ffa 100644 --- a/src/oca/ruby/opennebula.rb +++ b/src/oca/ruby/opennebula.rb @@ -51,6 +51,8 @@ require 'opennebula/document' require 'opennebula/document_pool' require 'opennebula/zone' require 'opennebula/zone_pool' +require 'opennebula/security_group' +require 'opennebula/security_group_pool' require 'opennebula/system' module OpenNebula diff --git a/src/oca/ruby/opennebula/pool.rb b/src/oca/ruby/opennebula/pool.rb index af2350eb22..af63adbac9 100644 --- a/src/oca/ruby/opennebula/pool.rb +++ b/src/oca/ruby/opennebula/pool.rb @@ -25,7 +25,7 @@ module OpenNebula alias_method :each_with_xpath, :each PAGINATED_POOLS=%w{VM_POOL IMAGE_POOL TEMPLATE_POOL VN_POOL - DOCUMENT_POOL} + DOCUMENT_POOL SECGROUP_POOL} protected #pool:: _String_ XML name of the root element diff --git a/src/oca/ruby/opennebula/security_group.rb b/src/oca/ruby/opennebula/security_group.rb new file mode 100644 index 0000000000..1ad85aabf0 --- /dev/null +++ b/src/oca/ruby/opennebula/security_group.rb @@ -0,0 +1,164 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + + +require 'opennebula/pool_element' + +module OpenNebula + class SecurityGroup < PoolElement + ####################################################################### + # Constants and Class Methods + ####################################################################### + + + SECGROUP_METHODS = { + :allocate => "secgroup.allocate", + :info => "secgroup.info", + :update => "secgroup.update", + :delete => "secgroup.delete", + :chown => "secgroup.chown", + :chmod => "secgroup.chmod", + :clone => "secgroup.clone", + :rename => "secgroup.rename" + } + + # Creates a SecurityGroup description with just its identifier + # this method should be used to create plain SecurityGroup objects. + # @param pe_id [Integer] the id of the object + def SecurityGroup.build_xml(pe_id=nil) + if pe_id + obj_xml = "#{pe_id}" + else + obj_xml = "" + end + + XMLElement.build_xml(obj_xml,'SECURITY_GROUP') + end + + # Class constructor + def initialize(xml, client) + super(xml,client) + + @client = client + end + + ####################################################################### + # XML-RPC Methods for the SecurityGroup Object + ####################################################################### + + # Retrieves the information of the given SecurityGroup. + def info() + super(SECGROUP_METHODS[:info], 'SECURITY_GROUP') + end + + alias_method :info!, :info + + # Allocates a new SecurityGroup in OpenNebula + # + # @param description [String] The contents of the SecurityGroup. + # + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def allocate(description) + super(SECGROUP_METHODS[:allocate], description) + end + + # Deletes the SecurityGroup + def delete() + super(SECGROUP_METHODS[:delete]) + end + + # Replaces the securitygroup contents + # + # @param new_securitygroup [String] New securitygroup contents + # @param append [true, false] True to append new attributes instead of + # replace the whole securitygroup + # + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def update(new_securitygroup, append=false) + super(SECGROUP_METHODS[:update], new_securitygroup, append ? 1 : 0) + end + + # Changes the owner/group + # + # @param uid [Integer] the new owner id. Set to -1 to leave the current one + # @param gid [Integer] the new group id. Set to -1 to leave the current one + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def chown(uid, gid) + super(SECGROUP_METHODS[:chown], uid, gid) + end + + # Changes the SecurityGroup permissions. + # + # @param octet [String] Permissions octed , e.g. 640 + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def chmod_octet(octet) + super(SECGROUP_METHODS[:chmod], octet) + end + + # Changes the SecurityGroup permissions. + # Each [Integer] argument must be 1 to allow, 0 deny, -1 do not change + # + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def chmod(owner_u, owner_m, owner_a, group_u, group_m, group_a, other_u, + other_m, other_a) + super(SECGROUP_METHODS[:chmod], owner_u, owner_m, owner_a, group_u, + group_m, group_a, other_u, other_m, other_a) + end + + # Clones this SecurityGroup into a new one + # + # @param [String] name for the new SecurityGroup. + # + # @return [Integer, OpenNebula::Error] The new SecurityGroup ID in case + # of success, Error otherwise + def clone(name) + return Error.new('ID not defined') if !@pe_id + + rc = @client.call(SECGROUP_METHODS[:clone], @pe_id, name) + + return rc + end + + # Renames this SecurityGroup + # + # @param name [String] New name for the SecurityGroup. + # + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def rename(name) + return call(SECGROUP_METHODS[:rename], @pe_id, name) + end + + ####################################################################### + # Helpers to get SecurityGroup information + ####################################################################### + + # Returns the group identifier + # [return] _Integer_ the element's group ID + def gid + self['GID'].to_i + end + + def owner_id + self['UID'].to_i + end + end +end diff --git a/src/oca/ruby/opennebula/security_group_pool.rb b/src/oca/ruby/opennebula/security_group_pool.rb new file mode 100644 index 0000000000..a2c80fc036 --- /dev/null +++ b/src/oca/ruby/opennebula/security_group_pool.rb @@ -0,0 +1,78 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + + +require 'opennebula/pool' + +module OpenNebula + class SecurityGroupPool < Pool + ####################################################################### + # Constants and Class attribute accessors + ####################################################################### + + SECGROUP_POOL_METHODS = { + :info => "secgrouppool.info" + } + + ####################################################################### + # Class constructor & Pool Methods + ####################################################################### + + # +client+ a Client object that represents an XML-RPC connection + # +user_id+ used to refer to a Pool with Templates from that user + def initialize(client, user_id=-1) + super('SECURITY_GROUP_POOL','SECURITY_GROUP',client) + + @user_id = user_id + end + + # Factory method to create Template objects + def factory(element_xml) + OpenNebula::SecurityGroup.new(element_xml,@client) + end + + ####################################################################### + # XML-RPC Methods for the Template Object + ####################################################################### + + # Retrieves all or part of the objects in the pool. + def info(*args) + case args.size + when 0 + info_filter(SECGROUP_POOL_METHODS[:info],@user_id,-1,-1) + when 3 + info_filter(SECGROUP_POOL_METHODS[:info],args[0],args[1],args[2]) + end + end + + def info_all() + return super(SECGROUP_POOL_METHODS[:info]) + end + + def info_mine() + return super(SECGROUP_POOL_METHODS[:info]) + end + + def info_group() + return super(SECGROUP_POOL_METHODS[:info]) + end + + alias_method :info!, :info + alias_method :info_all!, :info_all + alias_method :info_mine!, :info_mine + alias_method :info_group!, :info_group + end +end