class Chef::Knife::DataBagFromOktaGroup
Public Instance Methods
run()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 68 def run validate_arguments validate_okta_config setup begin Chef::DataBag.validate_name!(@data_bag_name) rescue Chef::Exceptions::InvalidDataBagName => e ui.fatal(e.message) exit(1) end if same_as_existing_data_bag_item? ui.info("Data bag item #{@data_bag_item_name} already exists and contains no changes, skipping upload") exit(0) end create_data_bag_if_missing create_data_bag_item_file display_data_bag_item_changes display_data_bag_item_members check_changes_within_range upload_data_bag_item ensure FileUtils.remove_entry tmpdir if tmpdir end
Private Instance Methods
active_group_members(group_id)
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 282 def active_group_members(group_id) okta_client.list_group_members(group_id).shift.select { |user| user[:status] == "ACTIVE" } end
attribute_key_values()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 141 def attribute_key_values @attribute_key_values ||= values_for_key(config[:okta_attribute]).sort end
check_changes_within_range()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 145 def check_changes_within_range return if config[:max_change] == 0 changes = data_bag_item_additions.size + data_bag_item_removals.size return if config[:max_change] > changes ui.fatal("Data bag item #{@data_bag_item_name} has more changes than --max-change allows (#{config[:max_change]}).") exit(1) end
create_data_bag_if_missing()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 191 def create_data_bag_if_missing # Verify if the data bag exists rest.get("data/#{@data_bag_name}") ui.info("Data bag #{@data_bag_name} already exists") rescue Net::HTTPServerException => e raise unless e.to_s =~ /^404/ # if it doesn't exists, try to create it rest.post("data", { "name" => @data_bag_name }) ui.info("Created data_bag[#{@data_bag_name}]") end
create_data_bag_item_file()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 202 def create_data_bag_item_file hash = { "id" => @data_bag_item_name, config[:okta_attribute] => attribute_key_values } File.open(data_bag_item_file, "w") { |f| f.write(JSON.pretty_generate(hash)) } end
data_bag_item_additions()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 207 def data_bag_item_additions return attribute_key_values if data_bag_item_data.nil? attribute_key_values - data_bag_item_data[config[:okta_attribute]] end
data_bag_item_data()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 173 def data_bag_item_data return @data_bag_item_data if @data_bag_item_data @data_bag_item_data = rest.get("data/#{@data_bag_name}/#{@data_bag_item_name}") rescue Net::HTTPServerException nil end
data_bag_item_exist?()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 180 def data_bag_item_exist? @data_bag_item_exists ||= data_bag_item_data @data_bag_item_exists.nil? ? false : true rescue Net::HTTPServerException false end
data_bag_item_file()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 187 def data_bag_item_file @data_bag_item_file ||= "#{tmpdir}/#{@data_bag_item_name}.json" end
data_bag_item_removals()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 212 def data_bag_item_removals return [] if data_bag_item_data.nil? data_bag_item_data[config[:okta_attribute]] - attribute_key_values end
display_data_bag_item_additions()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 217 def display_data_bag_item_additions return if data_bag_item_additions.empty? ui.info("The following will be added to the data bag item #{@data_bag_item_name}:") data_bag_item_additions.each { |v| ui.info(" * #{v}") } end
display_data_bag_item_changes()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 229 def display_data_bag_item_changes return unless config[:show_changes] if data_bag_item_data.nil? display_data_bag_item_additions elsif data_bag_item_data.keys.reject { |e| e == "id" }.shift.to_s == config[:okta_attribute] display_data_bag_item_removals display_data_bag_item_additions else ui.info("A new Okta profile attribute has been specified, replacing existing data bag item with the following:") attribute_key_values.each { |v| ui.info(" * #{v}") } end end
display_data_bag_item_members()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 243 def display_data_bag_item_members return unless config[:show_members] ui.info("The data bag item will be uploaded with the following contents:") attribute_key_values.each { |v| ui.info(" * #{v}") } end
display_data_bag_item_removals()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 223 def display_data_bag_item_removals return if data_bag_item_removals.empty? ui.info("The following will be removed from the data bag item #{@data_bag_item_name}:") data_bag_item_removals.each { |v| ui.info(" * #{v}") } end
group_hash(group_name)
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 269 def group_hash(group_name) group_hash = groups.select { |group| group[:type] == "OKTA_GROUP" && group[:profile][:name] =~ /^#{group_name}$/i }.shift if group_hash.nil? ui.fatal("Cannot find a group with the name \"#{group_name}\" in the specified Okta tenant") exit(1) end group_hash end
group_id(group_name)
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 278 def group_id(group_name) group_hash(group_name)[:id] end
groups()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 265 def groups @groups ||= okta_client.list_groups.shift end
okta_client()
click to toggle source
Okta
# File lib/chef/knife/data_bag_from_okta_group.rb, line 261 def okta_client @okta_client ||= Oktakit.new(token: config[:okta_token], api_endpoint: config[:okta_endpoint]) end
okta_user_active?(user_name)
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 298 def okta_user_active?(user_name) user_hash(user_name).status == "ACTIVE" rescue NoMethodError false end
same_as_existing_data_bag_item?()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 168 def same_as_existing_data_bag_item? return false if data_bag_item_data.nil? data_bag_item_data[config[:okta_attribute]] == attribute_key_values end
setup()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 131 def setup @data_bag_name = @name_args.shift @data_bag_item_name = @name_args.shift @okta_groups = @name_args.shift.split(',') end
tmpdir()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 137 def tmpdir @tmpdir ||= Dir.mktmpdir end
upload_data_bag_item()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 250 def upload_data_bag_item ui.confirm("Data bag item #{@data_bag_item_name} exists, overwrite it") if data_bag_item_exist? knife_data_bag_from_file = Chef::Knife::DataBagFromFile.new knife_data_bag_from_file.ui = ui knife_data_bag_from_file.name_args = [@data_bag_name, data_bag_item_file] knife_data_bag_from_file.run end
user_hash(user_name)
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 290 def user_hash(user_name) user_hash = users.select { |user| user.profile.displayName =~ /^#{user_name}$/i }.shift if user_hash.nil? ui.info("Cannot find a user with the name \"#{user_name}\" in the specified Okta tenant") end user_hash end
users()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 286 def users @users ||= okta_client.list_users.shift end
validate_arguments()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 97 def validate_arguments return unless @name_args.size < 3 ui.msg(opt_parser) exit(1) end
validate_okta_config()
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 103 def validate_okta_config config[:okta_attribute] ||= ENV["OKTA_ATTRIBUTE"] if ENV["OKTA_ATTRIBUTE"] config[:okta_endpoint] ||= ENV["OKTA_ENDPOINT"] if ENV["OKTA_ENDPOINT"] config[:okta_token] ||= ENV["OKTA_TOKEN"] if ENV["OKTA_TOKEN"] unless config[:okta_attribute] ui.fatal("You must use specify an Okta identity profile attribute, either using --okta-endpoint or knife[:okta_endpoint] in your config.") exit(1) end # This should probably be more dynamic, e.g. later on once we have a user hash to look if # the provided attribute matches a profile key and if not, fail, but for now we're OK with this. unless %w{displayName email login}.include?(config[:okta_attribute]) ui.fatal('Unsupported value for --okta-attribute, please specify either "displayName", "email" or "login".') exit(1) end unless config[:okta_endpoint] ui.fatal("You must use specify an Okta API endpoint, either using --okta-endpoint or knife[:okta_endpoint] in your config.") exit(1) end unless config[:okta_token] ui.fatal("You must use specify an Okta API token, either using --okta-token or knife[:okta_token] in your config.") exit(1) end end
values_for_key(key)
click to toggle source
# File lib/chef/knife/data_bag_from_okta_group.rb, line 155 def values_for_key(key) values = [] @okta_groups.each do |okta_group| group_members = active_group_members(group_id(okta_group)) group_members.each do |group_member| values << group_member[:profile][key.to_sym] end end values.compact.sort.uniq end