Class: MacAdmin::DSLocalRecord

Inherits:
Hash
  • Object
show all
Includes:
Common, MCX
Defined in:
lib/macadmin/dslocal.rb

Overview

DSLocalRecord (super class)

  • this is the raw constructor class for DSLocal records

  • records of ‘type’ should be created using one of the provided subclasses

  • this class delegates to Hash and therefore behaves as though it were one

  • added method_missing? to do fancy dot-style attribute returns

Direct Known Subclasses

Computer, Group, User

Constant Summary collapse

DSLOCAL_ROOT =

Where all the files on disk live

'/private/var/db/dslocal/nodes'

Constants included from Common

Common::MAC_OS_X_PRODUCT_VERSION

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from MCX

#has_mcx?, #mcx_delete, #mcx_export, #mcx_import, #pretty_mcx

Methods included from Common

#get_primary_mac_address, #load_plist, #restart_directoryservice

Constructor Details

#initialize(args) ⇒ DSLocalRecord

Create a new DSLocalRecord

  • this method is not meant to be called directly; use subclasses instead

  • params are valid DSLocalRecord attributes

  • when a node is not specified, ‘Default’ is assumed



41
42
43
44
45
46
47
48
49
50
# File 'lib/macadmin/dslocal.rb', line 41

def initialize(args)
  @real = (args.delete(:real) { nil }) unless args.is_a? String
  @data = normalize(args)
  @name = @data['name'].first
  @record_type = record_type
  @node = (@data.delete('node') { ['Default'] }).first.to_s
  @file = (@data.delete('file') { ["#{DSLOCAL_ROOT}/#{@node}/#{@record_type + 's'}/#{@name}.plist"] }).first.to_s
  @record = synthesize(@data)
  super(@record)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args, &block) ⇒ Object (private)

Provide dot notation for setting and getting valid attribs



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/macadmin/dslocal.rb', line 231

def method_missing(meth, *args, &block)
  if args.empty?
    return self[meth.to_s] if self[meth.to_s]
    return nil if defaults(@data)[meth.to_s]
  else
    if meth.to_s =~ /=$/
      if self["#{$`}"] or defaults(@data)["#{$`}"]
        if args.is_a? Array
          return self["#{$`}"] = (args.each { |e| e.to_s }).flatten
        elsif args.is_a? String
          return self["#{$`}"] = e.to_s
        end
      end
    end
  end
  super
end

Instance Attribute Details

#compositeObject (readonly)

Some reader attributes for introspection and debugging



21
22
23
# File 'lib/macadmin/dslocal.rb', line 21

def composite
  @composite
end

#dataObject (readonly)

Some reader attributes for introspection and debugging



21
22
23
# File 'lib/macadmin/dslocal.rb', line 21

def data
  @data
end

#fileObject

Some reader attributes for introspection and debugging



21
22
23
# File 'lib/macadmin/dslocal.rb', line 21

def file
  @file
end

#nodeObject (readonly)

Some reader attributes for introspection and debugging



21
22
23
# File 'lib/macadmin/dslocal.rb', line 21

def node
  @node
end

#realObject (readonly)

Some reader attributes for introspection and debugging



21
22
23
# File 'lib/macadmin/dslocal.rb', line 21

def real
  @real
end

#recordObject (readonly)

Some reader attributes for introspection and debugging



21
22
23
# File 'lib/macadmin/dslocal.rb', line 21

def record
  @record
end

Class Method Details

.init_with_file(file) ⇒ Object

Inits a record from a file on disk

  • param is a path to a DSLocal Property List file

  • if file is invalid, return nil



29
30
31
32
33
# File 'lib/macadmin/dslocal.rb', line 29

def init_with_file(file)
  data = load_plist file
  return nil unless data
  self.new :name => data['name'].first, :file => file, :real => data
end

Instance Method Details

#[](key) ⇒ Object

Override the Hash getter method

  • so that we can use Symbols as well as Strings



114
115
116
117
# File 'lib/macadmin/dslocal.rb', line 114

def [](key)
  key = key.to_s if key.is_a?(Symbol)
  super(key)
end

#[]=(key, value) ⇒ Object

Override the Hash setter method

  • so that we can use Symbols as well as Strings



121
122
123
124
# File 'lib/macadmin/dslocal.rb', line 121

def []=(key, value)
  key = key.to_s if key.is_a?(Symbol)
  super(key, value)
end

#create(file = @file) ⇒ Object

Create the record

  • simply writes the compiled Hash to disk

  • converts ShadowHashData attrib to CFPropertyList::Blob before writing

  • will accept an alternate path than the default; useful for debugging



63
64
65
66
67
68
69
70
71
72
# File 'lib/macadmin/dslocal.rb', line 63

def create(file = @file)
  out = @record.dup
  if shadowhashdata = out['ShadowHashData']
    out['ShadowHashData'] = [CFPropertyList::Blob.new(shadowhashdata.first)]
  end
  plist = CFPropertyList::List.new
  plist.value = CFPropertyList.guess(out)
  plist.save(file, CFPropertyList::List::FORMAT_BINARY)
  FileUtils.chmod(0600, file)
end

#destroy(file = @file) ⇒ Object

Delete the record

  • removes the file representing the record from disk

  • will accept an alternate path than the default; useful for debugging

  • returns true if the file was destroyed or does not exist; false otherwise



78
79
80
81
# File 'lib/macadmin/dslocal.rb', line 78

def destroy(file = @file)
  FileUtils.rm file if File.exists? file
  !File.exists? file
end

#diff(other) ⇒ Object

Diff two records

  • of limited value except for debugging

  • output is not very coherent



97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/macadmin/dslocal.rb', line 97

def diff(other)
  this = self.record
  other = other.record
  (this.keys + other.keys).uniq.inject({}) do |memo, key|
    unless this[key] == other[key]
      if this[key].kind_of?(Hash) &&  other[key].kind_of?(Hash)
        memo[key] = this[key].diff(other[key])
      else
        memo[key] = [this[key], other[key]] 
      end
    end
    memo
  end
end

#eql?(obj) ⇒ Boolean Also known as: equal?

Test object equality

  • Class#eql? is not being passed to the delegate

  • it needs a little help

Returns:

  • (Boolean)


86
87
88
89
90
91
# File 'lib/macadmin/dslocal.rb', line 86

def eql?(obj)
  if obj.is_a?(self.class)
    return self.record.eql?(obj.record)
  end
  false
end

#exists?Boolean

Does the specified resource already exist?

  • returns Boolean

Returns:

  • (Boolean)


54
55
56
57
# File 'lib/macadmin/dslocal.rb', line 54

def exists?
  @real = load_plist @file
  @composite.eql? @real
end