automate-it 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (137) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.hgignore +10 -0
  4. data/.loadpath +5 -0
  5. data/.project +17 -0
  6. data/CHANGES.txt +314 -0
  7. data/Hoe.rake +40 -0
  8. data/Manifest.txt +164 -0
  9. data/README.txt +40 -0
  10. data/Rakefile +256 -0
  11. data/TESTING.txt +57 -0
  12. data/TODO.txt +50 -0
  13. data/TUTORIAL.txt +391 -0
  14. data/automate-it.gemspec +25 -0
  15. data/bin/ai +3 -0
  16. data/bin/aifield +75 -0
  17. data/bin/aissh +93 -0
  18. data/bin/aitag +134 -0
  19. data/bin/automateit +133 -0
  20. data/docs/friendly_errors.txt +50 -0
  21. data/docs/previews.txt +86 -0
  22. data/examples/basic/Rakefile +26 -0
  23. data/examples/basic/config/automateit_env.rb +16 -0
  24. data/examples/basic/config/fields.yml +3 -0
  25. data/examples/basic/config/tags.yml +7 -0
  26. data/examples/basic/dist/README.txt +9 -0
  27. data/examples/basic/dist/myapp_server.erb +30 -0
  28. data/examples/basic/install.log +15 -0
  29. data/examples/basic/lib/README.txt +10 -0
  30. data/examples/basic/recipes/README.txt +4 -0
  31. data/examples/basic/recipes/install.rb +61 -0
  32. data/examples/basic/recipes/uninstall.rb +6 -0
  33. data/gpl.txt +674 -0
  34. data/helpers/cpan_wrapper.pl +220 -0
  35. data/helpers/which.cmd +7 -0
  36. data/lib/automateit.rb +55 -0
  37. data/lib/automateit/account_manager.rb +114 -0
  38. data/lib/automateit/account_manager/base.rb +138 -0
  39. data/lib/automateit/account_manager/etc.rb +128 -0
  40. data/lib/automateit/account_manager/nscd.rb +33 -0
  41. data/lib/automateit/account_manager/passwd_expect.rb +40 -0
  42. data/lib/automateit/account_manager/passwd_pty.rb +69 -0
  43. data/lib/automateit/account_manager/posix.rb +138 -0
  44. data/lib/automateit/address_manager.rb +88 -0
  45. data/lib/automateit/address_manager/base.rb +171 -0
  46. data/lib/automateit/address_manager/bsd.rb +28 -0
  47. data/lib/automateit/address_manager/freebsd.rb +59 -0
  48. data/lib/automateit/address_manager/linux.rb +42 -0
  49. data/lib/automateit/address_manager/openbsd.rb +66 -0
  50. data/lib/automateit/address_manager/portable.rb +37 -0
  51. data/lib/automateit/address_manager/sunos.rb +34 -0
  52. data/lib/automateit/cli.rb +85 -0
  53. data/lib/automateit/common.rb +65 -0
  54. data/lib/automateit/constants.rb +35 -0
  55. data/lib/automateit/download_manager.rb +48 -0
  56. data/lib/automateit/edit_manager.rb +321 -0
  57. data/lib/automateit/error.rb +10 -0
  58. data/lib/automateit/field_manager.rb +103 -0
  59. data/lib/automateit/interpreter.rb +631 -0
  60. data/lib/automateit/package_manager.rb +257 -0
  61. data/lib/automateit/package_manager/apt.rb +27 -0
  62. data/lib/automateit/package_manager/cpan.rb +101 -0
  63. data/lib/automateit/package_manager/dpkg.rb +54 -0
  64. data/lib/automateit/package_manager/egg.rb +64 -0
  65. data/lib/automateit/package_manager/gem.rb +201 -0
  66. data/lib/automateit/package_manager/pear.rb +95 -0
  67. data/lib/automateit/package_manager/pecl.rb +80 -0
  68. data/lib/automateit/package_manager/portage.rb +69 -0
  69. data/lib/automateit/package_manager/yum.rb +65 -0
  70. data/lib/automateit/platform_manager.rb +49 -0
  71. data/lib/automateit/platform_manager/darwin.rb +30 -0
  72. data/lib/automateit/platform_manager/debian.rb +26 -0
  73. data/lib/automateit/platform_manager/freebsd.rb +29 -0
  74. data/lib/automateit/platform_manager/gentoo.rb +26 -0
  75. data/lib/automateit/platform_manager/lsb.rb +44 -0
  76. data/lib/automateit/platform_manager/openbsd.rb +28 -0
  77. data/lib/automateit/platform_manager/struct.rb +80 -0
  78. data/lib/automateit/platform_manager/sunos.rb +39 -0
  79. data/lib/automateit/platform_manager/uname.rb +29 -0
  80. data/lib/automateit/platform_manager/windows.rb +40 -0
  81. data/lib/automateit/plugin.rb +7 -0
  82. data/lib/automateit/plugin/base.rb +32 -0
  83. data/lib/automateit/plugin/driver.rb +256 -0
  84. data/lib/automateit/plugin/manager.rb +224 -0
  85. data/lib/automateit/project.rb +493 -0
  86. data/lib/automateit/root.rb +17 -0
  87. data/lib/automateit/service_manager.rb +93 -0
  88. data/lib/automateit/service_manager/chkconfig.rb +39 -0
  89. data/lib/automateit/service_manager/rc_update.rb +37 -0
  90. data/lib/automateit/service_manager/sysv.rb +139 -0
  91. data/lib/automateit/service_manager/update_rcd.rb +35 -0
  92. data/lib/automateit/shell_manager.rb +316 -0
  93. data/lib/automateit/shell_manager/base_link.rb +67 -0
  94. data/lib/automateit/shell_manager/link.rb +24 -0
  95. data/lib/automateit/shell_manager/portable.rb +523 -0
  96. data/lib/automateit/shell_manager/symlink.rb +32 -0
  97. data/lib/automateit/shell_manager/which_base.rb +30 -0
  98. data/lib/automateit/shell_manager/which_unix.rb +16 -0
  99. data/lib/automateit/shell_manager/which_windows.rb +20 -0
  100. data/lib/automateit/tag_manager.rb +127 -0
  101. data/lib/automateit/tag_manager/struct.rb +121 -0
  102. data/lib/automateit/tag_manager/tag_parser.rb +93 -0
  103. data/lib/automateit/tag_manager/yaml.rb +29 -0
  104. data/lib/automateit/template_manager.rb +56 -0
  105. data/lib/automateit/template_manager/base.rb +181 -0
  106. data/lib/automateit/template_manager/erb.rb +17 -0
  107. data/lib/ext/metaclass.rb +17 -0
  108. data/lib/ext/object.rb +18 -0
  109. data/lib/ext/shell_escape.rb +7 -0
  110. data/lib/hashcache.rb +22 -0
  111. data/lib/helpful_erb.rb +63 -0
  112. data/lib/inactive_support.rb +53 -0
  113. data/lib/inactive_support/basic_object.rb +6 -0
  114. data/lib/inactive_support/clean_logger.rb +127 -0
  115. data/lib/inactive_support/core_ext/array/extract_options.rb +19 -0
  116. data/lib/inactive_support/core_ext/blank.rb +50 -0
  117. data/lib/inactive_support/core_ext/class/attribute_accessors.rb +48 -0
  118. data/lib/inactive_support/core_ext/class/inheritable_attributes.rb +140 -0
  119. data/lib/inactive_support/core_ext/enumerable.rb +63 -0
  120. data/lib/inactive_support/core_ext/hash/keys.rb +54 -0
  121. data/lib/inactive_support/core_ext/module/aliasing.rb +70 -0
  122. data/lib/inactive_support/core_ext/numeric/time.rb +91 -0
  123. data/lib/inactive_support/core_ext/string/inflections.rb +153 -0
  124. data/lib/inactive_support/core_ext/symbol.rb +14 -0
  125. data/lib/inactive_support/core_ext/time/conversions.rb +96 -0
  126. data/lib/inactive_support/duration.rb +96 -0
  127. data/lib/inactive_support/inflections.rb +53 -0
  128. data/lib/inactive_support/inflector.rb +282 -0
  129. data/lib/nested_error.rb +33 -0
  130. data/lib/nitpick.rb +33 -0
  131. data/lib/queued_logger.rb +68 -0
  132. data/lib/tempster.rb +250 -0
  133. data/misc/index_gem_repository.rb +304 -0
  134. data/misc/setup_egg.rb +12 -0
  135. data/misc/setup_gem_dependencies.sh +6 -0
  136. data/misc/setup_rubygems.sh +21 -0
  137. metadata +279 -0
