lib/jamf/api/classic/base_classes/group.rb in ruby-jss-2.0.0a11 vs lib/jamf/api/classic/base_classes/group.rb in ruby-jss-2.0.0b1
- old
+ new
@@ -110,21 +110,23 @@
#
def self.change_membership(group, add_members: [], remove_members: [], api: nil, cnx: Jamf.cnx)
cnx = api if api
raise Jamf::NoSuchItemError, "No #{self} matching '#{group}'" unless (group_id = valid_id group, cnx: cnx)
- raise Jamf::UnsupportedError, "Not a static group, can't change membership directly" if map_all_ids_to(:is_smart, cnx: cnx)[group_id]
+ raise Jamf::UnsupportedError, "Not a static group, can't change membership" if map_all(:id, to: :is_smart, cnx: cnx)[group_id]
add_members = [add_members].flatten
remove_members = [remove_members].flatten
return if add_members.empty? && remove_members.empty?
# we must know the current group membership, because the API
# will raise a conflict error if we try to remove a member
# that isn't in the group (which is kinda lame - it should just
# ignore this, like it does when we add a member that's already
# in the group.)
+ # Its even more lame because we have to instantiate the group
+ # and part of the point of this class method is to avoid that.
current_member_ids = fetch(id: group_id, cnx: cnx).member_ids
# nil if no changes to be made
xml_doc = change_membership_xml add_members, remove_members, current_member_ids
return unless xml_doc
@@ -187,11 +189,10 @@
member_removed ? removals : nil
end
private_class_method :member_removals_xml
-
# Attributes
#####################################
# @return [Array<Hash>] the group membership
#
@@ -205,38 +206,34 @@
#
attr_reader :members
# @return [Boolean] is this a smart group
attr_reader :is_smart
+ alias smart? is_smart
# @return [Boolean] does this group send notifications when it changes?
attr_reader :notify_on_change
+ alias notify_on_change? notify_on_change
+ alias notify? notify_on_change
-
# Constructor
#####################################
# When creating a new group in the JSS, you must call .make with a :type key
# and a value of :smart or :static, as well as a :name
#
# @see Jamf::APIObject
#
def initialize(**args)
- if args[:id] == :new
- raise Jamf::InvalidDataError, 'New group creation must specify a :type of :smart or :static' unless GROUP_TYPES.include? args[:type]
- end
+ raise Jamf::InvalidDataError, 'New group creation must specify a :type of :smart or :static' if args[:id] == :new && !(GROUP_TYPES.include? args[:type])
super
@is_smart = @init_data[:is_smart] || (args[:type] == :smart)
@members =
- if @init_data[self.class::MEMBER_CLASS::RSRC_LIST_KEY]
- @init_data[self.class::MEMBER_CLASS::RSRC_LIST_KEY]
- else
- []
- end
+ @init_data[self.class::MEMBER_CLASS::RSRC_LIST_KEY] || []
end # init
# Public Instance Methods
#####################################
@@ -249,13 +246,12 @@
# group to re-read the membership can happen too fast, the JSS won't know
# it exists yet and will throw a NoSuchItem error. If that
# happens, try again this many times with a 1 second pause between attempts.
#
def create(calculate_members: true, retries: 10)
- if @is_smart
- raise Jamf::MissingDataError, 'No criteria specified for smart group' unless @criteria
- end
+ raise Jamf::MissingDataError, 'No criteria specified for smart group' if @is_smart && !@criteria
+
super()
if calculate_members
tries = 0
while tries < retries
@@ -287,14 +283,14 @@
params[:refresh] = true if params[:refresh].nil?
if @in_jss
raise Jamf::UnsupportedError, 'Updating this object in the JSS is currently not supported by ruby-jss' unless updatable?
-
update refresh: params[:refresh]
else
raise Jamf::UnsupportedError, 'Creating this object in the JSS is currently not supported by ruby-jss' unless creatable?
+
create calculate_members: params[:calculate_members], retries: params[:retries]
end
end
# @see APIObject#delete
@@ -319,45 +315,60 @@
# Change static group to smart group
#
# @param args[Hash] the options and settings use for switching the computer group from static group to smart group
#
- # @option args criteria[Array] The criterias to be user for the smart group
- def set_smart(*params)
+ # @option args criteria[Array] The criteria to be user for the smart group
+ #
+ # @return [void]
+ def make_smart(**params)
return if @is_smart
params[:criteria] = [] if params[:criteria].nil?
criteria = params[:criteria]
@is_smart = true
@need_to_update = true
end
+ # backward compatility
+ alias set_smart make_smart
# Change smart group to static group
#
# @param args[Hash] the options and settings use for switching the computer group from smart group to static group
#
# @option args preserve_members[Boolean] Should the smart group preserve it's current members?
- def set_static(*params)
+ #
+ # @return [void]
+ def make_static(**params)
return unless @is_smart
preserve_members = params.include? :preserve_members
@is_smart = false
- clear() unless preserve_members
+ clear unless preserve_members
end
-
+ # backward compatility
+ alias set_static make_static
+
# How many members of the group?
#
# @return [Integer] the number of members of the group
#
def size
@members.count
end
+ alias count size
+ # @return [Boolean] Is this a static group?
+ def static?
+ !smart?
+ end
+ alias is_static static?
+
# @return [Array<String>] the names of the group members
#
def member_names
@members.map { |m| m[:name] }
end
@@ -379,19 +390,21 @@
# @return [void]
#
def members=(new_members)
raise UnsupportedError, "Smart group members can't be changed." if @is_smart
raise InvalidDataError, 'Arg must be an array of names and/or ids' unless new_members.is_a? Array
+
ok_members = []
new_members.each do |m|
ok_members << check_member(m)
end
ok_members.uniq!
# make sure we've actually changed...
return if members.map { |m| m[:id] }.sort == ok_members.map { |m| m[:id] }.sort
+
@members = ok_members
@need_to_update = true
end
# Add a member, by name or id
@@ -399,35 +412,46 @@
# @param m[Integer,String] the id or name of the member to add
#
# @return [void]
#
def add_member(mem)
- raise UnsupportedError, "Smart group members can't be changed." if @is_smart
+ raise UnsupportedError, "Smart group members can't be changed." if smart?
+
@members << check_member(mem)
@need_to_update = true
end
# Remove a member by id, or name
#
- # @param m[Integer,String] the id or name of the member to remove
+ # @param m[Integer,String] an identifier for the item to remove
#
# @return [void]
#
def remove_member(mem)
- raise InvalidDataError, "Smart group members can't be changed." if @is_smart
- raise InvalidDataError, "Can't remove nil" if mem.nil?
- removed = @members.reject! { |mm| [mm[:id], mm[:name], mm[:username]].include? mem }
- @need_to_update = true if removed
+ raise UnsupportedError, "Smart group members can't be changed." if smart?
+
+ # See if we have the identifier in the @members hash
+ id_to_remove = @members.select { |mm| mm.values.include? mem }.first&.dig :id
+ # But the members hash might not have SN, macaddr, etc, and never has udid, so
+ # look at the MEMBER_CLASS if needed
+ id_to_remove ||= self.class::MEMBER_CLASS.valid_id mem
+
+ # nothing to do if that id isn't one of our members
+ return unless id_to_remove && member_ids.include?(id_to_remove)
+
+ @members.delete_if { |k, v| k == :id && v == id_to_remove }
+ @need_to_update = true
end
# Remove all members
#
# @return [void]
#
def clear
raise InvalidDataError, "Smart group members can't be changed." if @is_smart
return if @members.empty?
+
@members.clear
@need_to_update = true
end
# Immediatly add and/or remove members in this static group
@@ -456,18 +480,12 @@
# @return [Array<Hash>] the refresh membership
#
def refresh_members
@members = @cnx.c_get(@rest_rsrc)[self.class::RSRC_OBJECT_KEY][self.class::MEMBER_CLASS::RSRC_LIST_KEY]
end
+
- # aliases
-
- alias smart? is_smart
- alias notify_on_change? notify_on_change
- alias notify? notify_on_change
- alias count size
-
# Public Instance Methods
#####################################
private
# Check that a potential group member is valid in the JSS.
@@ -475,16 +493,15 @@
# An exception is raised if the device doesn't exist.
#
# @return [Hash{:id=>Integer,:name=>String}] the valid id and name
#
def check_member(m)
- potential_members = self.class::MEMBER_CLASS.map_all_ids_to(:name, cnx: @cnx)
- if m.to_s =~ /^\d+$/
- return { id: m.to_i, name: potential_members[m] } if potential_members.key?(m.to_i)
- else
- return { name: m, id: potential_members.invert[m] } if potential_members.value?(m)
- end
- raise Jamf::NoSuchItemError, "No #{self.class::MEMBER_CLASS::RSRC_OBJECT_KEY} matching '#{m}' in the JSS."
+ desired_id = self.class::MEMBER_CLASS.valid_id m, cnx: @cnx
+ raise Jamf::NoSuchItemError, "No #{self.class::MEMBER_CLASS::RSRC_OBJECT_KEY} matching '#{m}' in the JSS." unless desired_id
+
+ desired_name = self.class::MEMBER_CLASS.map_all(:id, to: :name, cnx: @cnx)[desired_id]
+
+ { name: desired_name, id: desired_id }
end
# the xml formated data for adding or updating this in the JSS,
#
def rest_xml