@@ -0,0 +1,128 @@
1
+ # == AccountManager::Etc
2
+ #
3
+ # An AccountManager driver for Unix-like OSes that have the Ruby Etc module. It
4
+ # is only suitable for doing queries and lacks methods that perform
5
+ # modifications, such as +add_user+. Platform-specific drivers inherit from
6
+ # this class and provide methods that perform modifications.
7
+ class ::AutomateIt::AccountManager::Etc< ::AutomateIt::AccountManager::BaseDriver
8
+ depends_on :libraries => %w(etc),
9
+ :callbacks => lambda{
10
+ begin
11
+ ! ::Etc.getpwnam(::Etc.getlogin).nil?
12
+ rescue
13
+ false
14
+ end
15
+ }
16
+
17
+ def suitability(method, *args) # :nodoc:
18
+ return available? ? 1 : 0
19
+ end
20
+
21
+ #.......................................................................
22
+
23
+ # == UserQuery
24
+ #
25
+ # A class used for querying users. See AccountManager#users.
26
+ class UserQuery
27
+ # See AccountManager#users
28
+ def [](query)
29
+ ::Etc.endpwent
30
+ begin
31
+ case query
32
+ when String
33
+ return ::Etc.getpwnam(query)
34
+ when Fixnum
35
+ return ::Etc.getpwuid(query)
36
+ else
37
+ raise TypeError.new("unknonwn type for query: #{query.class}")
38
+ end
39
+ rescue ArgumentError
40
+ return nil
41
+ end
42
+ end
43
+ end
44
+
45
+ # See AccountManager#users
46
+ def users
47
+ return UserQuery.new
48
+ end
49
+
50
+ # See AccountManager#has_user?
51
+ def has_user?(query)
52
+ return ! users[query].nil?
53
+ end
54
+
55
+ #.......................................................................
56
+
57
+ # == GroupQuery
58
+ #
59
+ # A class used for querying groups. See AccountManager#groups.
60
+ class GroupQuery
61
+ # See AccountManager#groups
62
+ def [](query)
63
+ ::Etc.endgrent
64
+ begin
65
+ case query
66
+ when String
67
+ return ::Etc.getgrnam(query)
68
+ when Fixnum
69
+ return ::Etc.getgrgid(query)
70
+ else
71
+ raise TypeError.new("unknonwn type for query: #{query.class}")
72
+ end
73
+ rescue ArgumentError
74
+ return nil
75
+ end
76
+ end
77
+ end
78
+
79
+ # See AccountManager#groups
80
+ def groups
81
+ return GroupQuery.new
82
+ end
83
+
84
+ # See AccountManager#has_group?
85
+ def has_group?(query)
86
+ return ! groups[query].nil?
87
+ end
88
+
89
+ # See AccountManager#groups_for_user
90
+ def groups_for_user(query)
91
+ pwent = users[query]
92
+ return [] if preview? and not pwent
93
+ username = pwent.name
94
+ result = Set.new
95
+ result << groups[pwent.gid].name if groups[pwent.gid]
96
+ ::Etc.group do |grent|
97
+ result << grent.name if grent.mem.include?(username)
98
+ end
99
+ return result.to_a
100
+ end
101
+
102
+ # See AccountManager#users_for_group
103
+ def users_for_group(query)
104
+ grent = groups[query]
105
+ return (preview? || ! grent) ? [] : grent.mem
106
+ end
107
+
108
+ # See AccountManager#users_to_groups
109
+ def users_to_groups
110
+ result = {}
111
+ ::Etc.group do |grent|
112
+ grent.mem.each do |username|
113
+ result[username] ||= Set.new
114
+ result[username] << grent.name
115
+ end
116
+ end
117
+ ::Etc.passwd do |pwent|
118
+ grent = groups[pwent.gid]
119
+ unless grent
120
+ log.fatal(PNOTE+"WARNING: User's default group doesn't exist: user %s, gid %s" % [pwent.name, pwent.gid])
121
+ next
122
+ end
123
+ result[pwent.name] ||= Set.new
124
+ result[pwent.name] << grent.name
125
+ end
126
+ return result
127
+ end
128
+ end
@@ -0,0 +1,33 @@
1
+ # == AccountManager::NSCD
2
+ #
3
+ # AccountManager driver for invalidating records stored in the NSCD, Name
4
+ # Service Cache Daemon, found on Unix-like systems.
5
+ class ::AutomateIt::AccountManager::NSCD < ::AutomateIt::AccountManager::BaseDriver
6
+ depends_on :programs => %w(nscd ps),
7
+ # FIXME AccountManager.nscd - "ps -ef" isn't portable, may need to be "ps aux" or such
8
+ :callbacks => lambda{`ps -ef`.match(%r{/usr/sbin/nscd$})}
9
+
10
+ def suitability(method, *args) # :nodoc:
11
+ # Level must be higher than Portable
12
+ return available? ? 5 : 0
13
+ end
14
+
15
+ # Returns the NSCD database for the specified shorthand +query+.
16
+ def database_for(query)
17
+ case query.to_sym
18
+ when :user, :users, :passwd, :password
19
+ :passwd
20
+ when :group, :groups
21
+ :group
22
+ else
23
+ raise ArgumentError.new("Unknown cache database: #{query}")
24
+ end
25
+ end
26
+
27
+ # Invalidates the NSCD database, thus forcing a cache reload.
28
+ def invalidate(database)
29
+ return false unless available?
30
+
31
+ interpreter.sh("nscd -i #{database_for(database)}")
32
+ end
33
+ end
@@ -0,0 +1,40 @@
1
+ # == AccountManager::PasswdExpect
2
+ #
3
+ # An AccountManager driver for the +passwd+ command found on Unix-like systems
4
+ # using the +expect+ program as a wrapper because the Ruby PTY implementation
5
+ # is unreliable.
6
+ class ::AutomateIt::AccountManager::PasswdExpect < ::AutomateIt::AccountManager::BaseDriver
7
+ depends_on :programs => %w(passwd expect)
8
+
9
+ def suitability(method, *args) # :nodoc:
10
+ # Level must be higher than PasswdPTY
11
+ return available? ? 9 : 0
12
+ end
13
+
14
+ # See AccountManager#passwd
15
+ def passwd(user, password, opts={})
16
+ _passwd_helper(user, password, opts) do |user, password, opts|
17
+ log.silence(Logger::WARN) do
18
+ interpreter.mktemp do |filename|
19
+ # Script derived from /usr/share/doc/expect/examples/autopasswd
20
+ interpreter.render(:text => <<-HERE, :to => filename)
21
+ set password "#{password}"
22
+ spawn passwd "#{user}"
23
+ expect "assword:"
24
+ sleep 0.1
25
+ send "$password\\r"
26
+ expect "assword:"
27
+ sleep 0.1
28
+ send "$password\\r"
29
+ expect eof
30
+ HERE
31
+
32
+ cmd = "expect #{filename}"
33
+ cmd << " > /dev/null" if opts[:quiet]
34
+ return(interpreter.sh cmd)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+
@@ -0,0 +1,69 @@
1
+ # == AccountManager::PasswdPTY
2
+ #
3
+ # An AccountManager driver for +passwd+ command found on Unix-like systems
4
+ # using the Ruby PTY implementation.
5
+ #
6
+ # *WARNING*: The Ruby PTY module is unreliable or unavailable on most
7
+ # platforms. It may hang indefinitely or report incorrect results. Every
8
+ # attempt has been made to work around these problems, but this is a low-level
9
+ # problem. You are strongly encouraged to install the +expect+ program, which
10
+ # works flawlessly. Once the +expect+ program is installed, passwords will be
11
+ # changed using the AccountManager::PasswdExpect driver, which works properly.
12
+ class ::AutomateIt::AccountManager::PasswdPTY < ::AutomateIt::AccountManager::BaseDriver
13
+ depends_on \
14
+ :programs => %w(passwd uname),
15
+ :libraries => %w(open3 expect pty),
16
+ # Something is horribly wrong with Ruby PTY on Sun
17
+ :callbacks => lambda { `uname -s`.strip !~ /sunos|solaris|openbsd|freebsd/i }
18
+
19
+ def suitability(method, *args) # :nodoc:
20
+ # Level must be higher than Linux
21
+ return available? ? 3 : 0
22
+ end
23
+
24
+ # See AccountManager#passwd
25
+ def passwd(user, password, opts={})
26
+ log.info(PERROR+"Setting password with flaky Ruby PTY, which hangs or fails randomly. Install 'expect' (http://expect.nist.gov/) for reliable operation.")
27
+ _passwd_helper(user, password, opts) do
28
+ log.silence(Logger::WARN) do
29
+ interpreter.mktemp do |filename|
30
+ tries = 5
31
+ exitstatus = nil
32
+ begin
33
+ exitstruct = _passwd_raw(user, password, opts)
34
+ if exitstatus and not exitstruct.exitstatus.zero?
35
+ # FIXME AccountManager::Linux#passwd -- The `passwd` command randomly returns exit status 10 even when it succeeds. What does this mean and how to deal with it?! Temporary workaround is to throw an error and force a retry.
36
+ raise Errno::EPIPE.new("bad exitstatus %s" % exitstruct.exitstatus)
37
+ end
38
+ rescue Errno::EPIPE => e
39
+ # FIXME AccountManager::Linux#passwd -- EPIPE exception randomly thrown even when `passwd` succeeds. How to eliminate it? How to differentiate between this false error and a real one?
40
+ if tries <= 0
41
+ raise e
42
+ else
43
+ tries -= 1
44
+ retry
45
+ end
46
+ end
47
+ return exitstruct.exitstatus.zero?
48
+ end
49
+ end
50
+ end
51
+
52
+ end
53
+
54
+ def _passwd_raw(user, password, opts={})
55
+ quiet = (opts[:quiet] or not log.info?)
56
+
57
+ require 'open4'
58
+ return Open4::popen4("passwd %s 2>&1" % user) do |pid, sin, sout, serr|
59
+ $expect_verbose = ! quiet
60
+ 2.times do
61
+ sout.expect(/:/)
62
+ sleep 0.1 # Reduce chance of passwd thinking we're a robot :(
63
+ sin.puts password
64
+ puts "*" * 12 unless quiet
65
+ end
66
+ end
67
+ end
68
+ protected :_passwd_raw
69
+ end
@@ -0,0 +1,138 @@
1
+ # == AccountManager::POSIX
2
+ #
3
+ # A POSIX driver for the AccountManager.
4
+ class ::AutomateIt::AccountManager::POSIX < ::AutomateIt::AccountManager::BaseDriver
5
+ depends_on :programs => %w(useradd usermod userdel groupadd groupmod groupdel)
6
+
7
+ def suitability(method, *args) # :nodoc:
8
+ # Level must be higher than Portable
9
+ return available? ? 2 : 0
10
+ end
11
+
12
+ #.......................................................................
13
+
14
+ # See AccountManager#add_user
15
+ def add_user(username, opts={})
16
+ return _add_user_helper(username, opts) do |username, opts|
17
+ cmd = "useradd"
18
+ cmd << " -c #{opts[:description] || username}"
19
+ cmd << " -d #{opts[:home]}" if opts[:home]
20
+ cmd << " -m" unless opts[:create_home] == false
21
+ cmd << " -G #{opts[:groups].join(',')}" if opts[:groups]
22
+ cmd << " -s #{opts[:shell] || "/bin/bash"}"
23
+ cmd << " -u #{opts[:uid]}" if opts[:uid]
24
+ cmd << " -g #{opts[:gid]}" if opts[:gid]
25
+ cmd << " #{username} < /dev/null"
26
+ cmd << " > /dev/null 2>&1 | grep -v blocks" if opts[:quiet]
27
+ interpreter.sh(cmd)
28
+ end
29
+ end
30
+
31
+ # TODO AccountManager#update_user -- implement
32
+ ### def update_user(username, opts={}) dispatch(username, opts) end
33
+
34
+ # See AccountManager#remove_user
35
+ def remove_user(username, opts={})
36
+ return _remove_user_helper(username, opts) do |username, opts|
37
+ # Options: -r -- remove the home directory and mail spool
38
+ cmd = "userdel"
39
+ cmd << " -r" unless opts[:remove_home] == false
40
+ cmd << " #{username}"
41
+ cmd << " > /dev/null" if opts[:quiet]
42
+ interpreter.sh(cmd)
43
+ end
44
+ end
45
+
46
+ # See AccountManager#add_groups_to_user
47
+ def add_groups_to_user(groups, username)
48
+ return _add_groups_to_user_helper(groups, username) do |missing, username|
49
+ targets = (groups_for_user(username) + missing).uniq
50
+
51
+ cmd = "usermod -G #{targets.join(',')} #{username}"
52
+ interpreter.sh(cmd)
53
+ end
54
+ end
55
+
56
+ # See AccountManager#remove_groups_from_user
57
+ def remove_groups_from_user(groups, username)
58
+ return _remove_groups_from_user_helper(groups, username) do |present, username|
59
+ matches = (groups_for_user(username) - [groups].flatten).uniq
60
+ cmd = "usermod -G #{matches.join(',')} #{username}"
61
+ interpreter.sh(cmd)
62
+ end
63
+ end
64
+
65
+ #.......................................................................
66
+
67
+ # See AccountManager#add_group
68
+ def add_group(groupname, opts={})
69
+ modified = false
70
+ unless has_group?(groupname)
71
+ modified = true
72
+
73
+ cmd = "groupadd"
74
+ cmd << " -g #{opts[:gid]}" if opts[:gid]
75
+ cmd << " #{groupname}"
76
+ interpreter.sh(cmd)
77
+
78
+ manager.invalidate(:groups)
79
+ end
80
+
81
+ if opts[:members]
82
+ modified = true
83
+ add_users_to_group(opts[:members], groupname)
84
+ end
85
+
86
+ return modified ? groups[groupname] : false
87
+ end
88
+
89
+ # TODO AccountManager#update_group -- implement
90
+ ### def update_group(groupname, opts={}) dispatch(groupname, opts) end
91
+
92
+ # See AccountManager#remove_group
93
+ def remove_group(groupname, opts={})
94
+ return false unless has_group?(groupname)
95
+ cmd = "groupdel #{groupname}"
96
+ interpreter.sh(cmd)
97
+
98
+ manager.invalidate(:groups)
99
+
100
+ return true
101
+ end
102
+
103
+ # See AccountManager#add_users_to_group
104
+ def add_users_to_group(users, groupname)
105
+ _add_users_to_group_helper(users, groupname) do |missing, groupname|
106
+ for username in missing
107
+ targets = (groups_for_user(username) + [groupname]).uniq
108
+ cmd = "usermod -G #{targets.join(',')} #{username}"
109
+ interpreter.sh(cmd)
110
+ end
111
+ end
112
+ end
113
+
114
+ # See AccountManager#remove_users_from_group
115
+ def remove_users_from_group(users, groupname)
116
+ _remove_users_from_group_helper(users, groupname) do |present, groupname|
117
+ u2g = users_to_groups
118
+ for username in present
119
+ user_groups = u2g[username]
120
+ # FIXME tries to include non-present groups, should use some variant of present
121
+ cmd = "usermod -G #{(user_groups.to_a-[groupname]).join(',')} #{username}"
122
+ interpreter.sh(cmd)
123
+ end
124
+ end
125
+ end
126
+
127
+ # Dispatch common names to Etc, but don't define these methods here because
128
+ # that would make available? and suitability think these exist, when in fact,
129
+ # they're just wrappers.
130
+ def method_missing(symbol, *args, &block)
131
+ case symbol
132
+ when :users, :has_user?, :groups, :has_group?, :groups_for_user, :users_for_group, :users_to_groups
133
+ manager.send(symbol, *args, &block)
134
+ else
135
+ super(symbol, *args, &block)
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,88 @@
1
+ # == AddressManager
2
+ #
3
+ # The AddressManager provides a way to query, add and remove network
4
+ # addresses on a host.
5
+ class AutomateIt::AddressManager < AutomateIt::Plugin::Manager
6
+ # Does host have an address or interface? Arguments hash must include
7
+ # either a :device (e.g., "eth0") or :address (e.g., "10.0.0.10"), and an
8
+ # optional :label (e.g., "foo"). Note that an interface is the combination
9
+ # of a :device and :label, so "eth0" isn't the same as "eth0:foo".
10
+ #
11
+ # Examples on a host with address "10.0.0.10" on interface "eth0:foo":
12
+ # has?(:address => "10.0.0.10")
13
+ # => true
14
+ # has?(:address => "10.0.0.10", :device => "eth0")
15
+ # => false
16
+ # has?(:address => "10.0.0.10", :device => "eth0", :label => "foo")
17
+ # => true
18
+ # has?(:device => "eth0")
19
+ # => false
20
+ # has?(:device => "eth0", :label => "foo")
21
+ # => true
22
+ def has?(opts) dispatch(opts) end
23
+
24
+ # Add address to host if it doesn't have it. Requires root-level access.
25
+ # Returns +true+ if action was taken and succeeded.
26
+ #
27
+ # Arguments hash must include either a :device (e.g., "eth0") or :address
28
+ # (e.g., "10.0.0.10"), and an optional :label (e.g., "foo") and :mask (e.g.
29
+ # "24").
30
+ #
31
+ # An optional number of ARP :announcements may be specified, defaulting to
32
+ # AutomateIt::AddressManager::DEFAULT_ANNOUNCEMENTS. Drivers that handle
33
+ # announcements will block an extra second while making each announcement.
34
+ #
35
+ # Example:
36
+ # add(:address => "10.0.0.10", :mask => 24, :device => "eth0",
37
+ # :label => "foo", :announcements => 3)
38
+ def add(opts) dispatch(opts) end
39
+
40
+ # Number of ARP announcements to make by default during #add.
41
+ DEFAULT_ANNOUNCEMENTS = 3
42
+
43
+ # Remove address from host if it has it. Requires root-level access.
44
+ # Returns +true+ if action was taken and succeeded.
45
+ #
46
+ # Arguments hash must include either a :device (e.g., "eth0") or :address
47
+ # (e.g., "10.0.0.10"), and an optional :label (e.g., "foo") and :mask (e.g.
48
+ # "24").
49
+ #
50
+ # Example:
51
+ # remove(:address => "10.0.0.10", :mask => 24, :device => "eth0",
52
+ # :label => "foo")
53
+ def remove(opts) dispatch(opts) end
54
+
55
+ # Array of addresses for this host. Example:
56
+ # addresses
57
+ # => ["10.0.0.10", "127.0.0.1"]
58
+ def addresses() dispatch() end
59
+
60
+ # Array of interfaces for this host. Example:
61
+ # interfaces
62
+ # => ["eth0", "lo"]
63
+ def interfaces() dispatch() end
64
+
65
+ # Array of hostnames for this host, including variants by trying to resolve
66
+ # names for all addresses owned by this host. Example:
67
+ # hostnames
68
+ # => ["kagami", "kagami.lucky-channel", "kagami.lucky-channel.jp"]
69
+ def hostnames() dispatch() end
70
+
71
+ # Array of hostname variants for this +hostname+. This method performs no
72
+ # name resolution and simply infers a less qualified name from a more
73
+ # qualified hostname argument. Example:
74
+ # hostnames_for("kagami.lucky-channel")
75
+ # => ["kagami", "kagami.lucky-channel"]
76
+ # hostnames_for("kagami")
77
+ # => ["kagami"]
78
+ def hostnames_for(hostname) dispatch(hostname) end
79
+ end
80
+
81
+ # Drivers
82
+ require 'automateit/address_manager/base'
83
+ require 'automateit/address_manager/portable'
84
+ require 'automateit/address_manager/bsd'
85
+ require 'automateit/address_manager/linux'
86
+ require 'automateit/address_manager/sunos'
87
+ require 'automateit/address_manager/openbsd'
88
+ require 'automateit/address_manager/freebsd'