├── .config
└── cucumber.yml
├── .gitignore
├── CHANGELOG.adoc
├── Gemfile
├── LICENSE
├── MAINTAINERS
├── README.adoc
├── Rakefile
├── features
├── proxy.feature
├── registration.feature
├── step_definitions
│ ├── proxy_steps.rb
│ └── registration_steps.rb
└── support
│ └── env.rb
├── lib
├── vagrant-registration.rb
└── vagrant-registration
│ ├── action.rb
│ ├── action
│ ├── register.rb
│ ├── unregister_on_destroy.rb
│ └── unregister_on_halt.rb
│ ├── config.rb
│ ├── plugin.rb
│ └── version.rb
├── locales
└── en.yml
├── plugins
└── guests
│ └── redhat
│ ├── cap
│ ├── registration.rb
│ ├── rhn_register.rb
│ └── subscription_manager.rb
│ └── plugin.rb
├── resources
└── rhn_unregister.py
├── test
├── support
│ └── fake_ui.rb
├── test_helper.rb
└── vagrant-registration
│ └── cap
│ └── redhat
│ ├── rhn_register_test.rb
│ └── subscription_manager_test.rb
└── vagrant-registration.gemspec
/.config/cucumber.yml:
--------------------------------------------------------------------------------
1 | # config/cucumber.yml
2 | ##YAML Template
3 | ---
4 | default: --profile html
5 |
6 | pretty: --format pretty -b
7 | html: --format progress --format html --out=build/features_report.html -b
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.gem
2 | *.rbc
3 | *~
4 | *.swp
5 | /coverage/
6 | /InstalledFiles
7 | /spec/reports/
8 | /pkg/
9 | /test/tmp/
10 | /test/version_tmp/
11 | /tmp/
12 | .idea/
13 | *.iml
14 |
15 | ## Specific to RubyMotion:
16 | .dat*
17 | .repl_history
18 | build/
19 |
20 | ## Documentation cache and generated files:
21 | /.yardoc/
22 | /_yardoc/
23 | /doc/
24 | /rdoc/
25 |
26 | ## Environment normalisation:
27 | /.bundle/
28 | /lib/bundler/man/
29 |
30 | # for a library or gem, you might want to ignore these files since the code is
31 | # intended to run in multiple environments; otherwise, check them in:
32 | Gemfile.lock
33 | .ruby-version
34 | .ruby-gemset
35 |
36 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
37 | .rvmrc
38 |
--------------------------------------------------------------------------------
/CHANGELOG.adoc:
--------------------------------------------------------------------------------
1 | = Revision History
2 | :toc:
3 |
4 | [[section]]
5 | == 1.3.1
6 |
7 | * Fix #111 Default response (yes) for registration prompt not working
8 | * Fixing rhn_register upload certificate fail #114
9 | * Converted docs from markdown to asciidoc and format tweaks
10 | * Fix #117 Updating gemspec file after doc format changes to adoc
11 |
12 | [[section-1]]
13 | == 1.3.0
14 |
15 | * Fixed formatting, typo, grammar in README
16 | * Added MAINTAINERS file
17 | * Fix #44 allow more than one try to fill username and password
18 | * Fixes #99 using proxy info to unregister
19 | * Fix #107 register when passing credentials as env variables
20 |
21 | [[section-2]]
22 | == 1.2.3
23 |
24 | * Issue #90 Use locale based messaging
25 | * Issue #65 Adding cucumber tests for proxy settings
26 | * Issue #65 Adding proxy options to rhn_register and
27 | subscription_manager
28 | * Adding minitest as unit test framework and setting up basic test
29 | harness for Vagrant plugins
30 | * Issue #65 Removing obsolete bash tests
31 |
32 | [[section-3]]
33 | == 1.2.2
34 |
35 | * Introducing Cucumber based acceptance tests.
36 | * Fix: Handling of vagrant-registration action hooks depending on
37 | provider used.
38 |
39 | [[section-4]]
40 | == 1.2.1
41 |
42 | * Fix regression: Use sudo when asking on registration managers being
43 | present
44 |
45 | [[section-5]]
46 | == 1.2.0
47 |
48 | * Fix: `vagrant destroy` not triggering subscription deactivation and
49 | removal, issue #57
50 | * Fix: Allow auto-attach and force options to be configured
51 | * Fix: Remove unnecessary shebang from python script
52 | * Support for attaching to specified subscription pool(s), issue #36
53 | * Fix: rhn_register upload certificate fails, issue #60
54 |
55 | [[section-6]]
56 | == 1.1.0
57 |
58 | * Print warning if specifically selected manager is not available
59 | * Support running alongside vagrant-vbguest, issue #40
60 | * Support rhn_register manager
61 | * Fix: Handle various types of configuration option values, issue #48
62 | * Fix: Hide password on registration failure, issue #47
63 |
64 | [[section-7]]
65 | == 1.0.1
66 |
67 | * Fix: Set repo_ca_cert option in /etc/rhsm/rhsm.conf after uploading a
68 | certificate
69 |
70 | [[section-8]]
71 | == 1.0.0
72 |
73 | * Support providing a CA certificate via `config.registration.ca_cert`
74 | option
75 | * Issue warnings on unsupported configuration options
76 | * Do not ship tests
77 |
78 | [[section-9]]
79 | == 0.0.19
80 |
81 | * Remove extra files from installation
82 |
83 | [[section-20]]
84 | == 0.0.18
85 |
86 | * Support `config.registration.unregister_on_halt` option
87 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | group :development do
4 | gem 'vagrant',
5 | :git => 'git://github.com/mitchellh/vagrant.git',
6 | :ref => 'v1.9.8'
7 |
8 | # test dependencies
9 | gem 'minitest'
10 | gem 'mocha'
11 |
12 | gem 'cucumber', '~> 2.1'
13 | gem 'aruba', '~> 0.13'
14 | gem 'komenda', '~> 0.1.6'
15 | gem 'launchy'
16 | gem 'gem-compare'
17 | gem 'mechanize'
18 |
19 | # build tool
20 | gem 'rake'
21 | gem 'yard'
22 |
23 | # virtualization providers (for testing)
24 | gem 'vagrant-vbguest'
25 | gem 'vagrant-libvirt' if RUBY_PLATFORM =~ /linux/i
26 | gem 'fog-libvirt', '0.0.3' if RUBY_PLATFORM =~ /linux/i # https://github.com/pradels/vagrant-libvirt/issues/568
27 | end
28 |
29 | group :plugins do
30 | gem 'vagrant-registration', path: '.'
31 | end
32 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 | {description}
294 | Copyright (C) {year} {fullname}
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | {signature of Ty Coon}, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
--------------------------------------------------------------------------------
/MAINTAINERS:
--------------------------------------------------------------------------------
1 | Project/Code Maintainers
2 | ------------------------
3 | - Josef Strzibny @strzibny
4 | - Langdon White @whitel
5 | - Pavel Valena @pvalena
6 | - Lalatendu Mohanty @LalatenduMohanty
7 | - Hardy Ferentschik @hferentschik
8 | - Budh Ram Gurung @budhrg
9 |
--------------------------------------------------------------------------------
/README.adoc:
--------------------------------------------------------------------------------
1 | [[vagrant-registration]]
2 | = vagrant-registration
3 | :toc:
4 | :toc-placement!:
5 |
6 | The vagrant-registration plugin for Vagrant allows developers to easily
7 | register their guests for updates on systems with a subscription model
8 | (like Red Hat Enterprise Linux).
9 |
10 | This plugin would run _register_ action on `vagrant up` before any
11 | provisioning and _unregister_ on `vagrant halt` or `vagrant destroy`.
12 | The actions then call the registration capabilities that have to be
13 | provided for the given OS.
14 |
15 | '''
16 | toc::[]
17 | '''
18 |
19 | == Installation
20 |
21 | Install vagrant-registration as any other Vagrant plugin:
22 |
23 | [source,shell]
24 | ----
25 | $ vagrant plugin install vagrant-registration
26 | ----
27 |
28 | If you are on Fedora, you can install the packaged version of the plugin
29 | by running:
30 |
31 | [source,shell]
32 | ----
33 | # dnf install vagrant-registration
34 | ----
35 |
36 | == Usage
37 |
38 | The plugin is designed in a registration-manager agnostic way, which
39 | means, that the plugin itself, depends neither on any OS nor on the way
40 | of registration. The vagrant-registration plugin only calls registration
41 | capabilities for the given guest, passes the configuration options to
42 | them and handles interactive registration.
43 |
44 | That being said, this plugin currently ships only with registration
45 | capability files for RHEL's Subscription Manager and `rhn_register`.
46 | Feel free to submit others.
47 |
48 | To configure the plugin, always include the configuration options
49 | mentioned in this file within the following configuration block in your
50 | Vagrantfile.
51 |
52 | ....
53 | Vagrant.configure('2') do |config|
54 | ...
55 | end
56 | ....
57 |
58 | === General Configuration
59 |
60 | * *skip* skips the registration. If you wish to skip the registration
61 | process altogether, you can do so by setting a `skip` option to `true`:
62 |
63 | [source,ruby]
64 | ----
65 | config.registration.skip = true
66 | ----
67 |
68 | * *unregister_on_halt* disables or enables automatic unregistration on
69 | halt (on shut down). By default the plugin unregisters on halt, you can
70 | however change that by setting the option to `false` so that the box
71 | will unregister only on destroy:
72 |
73 | [source,ruby]
74 | ----
75 | config.registration.unregister_on_halt = false
76 | ----
77 |
78 | * *manager* selects the registration manager provider. By default the
79 | plugin will use the `subscription_manager` as the registration manager
80 | provider. You can however, change that by setting the option to a
81 | different manager:
82 |
83 | [source,ruby]
84 | ----
85 | config.registration.manager = 'subscription_manager'
86 | ----
87 |
88 | === Credential Configuration
89 |
90 | You can set up the credentials as follows:
91 |
92 | [source,ruby]
93 | ----
94 | Vagrant.configure('2') do |config|
95 | ...
96 | if Vagrant.has_plugin?('vagrant-registration')
97 | config.registration.username = 'foo'
98 | config.registration.password = 'bar'
99 | end
100 |
101 | # Alternatively
102 | if Vagrant.has_plugin?('vagrant-registration')
103 | config.registration.org = 'foo'
104 | config.registration.activationkey = 'bar'
105 | end
106 | ...
107 | end
108 | ----
109 |
110 | This should go, preferably, into the Vagrantfile in your Vagrant home
111 | directory (defaults to ~/.vagrant.d), to make it available for every
112 | project. It can be later overridden in an individual project's
113 | Vagrantfile if needed.
114 |
115 | If you prefer not to store your username and/or password on your
116 | filesystem, you can optionally configure vagrant-registration plugin to
117 | use environment variables such as:
118 |
119 | [source,ruby]
120 | ----
121 | Vagrant.configure('2') do |config|
122 | ...
123 | config.registration.username = ENV['SUB_USERNAME']
124 | config.registration.password = ENV['SUB_PASSWORD']
125 | ...
126 | end
127 | ----
128 |
129 | If you do not configure your credentials as outlined above, you will
130 | receive a maximum of 3 prompts for them during the `vagrant up` process.
131 |
132 | Please note that the interactive mode asks you for the preferred
133 | registration pair only for the configured manager.
134 |
135 | === HTTP Proxy Configuration
136 |
137 | HTTP Proxy can be configured via the __proxy__, _proxyUser_ and
138 | _proxyPassword_ configuration options:
139 |
140 | [source,ruby]
141 | ----
142 | Vagrant.configure('2') do |config|
143 | ...
144 | if Vagrant.has_plugin?('vagrant-registration')
145 | config.registration.proxy = 'mongo:8080'
146 | config.registration.proxyUser = 'flash'
147 | config.registration.proxyPassword = 'zarkov'
148 | end
149 | ...
150 | end
151 | ----
152 |
153 | As described in the link:#credentials-configuration[credentials
154 | configuration] section, these settings can be placed either into the
155 | Vagrantfile in the Vagrant home directory or provided as environment
156 | variables.
157 |
158 | === subscription-manager Configuration
159 |
160 | The vagrant-registration plugin uses `subscription_manager` as the
161 | default manager. This can also be explicitly configured by setting the
162 | `manager` option to `subscription_manager`:
163 |
164 | [source,ruby]
165 | ----
166 | Vagrant.configure('2') do |config|
167 | ...
168 | if Vagrant.has_plugin?('vagrant-registration')
169 | config.registration.manager = 'subscription_manager'
170 | end
171 | ...
172 | end
173 | ----
174 |
175 | In case you choose `subscription_manager` as the manager, you would be
176 | asked for your user credentials, such as the username and password.
177 |
178 | The vagrant-registration plugin supports all the options for the
179 | subscription-manager's register command. You can set any option easily
180 | by setting `config.registration.OPTION_NAME = 'OPTION_VALUE'` in your
181 | Vagrantfile (please see the subscription-manager's documentation for
182 | option description).
183 |
184 | ==== subscription-manager Default Options
185 |
186 | * **--force**: Subscription Manager will fail if you attempt to register
187 | an already registered machine (see the man page for explanation),
188 | therefore vagrant-registration appends the `--force` flag automatically
189 | when subscribing. If you would like to disable this feature, set `force`
190 | option to `false`:
191 |
192 | [source,ruby]
193 | ----
194 | config.registration.force = false
195 | ----
196 |
197 | * **--auto-attach**: Vagrant would fail to install packages on
198 | registered RHEL system if the subscription is not attached, therefore
199 | vagrant-registration appends the `--auto-attach` flag automatically when
200 | subscribing. To disable this option, set `auto_attach` option to
201 | `false`:
202 |
203 | [source,ruby]
204 | ----
205 | config.registration.auto_attach = false
206 | ----
207 |
208 | Note that the `auto_attach` option is set to false when using
209 | org/activationkey for registration or if pools are specified.
210 |
211 | ==== subscription-manager Options Reference
212 |
213 | [source,ruby]
214 | ----
215 | # The username to subscribe with (required)
216 | config.registration.username
217 |
218 | # The password of the subscriber (required)
219 | config.registration.password
220 |
221 | # Give the hostname of the subscription service to use (required for Subscription
222 | # Asset Manager, defaults to Customer Portal Subscription Management)
223 | config.registration.serverurl
224 |
225 | # A path to a CA certificate, this file would be copied to /etc/rhsm/ca and
226 | # if the file does not have .pem extension, it will be automatically added
227 | config.registration.ca_cert
228 |
229 | # Give the hostname of the content delivery server to use to receive updates
230 | # (required for Satellite 6)
231 | config.registration.baseurl
232 |
233 | # Give the organization to which to join the system (required, except for
234 | # hosted environments)
235 | config.registration.org
236 |
237 | # Register the system to an environment within an organization (optional)
238 | config.registration.environment
239 |
240 | # Name of the subscribed system (optional, defaults to hostname if unset)
241 | config.registration.name
242 |
243 | # Auto attach suitable subscriptions (optional, auto attach if true,
244 | # defaults to true)
245 | config.registration.auto_attach
246 |
247 | # Attach existing subscriptions as part of the registration process (optional)
248 | config.registration.activationkey
249 |
250 | # Set the service level to use for subscriptions on that machine
251 | # (optional, used only used with the --auto-attach)
252 | config.registration.servicelevel
253 |
254 | # Set the operating system minor release to use for subscriptions for
255 | # the system (optional, used only used with the --auto-attach)
256 | config.registration.release
257 |
258 | # Force the registration (optional, force if true, defaults to true)
259 | config.registration.force
260 |
261 | # Set what type of consumer is being registered (optional, defaults to system)
262 | config.registration.type
263 |
264 | # Skip the registration (optional, skip if true, defaults to false)
265 | config.registration.skip
266 |
267 | # Specify a HTTP proxy to use. This config option if of the format [|:], eg mongo:8080
268 | config.registration.proxy
269 |
270 | # Specify a username to use with an authenticated HTTP proxy
271 | config.registration.proxyUser
272 |
273 | # Specify a password to use with an authenticated HTTP proxy
274 | config.registration.proxyPassword
275 |
276 | # Attach to specified pool(s) (optional)
277 | #
278 | # Example:
279 | # config.registration.pools = [ 'POOL-ID-1', 'POOL-ID-2' ]
280 | config.registration.pools
281 | ----
282 |
283 | === rhn-register Configuration
284 |
285 | vagrant-registration will use the `rhn_register` manager only if
286 | explicitly configured by setting the `manager` option to `rhn_register`:
287 |
288 | [source,ruby]
289 | ----
290 | Vagrant.configure('2') do |config|
291 | ...
292 | if Vagrant.has_plugin?('vagrant-registration')
293 | config.registration.manager = 'rhn_register'
294 | end
295 | ...
296 | end
297 | ----
298 |
299 | In case of a `rhn_register` manager, the preferred registration pair is
300 | the username/password/serverurl combination.
301 |
302 | vagrant-registration supports most of the options of rhnreg_ks's
303 | command. You can set any option easily by setting
304 | `config.registration.OPTION_NAME = 'OPTION_VALUE'` in your Vagrantfile
305 | (please see the `rhnreg_ks`'s documentation for option description).
306 |
307 | `rhn_register` manager reuses the naming of `subscription-manager`'s
308 | command options where possible.
309 |
310 | ==== rhn-register Default Options
311 |
312 | * **--force**: `rhnreg_ks` command will fail if you attempt to register
313 | an already registered machine (see the man page for explanation),
314 | therefore vagrant-registration appends the `--force` flag automatically
315 | when subscribing. If you would like to disable this feature, set `force`
316 | option to `false`:
317 |
318 | [source,ruby]
319 | ----
320 | config.registration.force = false
321 | ----
322 |
323 | ==== rhn-register Options Reference
324 |
325 | [source,ruby]
326 | ----
327 | # The username to register the system with under Spacewalk Server, Red Hat Satellite or
328 | # Red Hat Network Classic. This can be an existing Spacewalk, Red Hat Satellite or
329 | # Red Hat Network Classic username, or a new user‐name.
330 | config.registration.username
331 |
332 | # The password associated with the username specified with the `--username` option.
333 | # This is an unencrypted password.
334 | config.registration.password
335 |
336 | # Give the URL of the subscription service to use (required for registering a
337 | # system with the "Spacewalk Server", "Red Hat Satellite" or "Red Hat Network Classic").
338 | # The configuration name is mapped to the `--serverUrl` option of rhnreg_ks command.
339 | #
340 | # The serverurl is mandatory and if you do not provide a value,
341 | # you will be prompted for them in the "up process."
342 | config.registration.serverurl
343 |
344 | # A path to a CA certificate file (optional)
345 | # The configuration name is mapped to the `--sslCACert` option of rhnreg_ks command.
346 | #
347 | # The CA certificate file is be uploaded to /usr/share/rhn/ in guest
348 | # and the configuration in `/etc/sysconfig/rhn/up2date` is updated to:
349 | # `sslCACert=/usr/share/rhn/`
350 | #
351 | # As default only the configuration in `/etc/sysconfig/rhn/up2date` is updated
352 | # to point to the CA certificate file that is present on Fedora, CentOS and RHEL:
353 | # `sslCACert=/usr/share/rhn/RHNS-CA-CERT`
354 | config.registration.ca_cert
355 |
356 | # Give the organization to which to join the system (required, except for
357 | # hosted environments)
358 | # The configuration name is mapped to the `--systemorgid` option of rhnreg_ks command.
359 | config.registration.org
360 |
361 | # Name of the subscribed system (optional, defaults to hostname if unset)
362 | # The configuration name is mapped to the `--profilename` option of rhnreg_ks command.
363 | config.registration.name
364 |
365 | # Attach existing subscriptions as part of the registration process (optional)
366 | config.registration.activationkey
367 |
368 | # Subscribe this system to the EUS channel tied to the system's redhat-release (optional)
369 | config.registration.use_eus_channel
370 |
371 | # Do not probe or upload any hardware info (optional)
372 | config.registration.nohardware
373 |
374 | # Do not profile or upload any package info (optional)
375 | config.registration.nopackages
376 |
377 | # Do not upload any virtualization info (optional)
378 | config.registration.novirtinfo
379 |
380 | # Do not start rhnsd after completion (optional)
381 | config.registration.norhnsd
382 |
383 | # Force the registration (optional, force if true, defaults to true)
384 | config.registration.force
385 |
386 | # Skip the registration (optional, skip if true, defaults to false)
387 | config.registration.skip
388 |
389 | # Specify a HTTP proxy to use. This config option if of the format [|:], eg mongo:8080
390 | config.registration.proxy
391 |
392 | # Specify a username to use with an authenticated HTTP proxy
393 | config.registration.proxyUser
394 |
395 | # Specify a password to use with an authenticated HTTP proxy
396 | config.registration.proxyPassword
397 | ----
398 |
399 | == Development
400 |
401 | The use of https://rvm.io[RVM] is recommended. Verified to work with ruby-2.2.10.
402 |
403 | ....
404 | rvm install 2.2
405 | rvm use 2.2
406 | ....
407 |
408 | To install a development environment, clone the repo and prepare
409 | dependencies by:
410 |
411 | ....
412 | gem install bundler
413 | bundle install
414 | ....
415 |
416 | === Tests
417 |
418 | ==== Minitest
419 |
420 | The source contains a set of
421 | http://ruby-doc.org/stdlib-2.0.0/libdoc/minitest/rdoc/MiniTest.html[Minitest]
422 | based unit tests. They can be run via:
423 |
424 | ....
425 | $ bundle exec rake test
426 | ....
427 |
428 | ==== Acceptance tests
429 |
430 | The source also contains a set of https://cucumber.io/[Cucumber] based
431 | acceptance tests. They can be run via:
432 |
433 | ....
434 | $ bundle exec rake features
435 | ....
436 |
437 | The tests assume that the CDK box files are available under
438 | __build/boxes/cdk-.box__. You can either copy the box files
439 | manually or use the _get_cdk_ rake task to download them.
440 |
441 | As per default, only the scenarios for CDK in combination with
442 | VirtualBox are run. You can also run the tests against Libvirt, using
443 | the environment variable __PROVIDER__:
444 |
445 | ....
446 | # Run tests against Libvirt
447 | $ bundle exec rake features PROVIDER=libvirt
448 |
449 | # Run against VirtualBox and Libvirt
450 | $ bundle exec rake features PROVIDER=virtualbox,libvirt
451 | ....
452 |
453 | You can also run a single feature specifying the explicit feature file
454 | to use:
455 |
456 | ....
457 | $ bundle exec rake features FEATURE=features/.feature
458 | ....
459 |
460 | After test execution the acceptance test reports can be found under
461 | __build/features_report.html__. They can also be opened via:
462 |
463 | ....
464 | $ bundle exec rake features:open_report
465 | ....
466 |
467 | == Releasing
468 |
469 | To release a new version of vagrant-registration you will need to do the following:
470 |
471 | *(only contributors of the GitHub repo and owners of the project at RubyGems will have rights to do this)*
472 |
473 | 1. First, bump, commit, and push the version in ~/lib/vagrant-registration/version.rb:
474 | * Follow [Semantic Versioning](http://semver.org/).
475 | 2. Then, create a matching GitHub Release (this will also create a tag):
476 | * Preface the version number with a `v`.
477 | * https://github.com/projectatomic/adb-vagrant-registration/releases
478 | 3. You will then need to build and push the new gem to RubyGems:
479 | * `rake build`
480 | * `gem push pkg/vagrant-registration-1.3.2.gem`
481 | 4. Then, when John Doe runs the following, they will receive the updated vagrant-registration plugin:
482 | * `vagrant plugin update`
483 | * `vagrant plugin update vagrant-registration`
484 |
485 | == Acknowledgements
486 |
487 | The project would like to make sure we thank
488 | https://github.com/purpleidea/[purpleidea],
489 | https://github.com/humaton/[humaton],
490 | https://github.com/strzibny[strzibny],
491 | https://github.com/scollier/[scollier],
492 | https://github.com/puzzle[puzzle], https://github.com/voxik[voxik],
493 | https://github.com/lukaszachy[lukaszachy],
494 | https://github.com/goern[goern],
495 | https://github.com/iconoeugen[iconoeugen] and
496 | https://github.com/pvalena[pvalena] (in no particular order) for their
497 | contributions of ideas, code and testing for this project.
498 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require 'bundler/gem_tasks'
2 | require 'rake/clean'
3 | require 'rake/testtask'
4 | require 'cucumber/rake/task'
5 | require 'yard'
6 | require 'rubygems/comparator'
7 | require 'launchy'
8 | require 'mechanize'
9 | require 'fileutils'
10 |
11 | CLOBBER.include('pkg')
12 | CLEAN.include('build')
13 |
14 | # Documentation
15 | YARD::Rake::YardocTask.new do |t|
16 | t.files = ['lib/**/*.rb', 'plugins/**/*.rb']
17 | t.options = []
18 | t.stats_options = ['--list-undoc']
19 | end
20 |
21 | task :init do
22 | FileUtils.mkdir_p 'build'
23 | end
24 |
25 | # Default test task
26 | desc 'Run all unit tests'
27 | Rake::TestTask.new do |t|
28 | t.pattern = 'test/**/*_test.rb'
29 | t.libs << 'test'
30 | end
31 |
32 | # Cucumber acceptance test tasks
33 | Cucumber::Rake::Task.new(:features)
34 | task :features => :init
35 |
36 | namespace :features do
37 | desc 'Opens the HTML Cucumber test report'
38 | task :open_report do
39 | Launchy.open('./build/features_report.html')
40 | end
41 | end
42 |
43 | # Compare latest release with current git head
44 | task compare: [:clean, :build] do
45 | git_version = VagrantPlugins::Registration::VERSION
46 | options = {}
47 | options[:output] = 'pkg'
48 | options[:keep_all] = true
49 | comparator = Gem::Comparator.new(options)
50 | comparator.compare_versions('vagrant-registration', ['_', git_version])
51 | comparator.print_results
52 | end
53 |
54 | desc 'Download CDK Vagrant box using the specified provider (default \'virtualbox\')'
55 | task :get_cdk, [:provider] do |t, args|
56 | provider = args[:provider].nil? ? 'virtualbox' : args[:provider]
57 | agent = Mechanize.new
58 | agent.follow_meta_refresh = true
59 | agent.get(CDK_DOWNLOAD_URL) do |page|
60 |
61 | # Submit first form which is the redirect to login page form
62 | login_page = page.forms.first.submit
63 |
64 | # Submit the login form
65 | after_login = login_page.form_with(:name => 'login_form') do |f|
66 | username_field = f.field_with(:id => 'username')
67 | username_field.value = 'service-manager@mailinator.com'
68 | password_field = f.field_with(:id => 'password')
69 | password_field.value = 'service-manager'
70 | end.click_button
71 |
72 | # There is one more redirect after successful login
73 | download_page = after_login.forms.first.submit
74 |
75 | download_page.links.each do |link|
76 | if link.href =~ /#{Regexp.quote(CDK_BOX_BASE_NAME)}-#{Regexp.quote(provider)}.box/
77 | download_dir = File.join(File.dirname(__FILE__), 'build', 'boxes')
78 | unless File.directory?(download_dir)
79 | FileUtils.mkdir_p(download_dir)
80 | end
81 | agent.pluggable_parser.default = Mechanize::Download
82 | puts "Downloading #{link.href}"
83 | agent.get(link.href).save(File.join(download_dir, "cdk-#{provider}.box"))
84 | end
85 | end
86 | end
87 | end
88 | task :get_cdk => :init
89 |
--------------------------------------------------------------------------------
/features/proxy.feature:
--------------------------------------------------------------------------------
1 | Feature: Booting VM with various proxy settings
2 |
3 | @needs-proxy
4 | Scenario Outline: Test valid proxy configuration
5 | Given provider is
6 | And a file named "Vagrantfile" with:
7 | """
8 | begin
9 | require 'vagrant-libvirt'
10 | rescue LoadError
11 | # NOOP
12 | end
13 |
14 | Vagrant.configure(2) do |config|
15 | config.vm.box = 'cdk'
16 | config.vm.box_url = 'file://../boxes/cdk-.box'
17 | config.vm.network :private_network, ip: '10.10.10.123'
18 | config.vm.synced_folder '.', '/vagrant', disabled: true
19 |
20 | config.registration.username = 'service-manager@mailinator.com'
21 | config.registration.password = 'service-manager'
22 | config.registration.proxy = '10.10.10.1:8888'
23 | config.registration.proxyUser = 'validUser'
24 | config.registration.proxyPassword = ''
25 | end
26 | """
27 |
28 | When I run `bundle exec vagrant up --provider `
29 | Then registration
30 |
31 | Examples:
32 | | provider | password | expectation |
33 | | virtualbox | validPass | should be successful |
34 | | virtualbox | invalidPass | should not be successful |
35 | | libvirt | validPass | should be successful |
36 | | libvirt | invalidPass | should not be successful |
37 |
--------------------------------------------------------------------------------
/features/registration.feature:
--------------------------------------------------------------------------------
1 | Feature: Booting VM with various registration settings
2 |
3 | Scenario Outline: Boot VirtualBox with and without vbguest additions plugin
4 | Given provider is virtualbox
5 | And a file named "Vagrantfile" with:
6 | """
7 |
8 | Vagrant.configure(2) do |config|
9 | config.vm.box = 'cdk'
10 | config.vm.box_url = 'file://../boxes/cdk-virtualbox.box'
11 | config.registration.username = 'service-manager@mailinator.com'
12 | config.registration.password = 'service-manager'
13 | end
14 | """
15 |
16 | When I successfully run `bundle exec vagrant up --provider virtualbox`
17 | Then vbguest additions be installed
18 |
19 | Examples:
20 | | require | expectation |
21 | | # no require | should not |
22 | | require 'vagrant-vbguest' | should |
23 |
24 |
25 | Scenario Outline: Test invalid registration credentials
26 | Given provider is
27 | And a file named "Vagrantfile" with:
28 | """
29 | begin
30 | require 'vagrant-libvirt'
31 | rescue LoadError
32 | # NOOP
33 | end
34 |
35 | Vagrant.configure(2) do |config|
36 | config.vm.box = 'cdk'
37 | config.vm.box_url = 'file://../boxes/cdk-.box'
38 | config.registration.username = 'foo'
39 | config.registration.password = 'bar'
40 | config.vm.synced_folder '.', '/vagrant', disabled: true
41 | end
42 | """
43 |
44 | When I run `bundle exec vagrant up --provider `
45 | Then startup should fail with invalid credentials error
46 |
47 | Examples:
48 | | provider |
49 | | virtualbox |
50 | | libvirt |
51 |
52 |
53 | Scenario Outline: Test skipping registration
54 | And provider is
55 | And a file named "Vagrantfile" with:
56 | """
57 | begin
58 | require 'vagrant-libvirt'
59 | rescue LoadError
60 | # NOOP
61 | end
62 |
63 | Vagrant.configure(2) do |config|
64 | config.vm.box = 'cdk'
65 | config.vm.box_url = 'file://../boxes/cdk-.box'
66 | config.registration.skip = true
67 | config.vm.synced_folder '.', '/vagrant', disabled: true
68 | end
69 | """
70 |
71 | When I run `bundle exec vagrant up --provider `
72 | Then registration should not be successful
73 |
74 | Examples:
75 | | provider |
76 | | virtualbox |
77 | | libvirt |
78 |
79 | Scenario Outline: Test successful registration
80 | Given provider is
81 | And a file named "Vagrantfile" with:
82 | """
83 | begin
84 | require 'vagrant-libvirt'
85 | rescue LoadError
86 | # NOOP
87 | end
88 |
89 | Vagrant.configure(2) do |config|
90 | config.vm.box = 'cdk'
91 | config.vm.box_url = 'file://../boxes/cdk-.box'
92 | config.registration.username = 'service-manager@mailinator.com'
93 | config.registration.password = 'service-manager'
94 | config.vm.synced_folder '.', '/vagrant', disabled: true
95 | end
96 | """
97 |
98 | When I run `bundle exec vagrant up --provider `
99 | Then registration should be successful
100 |
101 | Examples:
102 | | provider |
103 | | virtualbox |
104 | | libvirt |
105 |
--------------------------------------------------------------------------------
/features/step_definitions/proxy_steps.rb:
--------------------------------------------------------------------------------
1 | require 'webrick'
2 | require 'webrick/httpproxy'
3 | require 'stringio'
4 | require 'logger'
5 |
6 | def match_credentials(req, res)
7 | type, credentials = req.header['proxy-authorization'].first.to_s.split(/\s+/, 2)
8 | received_username, received_password = credentials.to_s.unpack("m*")[0].split(":", 2)
9 | unless received_username == 'validUser' && received_password == 'validPass'
10 | res['proxy-authenticate'] = %{Basic realm="testing"}
11 | raise WEBrick::HTTPStatus::ProxyAuthenticationRequired
12 | end
13 | end
14 |
15 | Before('@needs-proxy') do
16 | @log = StringIO.new
17 | logger = Logger.new(@log)
18 | @proxy = WEBrick::HTTPProxyServer.new(:ServerType => Thread,
19 | :Logger => logger,
20 | :AccessLog => [[@log, "[ %m %U -> %s %b"]],
21 | :Port => 8888,
22 | :ProxyAuthProc => method(:match_credentials)
23 | )
24 | @proxy.start
25 | end
26 |
27 | After('@needs-proxy') do
28 | @proxy.stop
29 | @proxy.shutdown
30 | #puts @log
31 | end
32 |
33 |
--------------------------------------------------------------------------------
/features/step_definitions/registration_steps.rb:
--------------------------------------------------------------------------------
1 | Then(/^vbguest additions should( not)? be installed$/) do |negated|
2 | run("vagrant ssh -c \"lsmod | grep -i vbox\"")
3 |
4 | if negated
5 | expect(last_command_started).to have_exit_status(1)
6 | expect(last_command_started).not_to have_output(/vboxguest/)
7 | else
8 | expect(last_command_started).to have_exit_status(0)
9 | expect(last_command_started).to have_output(/vboxguest/)
10 | end
11 | end
12 |
13 | Then(/^startup should fail with invalid credentials error$/) do
14 | expect(last_command_started).to have_exit_status(1)
15 | expect(last_command_started).to have_output(/Invalid username or password./)
16 | end
17 |
18 |
--------------------------------------------------------------------------------
/features/support/env.rb:
--------------------------------------------------------------------------------
1 | require 'aruba/cucumber'
2 | require 'komenda'
3 |
4 | ###############################################################################
5 | # Aruba config and Cucumber hooks
6 | ###############################################################################
7 |
8 | Aruba.configure do |config|
9 | config.exit_timeout = 300
10 | config.activate_announcer_on_command_failure = [:stdout, :stderr]
11 | config.working_directory = 'build/aruba'
12 | end
13 |
14 | Before do |scenario|
15 | @scenario_name = scenario.name
16 | ENV['VAGRANT_HOME'] = File.join(File.dirname(__FILE__), '..', '..', 'build', 'vagrant.d')
17 | end
18 |
19 | After do |_scenario|
20 | if File.exist?(File.join(aruba.config.working_directory, 'Vagrantfile'))
21 | Komenda.run('bundle exec vagrant destroy -f', cwd: aruba.config.working_directory, fail_on_fail: true)
22 | if ENV.has_key?('CUCUMBER_RUN_PROVIDER')
23 | # if we have more than one provider we need to wait between scenarios in order to allow for proper cleanup/shutdown
24 | # of virtualization framework
25 | sleep 10
26 | end
27 | end
28 | end
29 |
30 | ###############################################################################
31 | # Some shared step definitions
32 | ##############################################################################
33 | Given /provider is (.*)/ do |current_provider|
34 | requested_provider = ENV.has_key?('PROVIDER') ? ENV['PROVIDER'] : 'virtualbox'
35 |
36 | unless requested_provider.include?(current_provider)
37 | #puts "Skipping scenario '#{@scenario_name}' for provider '#{current_provider}', since this provider is not explicitly enabled via environment variable 'PROVIDER'"
38 | skip_this_scenario
39 | end
40 | end
41 |
42 | Given /box is (.*)/ do |current_box|
43 | requested_box = ENV.has_key?('BOX') ? ENV['BOX'] : 'cdk'
44 |
45 | unless requested_box.include?(current_box)
46 | #puts "Skipping scenario '#{@scenario_name}' for box '#{current_box}', since this box is not explicitly enabled via environment variable 'BOX'"
47 | skip_this_scenario
48 | end
49 | end
50 |
51 | Then(/^stdout from "([^"]*)" should match \/(.*)\/$/) do |cmd, regexp|
52 | aruba.command_monitor.find(Aruba.platform.detect_ruby(cmd)).send(:stdout) =~ /#{regexp}/
53 | end
54 |
55 | Then(/^registration should( not)? be successful$/) do |negated|
56 | run("vagrant ssh -c \"sudo subscription-manager version\"")
57 |
58 | expect(last_command_started).to have_exit_status(0)
59 | if negated
60 | expect(last_command_started).to have_output(/This system is currently not registered/)
61 | else
62 | expect(last_command_started).to have_output(/Red Hat Subscription Management/)
63 | end
64 | end
--------------------------------------------------------------------------------
/lib/vagrant-registration.rb:
--------------------------------------------------------------------------------
1 | require 'pathname'
2 | require 'vagrant-registration/plugin'
3 |
4 | module VagrantPlugins
5 | module Registration
6 | lib_path = Pathname.new(File.expand_path('../vagrant-registration', __FILE__))
7 | autoload :Action, lib_path.join('action')
8 |
9 | # This returns the path to the source of this plugin.
10 | def self.source_root
11 | @source_root ||= Pathname.new(File.expand_path('../../', __FILE__))
12 | end
13 |
14 | # Temporally load the extra capability files for Red Hat
15 | load(File.join(source_root, 'plugins/guests/redhat/plugin.rb'))
16 | # Default I18n to load the en locale
17 | I18n.load_path << File.expand_path('locales/en.yml', source_root)
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/lib/vagrant-registration/action.rb:
--------------------------------------------------------------------------------
1 | module VagrantPlugins
2 | module Registration
3 | module Action
4 |
5 | def self.action_register
6 | Vagrant::Action::Builder.new.tap do |b|
7 | b.use Register
8 | end
9 | end
10 |
11 | def self.action_unregister_on_halt
12 | Vagrant::Action::Builder.new.tap do |b|
13 | b.use UnregisterOnHalt
14 | end
15 | end
16 |
17 | def self.action_unregister_on_destroy
18 | Vagrant::Action::Builder.new.tap do |b|
19 | b.use UnregisterOnDestroy
20 | end
21 | end
22 |
23 | action_root = Pathname.new(File.expand_path('../action', __FILE__))
24 | autoload :Register, action_root.join('register')
25 | autoload :UnregisterOnHalt, action_root.join('unregister_on_halt')
26 | autoload :UnregisterOnDestroy, action_root.join('unregister_on_destroy')
27 | end
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/lib/vagrant-registration/action/register.rb:
--------------------------------------------------------------------------------
1 | require 'log4r'
2 |
3 | module VagrantPlugins
4 | module Registration
5 | module Action
6 | # This registers the guest if the guest plugin supports it
7 | class Register
8 | MAX_REGISTRATION_ATTEMPTS = 3
9 |
10 | def initialize(app, _)
11 | @app = app
12 | @logger = Log4r::Logger.new('vagrant_registration::action::register')
13 | end
14 |
15 | def call(env)
16 | ui = env[:ui]
17 | # Configuration from Vagrantfile
18 | config = env[:machine].config.registration
19 | machine = env[:machine]
20 | guest = env[:machine].guest
21 |
22 | if should_register?(machine, ui)
23 | ui.info I18n.t('registration.action.register.registration_info')
24 | check_configuration_options(machine, ui)
25 |
26 | if credentials_provided? machine
27 | guest.capability(:registration_register, ui)
28 | else
29 | @logger.debug I18n.t('registration.action.register.no_credentials')
30 |
31 | # Offer to register ATM or skip
32 | register_now = ui.ask I18n.t('registration.action.register.prompt')
33 | process_registration(guest, machine, ui, config) if register_now == 'y' || register_now.empty?
34 | end
35 | end
36 |
37 | @logger.debug(I18n.t('registration.action.register.skip_due_config')) if config.skip
38 |
39 | # Call next middleware in chain
40 | @app.call(env)
41 | end
42 |
43 | private
44 |
45 | # Shall we register the box?
46 | def should_register?(machine, ui)
47 | !machine.config.registration.skip &&
48 | capabilities_provided?(machine.guest) &&
49 | manager_installed?(machine.guest, ui) &&
50 | !machine.guest.capability(:registration_registered?)
51 | end
52 |
53 | # Issues warning if an unsupported option is used and displays
54 | # a list of supported options
55 | def check_configuration_options(machine, ui)
56 | manager = machine.guest.capability(:registration_manager).to_s
57 | available_options = machine.guest.capability(:registration_options)
58 | options = machine.config.registration.conf.each_pair.map { |pair| pair[0] }
59 |
60 | if unsupported_options_provided?(manager, available_options, options, ui)
61 | ui.warn(I18n.t('registration.action.register.options_support_warning',
62 | manager: manager, options: available_options.join(', ')))
63 | end
64 | end
65 |
66 | # Return true if there are any unsupported options
67 | def unsupported_options_provided?(manager, available_options, options, ui)
68 | warned = false
69 | options.each do |option|
70 | unless available_options.include? option
71 | ui.warn(I18n.t('registration.action.register.unsupported_option',
72 | manager: manager, option: option))
73 | warned = true
74 | end
75 | end
76 | warned
77 | end
78 |
79 | # Check if registration capabilities are available
80 | def capabilities_provided?(guest)
81 | if guest.capability?(:registration_register) &&
82 | guest.capability?(:registration_manager_installed) &&
83 | guest.capability?(:registration_registered?)
84 | true
85 | else
86 | @logger.debug I18n.t('registration.action.register.skip_missing_guest_capability')
87 | false
88 | end
89 | end
90 |
91 | # Check if selected registration manager is installed
92 | def manager_installed?(guest, ui)
93 | if guest.capability(:registration_manager_installed, ui)
94 | true
95 | else
96 | @logger.debug I18n.t('registration.action.manager_not_found')
97 | false
98 | end
99 | end
100 |
101 | # Fetch required credentials for selected manager
102 | def credentials_required(machine)
103 | if machine.guest.capability?(:registration_credentials)
104 | machine.guest.capability(:registration_credentials)
105 | else
106 | []
107 | end
108 | end
109 |
110 | # Secret options for selected manager
111 | def secrets(machine)
112 | if machine.guest.capability?(:registration_secrets)
113 | machine.guest.capability(:registration_secrets)
114 | else
115 | []
116 | end
117 | end
118 |
119 | # Check if required credentials has been provided in Vagrantfile
120 | #
121 | # Checks if at least one of the registration options is able to
122 | # register.
123 | def credentials_provided?(machine)
124 | provided = true
125 | credentials_required(machine).each do |registration_option|
126 | provided = true
127 | registration_option.each do |value|
128 | provided = false unless machine.config.registration.send value
129 | end
130 | break if provided
131 | end
132 | provided ? true : false
133 | end
134 |
135 | # Ask user on required credentials and return them,
136 | # skip options that are provided by Vagrantfile
137 | def register_on_screen(machine, ui)
138 | credentials_required(machine)[0].each do |option|
139 | unless machine.config.registration.send(option)
140 | echo = !(secrets(machine).include? option)
141 | response = ui.ask("#{option}: ", echo: echo)
142 | machine.config.registration.send("#{option}=".to_sym, response)
143 | end
144 | end
145 | machine.config.registration
146 | end
147 |
148 | def process_registration(guest, machine, ui, config)
149 | attempt_count = 1
150 |
151 | MAX_REGISTRATION_ATTEMPTS.times do
152 | config = register_on_screen(machine, ui)
153 |
154 | begin
155 | guest.capability(:registration_register, ui)
156 | ui.info I18n.t('registration.action.register.registration_success')
157 | # break out of loop on successful registration
158 | break
159 | rescue StandardError => e
160 | if attempt_count == MAX_REGISTRATION_ATTEMPTS
161 | ui.error e.message
162 | exit 126
163 | else
164 | # reset registration config
165 | reset_registration_config(machine)
166 | attempt_count += 1
167 | ui.info I18n.t('registration.action.register.registration_retry',
168 | attempt_count: attempt_count, max_attempt: MAX_REGISTRATION_ATTEMPTS)
169 | end
170 | end
171 | end
172 |
173 | config
174 | end
175 |
176 | def reset_registration_config(machine)
177 | credentials_required(machine)[0].each do |option|
178 | machine.config.registration.send("#{option}=".to_sym, nil)
179 | end
180 | end
181 | end
182 | end
183 | end
184 | end
185 |
--------------------------------------------------------------------------------
/lib/vagrant-registration/action/unregister_on_destroy.rb:
--------------------------------------------------------------------------------
1 | require 'log4r'
2 |
3 | module VagrantPlugins
4 | module Registration
5 | module Action
6 | # This unregisters the guest if the guest has registration capability
7 | class UnregisterOnDestroy
8 | def initialize(app, env)
9 | @app = app
10 | @logger = Log4r::Logger.new('vagrant_registration::action::unregister_on_destroy')
11 | end
12 |
13 | def call(env)
14 | config = env[:machine].config.registration
15 | guest = env[:machine].guest
16 |
17 | if capabilities_provided?(guest) && manager_installed?(guest, env[:ui]) && !config.skip
18 | env[:ui].info I18n.t('registration.action.unregister.unregistration_info')
19 | guest.capability(:registration_unregister)
20 | end
21 |
22 | @logger.debug(I18n.t('registration.action.unregister.skip_due_config')) if config.skip
23 | @app.call(env)
24 |
25 | # Guest might not be available after halting, so log the exception and continue
26 | rescue => e
27 | @logger.info(e)
28 | @logger.debug I18n.t('registration.action.unregister.guest_unavailable')
29 | @app.call(env)
30 | end
31 |
32 | private
33 |
34 | # Check if registration capabilities are available
35 | def capabilities_provided?(guest)
36 | if guest.capability?(:registration_unregister) && guest.capability?(:registration_manager_installed)
37 | true
38 | else
39 | @logger.debug I18n.t('registration.action.unregister.skip_missing_guest_capability')
40 | false
41 | end
42 | end
43 |
44 | # Check if selected registration manager is installed
45 | def manager_installed?(guest, ui)
46 | if guest.capability(:registration_manager_installed, ui)
47 | true
48 | else
49 | @logger.debug I18n.t('registration.action.manager_not_found')
50 | false
51 | end
52 | end
53 | end
54 | end
55 | end
56 | end
57 |
--------------------------------------------------------------------------------
/lib/vagrant-registration/action/unregister_on_halt.rb:
--------------------------------------------------------------------------------
1 | require 'log4r'
2 |
3 | module VagrantPlugins
4 | module Registration
5 | module Action
6 | # This unregisters the guest if the guest has registration capability
7 | class UnregisterOnHalt
8 | def initialize(app, env)
9 | @app = app
10 | @logger = Log4r::Logger.new('vagrant_registration::action::unregister_on_halt')
11 | end
12 |
13 | def call(env)
14 | config = env[:machine].config.registration
15 | guest = env[:machine].guest
16 |
17 | if capabilities_provided?(guest) && manager_installed?(guest, env[:ui]) && !config.skip && config.unregister_on_halt
18 | env[:ui].info I18n.t('registration.action.unregister.unregistration_info')
19 | guest.capability(:registration_unregister)
20 | end
21 |
22 | @logger.debug(I18n.t('registration.action.unregister.skip_due_config')) if config.skip
23 | @logger.debug(I18n.t('registration.action.unregister.skip_on_halt_due_config')) unless config.unregister_on_halt
24 | @app.call(env)
25 |
26 | # Guest might not be available after halting, so log the exception and continue
27 | rescue => e
28 | @logger.info(e)
29 | @logger.debug I18n.t('registration.action.unregister.guest_unavailable')
30 | @app.call(env)
31 | end
32 |
33 | private
34 |
35 | # Check if registration capabilities are available
36 | def capabilities_provided?(guest)
37 | if guest.capability?(:registration_unregister) && guest.capability?(:registration_manager_installed)
38 | true
39 | else
40 | @logger.debug I18n.t('registration.action.unregister.skip_missing_guest_capability')
41 | false
42 | end
43 | end
44 |
45 | # Check if selected registration manager is installed
46 | def manager_installed?(guest, ui)
47 | if guest.capability(:registration_manager_installed, ui)
48 | true
49 | else
50 | @logger.debug I18n.t('registration.action.manager_not_found')
51 | false
52 | end
53 | end
54 | end
55 | end
56 | end
57 | end
58 |
--------------------------------------------------------------------------------
/lib/vagrant-registration/config.rb:
--------------------------------------------------------------------------------
1 | require 'vagrant'
2 | require 'ostruct'
3 |
4 | module VagrantPlugins
5 | module Registration
6 | class Config < Vagrant.plugin('2', :config)
7 | attr_reader :conf
8 |
9 | def initialize(region_specific=false)
10 | @conf = UNSET_VALUE
11 | @logger = Log4r::Logger.new('vagrant_registration::config')
12 | end
13 |
14 | def finalize!
15 | get_config
16 | @conf.skip = false unless @conf.skip
17 | # Unregister on halt by default
18 | @conf.unregister_on_halt = true if @conf.unregister_on_halt.nil?
19 | @logger.info I18n.t('registration.config.final_message', conf: @conf.inspect)
20 | end
21 |
22 | def method_missing(method_sym, *arguments, &block)
23 | get_config
24 | command = "@conf.#{method_sym} #{adjust_arguments(arguments)}"
25 | @logger.info I18n.t('registration.config.method_missing_command', command: command)
26 | eval command
27 | end
28 |
29 | private
30 |
31 | # Don't set @conf to OpenStruct in initialize
32 | # to preserve config hierarchy
33 | def get_config
34 | @conf = OpenStruct.new if @conf == UNSET_VALUE
35 | end
36 |
37 | # Serialize strings, nil and boolean values, symbols, arrays and hashes
38 | # to be used within eval()
39 | def adjust_arguments(args)
40 | return '' if args.size < 1
41 | args.inspect[1..-2]
42 | end
43 | end
44 | end
45 | end
46 |
--------------------------------------------------------------------------------
/lib/vagrant-registration/plugin.rb:
--------------------------------------------------------------------------------
1 | begin
2 | require 'vagrant'
3 | rescue LoadError
4 | raise 'The vagrant-registration plugin must be run within Vagrant.'
5 | end
6 |
7 | # This is a sanity check to make sure no one is attempting to install
8 | # this into an early Vagrant version.
9 | if Vagrant::VERSION < '1.2.0'
10 | fail I18n.t('registration.plugin.compatible_message')
11 | end
12 |
13 | module VagrantPlugins
14 | module Registration
15 | class Plugin < Vagrant.plugin('2')
16 | class << self
17 | # vagrant-vbguest plugin updates GuestAdditions for VirtualBox
18 | # and therefore needs to be run after the box got registered.
19 | # See https://github.com/projectatomic/adb-vagrant-registration/issues/69
20 | #
21 | # vagrant-vbguest hooks before VagrantPlugins::ProviderVirtualBox::Action::CheckGuestAdditions
22 | # (see https://github.com/mitchellh/vagrant/blob/master/plugins/providers/virtualbox/action.rb#L81)
23 | # For registration to occur in time, it has to happen before that. Using WaitForCommunicator
24 | # to be sure - https://github.com/dotless-de/vagrant-vbguest/blob/master/lib/vagrant-vbguest.rb#L53
25 | #
26 | # For vagrant-libvirt WaitTillUp is used
27 | def register(hook)
28 | setup_logging
29 |
30 | registered = false
31 | if virtual_box?
32 | hook.after(VagrantPlugins::ProviderVirtualBox::Action::WaitForCommunicator,
33 | VagrantPlugins::Registration::Action.action_register)
34 | registered = true
35 | end
36 | if libvirt?
37 | hook.after(VagrantPlugins::ProviderLibvirt::Action::WaitTillUp,
38 | VagrantPlugins::Registration::Action.action_register)
39 | registered = true
40 | end
41 | # Best guess for the other providers
42 | unless registered
43 | hook.after(Vagrant::Action::Builtin::WaitForCommunicator,
44 | VagrantPlugins::Registration::Action.action_register)
45 | end
46 | end
47 |
48 | def unregister_on_halt(hook)
49 | setup_logging
50 | hook.prepend(VagrantPlugins::Registration::Action.action_unregister_on_halt)
51 | end
52 |
53 | def unregister_on_destroy(hook)
54 | setup_logging
55 | hook.prepend(VagrantPlugins::Registration::Action.action_unregister_on_destroy)
56 | end
57 | end
58 |
59 | name I18n.t('registration.plugin.name')
60 | description I18n.t('registration.plugin.description')
61 |
62 | action_hook(:registration_register, :machine_action_up, &method(:register))
63 | action_hook(:registration_register, :machine_action_provision, &method(:register))
64 | action_hook(:registration_unregister_on_halt, :machine_action_halt, &method(:unregister_on_halt))
65 | action_hook(:registration_unregister_on_destroy, :machine_action_destroy, &method(:unregister_on_destroy))
66 |
67 | config(:registration) do
68 | setup_logging
69 | require_relative 'config'
70 | Config
71 | end
72 |
73 | # This sets up our log level to be whatever VAGRANT_LOG is
74 | # for loggers prepended with 'vagrant_registration'
75 | def self.setup_logging
76 | require 'log4r'
77 | level = nil
78 | begin
79 | level = Log4r.const_get(ENV['VAGRANT_LOG'].upcase)
80 | rescue NameError
81 | # This means that the logging constant wasn't found,
82 | # which is fine. We just keep `level` as `nil`. But
83 | # we tell the user.
84 | level = nil
85 | end
86 | # Some constants, such as "true" resolve to booleans, so the
87 | # above error checking doesn't catch it. This will check to make
88 | # sure that the log level is an integer, as Log4r requires.
89 | level = nil unless level.is_a?(Integer)
90 | # Set the logging level on all "vagrant" namespaced
91 | # logs as long as we have a valid level.
92 | if level
93 | logger = Log4r::Logger.new('vagrant_registration')
94 | logger.outputters = Log4r::Outputter.stderr
95 | logger.level = level
96 | logger = nil
97 | end
98 | end
99 |
100 | # Determines if VirtualBox is provider
101 | def self.virtual_box?
102 | defined?(VagrantPlugins::ProviderVirtualBox::Provider)
103 | end
104 |
105 | # Determines if LibVirt is provider
106 | def self.libvirt?
107 | defined?(VagrantPlugins::ProviderLibvirt::Provider)
108 | end
109 | end
110 | end
111 | end
112 |
--------------------------------------------------------------------------------
/lib/vagrant-registration/version.rb:
--------------------------------------------------------------------------------
1 | module VagrantPlugins
2 | # Registration plugin to auto-register guests on `vagrant up`
3 | module Registration
4 | VERSION = '1.3.4'
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/locales/en.yml:
--------------------------------------------------------------------------------
1 | en:
2 | registration:
3 | config:
4 | final_message: 'Final registration configuration: %{conf}'
5 | method_missing_command: 'Evaluating registration configuration: %{command}'
6 | plugin:
7 | compatible_message: 'The Vagrant RHEL plugin is only compatible with Vagrant 1.2+.'
8 | name: 'Registration'
9 | description: |-
10 | This plugin adds register and unregister functionality to Vagrant Guests that
11 | support the capability
12 | action:
13 | manager_not_found: 'Registration manager not found on guest'
14 | register:
15 | registration_info: 'Registering box with vagrant-registration...'
16 | no_credentials: 'Credentials for registration not provided'
17 | prompt: 'Would you like to register the system now (default: yes)? [y|n]'
18 | skip_due_config: 'Registration is skipped due to the configuration'
19 | options_support_warning: |-
20 | WARNING: %{manager} supports only the following options:
21 | WARNING: %{options}"
22 | unsupported_option: "WARNING: %{option} option is not supported for %{manager}"
23 | skip_missing_guest_capability: 'Registration is skipped due to the missing guest capability'
24 | registration_retry: |-
25 | Invalid username/password. Try again (%{attempt_count}/%{max_attempt})
26 | registration_success: 'Registration successful.'
27 | unregister:
28 | unregistration_info: 'Unregistering box with vagrant-registration...'
29 | skip_due_config: 'Unregistration is skipped due to the configuration'
30 | skip_on_halt_due_config: 'Unregistration is skipped on halt due to the configuration'
31 | guest_unavailable: 'Guest is not available, ignore unregistration'
32 | skip_missing_guest_capability: 'Unregistration is skipped due to the missing guest capability'
33 |
--------------------------------------------------------------------------------
/plugins/guests/redhat/cap/registration.rb:
--------------------------------------------------------------------------------
1 | module VagrantPlugins
2 | module GuestRedHat
3 | module Cap
4 | # Common configuration options for all managers
5 | DEFAULT_CONFIGURATION_OPTIONS = [:manager, :skip, :unregister_on_halt]
6 |
7 | # This provides registration capabilities for vagrant-registration
8 | #
9 | # As we might support more registration options (managers), this
10 | # just calls the capabilities of the selected registration manager
11 | # (from config.registration.manager).
12 | class Registration
13 | # Is the machine already registered?
14 | def self.registration_registered?(machine)
15 | cap = "#{registration_manager(machine)}_registered?".to_sym
16 | if machine.guest.capability?(cap)
17 | machine.guest.capability(cap)
18 | else
19 | false
20 | end
21 | end
22 |
23 | # Register the given machine
24 | def self.registration_register(machine, ui)
25 | cap = "#{registration_manager(machine)}_register".to_sym
26 | if machine.guest.capability?(cap)
27 | machine.guest.capability(cap, ui)
28 | else
29 | false
30 | end
31 | end
32 |
33 | # Unregister the given machine
34 | def self.registration_unregister(machine)
35 | cap = "#{registration_manager(machine)}_unregister".to_sym
36 | if machine.guest.capability?(cap)
37 | machine.guest.capability(cap)
38 | else
39 | false
40 | end
41 | end
42 |
43 | # Check that the machine has the selected registration manager installed
44 | # and warn if the user specifically selected a manager that is not available
45 | def self.registration_manager_installed(machine, ui)
46 | cap = "#{registration_manager(machine)}".to_sym
47 | return machine.guest.capability(cap) if machine.guest.capability?(cap)
48 | if machine.config.registration.manager != ''
49 | ui.error("WARNING: Selected registration manager #{machine.config.registration.manager} is not available, skipping.")
50 | end
51 | false
52 | end
53 |
54 | # Required configuration options of the registration manager
55 | #
56 | # This is array of arrays of all possible registration combinations.
57 | # First one is the default used in interactive mode.
58 | #
59 | # e.g. [[:username, :password]]
60 | def self.registration_credentials(machine)
61 | cap = "#{registration_manager(machine)}_credentials".to_sym
62 | if machine.guest.capability?(cap)
63 | machine.guest.capability(cap)
64 | else
65 | []
66 | end
67 | end
68 |
69 | # Return all available options for a given registration manager together
70 | # with general options available to any.
71 | def self.registration_options(machine)
72 | cap = "#{registration_manager(machine)}_options".to_sym
73 | if machine.guest.capability?(cap)
74 | DEFAULT_CONFIGURATION_OPTIONS + machine.guest.capability(cap)
75 | else
76 | DEFAULT_CONFIGURATION_OPTIONS
77 | end
78 | end
79 |
80 | # Return secret options for the registration manager
81 | def self.registration_secrets(machine)
82 | cap = "#{registration_manager(machine)}_secrets".to_sym
83 | if machine.guest.capability?(cap)
84 | machine.guest.capability(cap)
85 | else
86 | []
87 | end
88 | end
89 |
90 | # Return selected registration manager or default
91 | def self.registration_manager(machine)
92 | (machine.config.registration.manager || 'subscription_manager').to_sym
93 | end
94 | end
95 | end
96 | end
97 | end
98 |
--------------------------------------------------------------------------------
/plugins/guests/redhat/cap/rhn_register.rb:
--------------------------------------------------------------------------------
1 | module VagrantPlugins
2 | module GuestRedHat
3 | module Cap
4 | class RhnRegister
5 | # Test that the machine is already registered
6 | def self.rhn_register_registered?(machine)
7 | true if machine.communicate.sudo('/usr/sbin/rhn_check')
8 | rescue
9 | false
10 | end
11 |
12 | # Test that we have rhn installed
13 | def self.rhn_register(machine)
14 | machine.communicate.test('/usr/sbin/rhn_check --version', sudo: true) &&
15 | machine.communicate.test('/usr/sbin/rhnreg_ks --version', sudo: true)
16 | end
17 |
18 | # Register the machine using 'rhnreg_ks' command, config is (Open)Struct
19 | def self.rhn_register_register(machine, ui)
20 | rhn_register_upload_certificate(machine, ui)
21 | rhn_register_server_url(machine, ui) if machine.config.registration.serverurl
22 | command = "rhnreg_ks #{configuration_to_options(machine.config.registration)}"
23 |
24 | # Handle exception to avoid displaying password
25 | begin
26 | error = String.new
27 | machine.communicate.sudo(registration_command(command)) do |type, data|
28 | error += "#{data}" if type == :stderr
29 | end
30 | rescue Vagrant::Errors::VagrantError
31 | raise Vagrant::Errors::VagrantError.new, error.strip
32 | end
33 | end
34 |
35 | # Unregister the machine using 'rhn_unregister.py' resource script
36 | def self.rhn_register_unregister(machine)
37 | machine.communicate.tap do |comm|
38 | tmp = '/tmp/rhn_unregister'
39 | system_id = '/etc/sysconfig/rhn/systemid'
40 | server_url = machine.config.registration.serverurl
41 | # Generate the API URL
42 | server_url = server_url.sub(/XMLRPC$/, 'rpc/api')
43 | comm.sudo("rm -f #{tmp}", error_check: false)
44 | comm.upload(resource('rhn_unregister.py'), tmp)
45 | comm.sudo("python #{tmp} -s #{server_url} -f #{system_id}")
46 | comm.sudo("rm -f #{tmp}")
47 | # Guest still thinks it is a part of RHN network until systemdid file is removed
48 | comm.sudo("rm -f #{system_id}")
49 | end
50 | end
51 |
52 | # Return required configuration options for rhn register
53 | #
54 | # For rhn_register the Server URL is mandatory and must be always
55 | # provided together with the credentials
56 | def self.rhn_register_credentials(machine)
57 | [[:username, :password, :serverurl], [:org, :activationkey, :serverurl]]
58 | end
59 |
60 | # Return all available options for rhn register
61 | def self.rhn_register_options(machine)
62 | [:name, :username, :password, :org, :serverurl, :ca_cert,
63 | :activationkey, :use_eus_channel, :nohardware, :nopackages,
64 | :novirtinfo, :norhnsd, :force, :proxy, :proxyUser, :proxyPassword]
65 | end
66 |
67 | # Return secret options for rhreg_ks
68 | def self.rhn_register_secrets(manager)
69 | [:password]
70 | end
71 |
72 | private
73 |
74 | # Upload provided SSL CA cert to the standard /usr/share/rhn/ path on the guest
75 | # and configure the correct path in `up2date` system configuration
76 | def self.rhn_register_upload_certificate(machine, ui)
77 | # Set as the default CA certificate file that is present on Fedora, CentOS and RHEL
78 | cert_file_name = 'RHNS-CA-CERT'
79 | if machine.config.registration.ca_cert
80 | ui.info("Uploading CA certificate from #{machine.config.registration.ca_cert}...")
81 | if File.exist?(machine.config.registration.ca_cert)
82 | # Make sure the provided CA certificate file will be configured
83 | cert_file_name = File.basename(machine.config.registration.ca_cert)
84 | cert_file_content = File.read(machine.config.registration.ca_cert)
85 | machine.communicate.sudo("echo '#{cert_file_content}' > /usr/share/rhn/#{cert_file_name}")
86 | else
87 | ui.warn("WARNING: Provided CA certificate file #{machine.config.registration.ca_cert} does not exist, skipping")
88 | end
89 | end
90 | # Make sure the correct CA certificate file is always configured
91 | ui.info("Updating CA certificate to /usr/share/rhn/#{cert_file_name}`...")
92 | machine.communicate.sudo("sed -i 's|^sslCACert\s*=.*$|sslCACert=/usr/share/rhn/#{cert_file_name}|g' /etc/sysconfig/rhn/up2date")
93 | end
94 |
95 | # Build registration command that skips registration if the system is registered
96 | def self.registration_command(command)
97 | "cmd=$(#{command}); if [ \"$?\" != \"0\" ]; then echo $cmd | grep 'This system is already registered' || (echo $cmd 1>&2 && exit 1) ; fi"
98 | end
99 |
100 | # Update configuration file '/etc/sysconfig/rhn/up2date' with
101 | # provided server URL
102 | def self.rhn_register_server_url(machine, ui)
103 | ui.info("Update server URL to #{machine.config.registration.serverurl}...")
104 | machine.communicate.sudo("sed -i 's|^serverURL=.*$|serverURL=/usr/share/rhn/#{machine.config.registration.serverurl}|' /etc/sysconfig/rhn/up2date")
105 | end
106 |
107 | # The absolute path to the resource file
108 | def self.resource(name)
109 | File.join(resource_root, name)
110 | end
111 |
112 | # The absolute path to the resource directory
113 | def self.resource_root
114 | File.expand_path('../../../../../resources', __FILE__)
115 | end
116 |
117 | # Build additional rhreg_ks options based on the plugin configuration
118 | def self.configuration_to_options(config)
119 | config.force = true if config.force.nil?
120 |
121 | options = []
122 | options << "--profilename='#{config.name}'" if config.name
123 | options << "--username='#{config.username}'" if config.username
124 | options << "--password='#{config.password}'" if config.password
125 | options << "--systemorgid='#{config.org}'" if config.org
126 | options << "--serverUrl='#{config.serverurl}'" if config.serverurl
127 | options << "--activationkey='#{config.activationkey}'" if config.activationkey
128 | options << '--use-eus-channel' if config.use_eus_channel
129 | options << '--nohardware' if config.nohardware
130 | options << '--nopackages' if config.nopackages
131 | options << '--novirtinfo' if config.novirtinfo
132 | options << '--norhnsd' if config.norhnsd
133 | options << '--force' if config.force
134 | options << "--proxy='#{config.proxy}'" if config.proxy
135 | options << "--proxyUser='#{config.proxyUser}'" if config.proxyUser
136 | options << "--proxyPassword='#{config.proxyPassword}'" if config.proxyPassword
137 | options.join(' ')
138 | end
139 | end
140 | end
141 | end
142 | end
143 |
--------------------------------------------------------------------------------
/plugins/guests/redhat/cap/subscription_manager.rb:
--------------------------------------------------------------------------------
1 | module VagrantPlugins
2 | module GuestRedHat
3 | module Cap
4 | class SubscriptionManager
5 | # Test that the machine is already registered
6 | def self.subscription_manager_registered?(machine)
7 | true if machine.communicate.sudo("/usr/sbin/subscription-manager list --consumed --pool-only | grep -E '^[a-f0-9]{32}$'")
8 | rescue
9 | false
10 | end
11 |
12 | # Test that we have subscription-manager installed
13 | def self.subscription_manager(machine)
14 | machine.communicate.test('/usr/sbin/subscription-manager', sudo: true)
15 | end
16 |
17 | # Register the machine using 'register' option, config is (Open)Struct
18 | def self.subscription_manager_register(machine, ui)
19 | subscription_manager_upload_certificate(machine, ui) if machine.config.registration.ca_cert
20 | command = "subscription-manager register #{configuration_to_options(machine.config.registration)}"
21 |
22 | # Handle exception to avoid displaying password
23 | begin
24 | error = String.new
25 | machine.communicate.sudo(registration_command(command)) do |type, data|
26 | error += "#{data}" if type == :stderr
27 | end
28 | rescue Vagrant::Errors::VagrantError
29 | raise Vagrant::Errors::VagrantError.new, error.strip
30 | end
31 |
32 | attach_pools(machine, machine.config.registration.pools)
33 | end
34 |
35 | # Unregister the machine using 'unregister' option
36 | def self.subscription_manager_unregister(machine)
37 | machine.communicate.sudo("subscription-manager unregister #{configuration_to_options_unregister(machine.config.registration)}")
38 | end
39 |
40 | # Return required configuration options for subscription-manager
41 | def self.subscription_manager_credentials(machine)
42 | [[:username, :password], [:org, :activationkey]]
43 | end
44 |
45 | # Return all available options for subscription-manager
46 | #
47 | # ca_cert is not part of 'register' command API, but it's needed
48 | # in conjuntion with serverurl option.
49 | def self.subscription_manager_options(machine)
50 | [:username, :password, :serverurl, :baseurl, :org, :environment,
51 | :name, :auto_attach, :activationkey, :servicelevel, :release,
52 | :force, :type, :ca_cert, :pools, :proxy, :proxyUser, :proxyPassword]
53 | end
54 |
55 | # Return secret options for subscription-manager
56 | def self.subscription_manager_secrets(machine)
57 | [:password]
58 | end
59 |
60 | private
61 |
62 | # Upload provided CA cert to the standard /etc/rhsm/ca path on the guest
63 | #
64 | # Since subscription-manager recognizes only .pem files, we rename those
65 | # files not ending with '.pem' extension.
66 | def self.subscription_manager_upload_certificate(machine, ui)
67 | ui.info("Uploading CA certificate from #{machine.config.registration.ca_cert}...")
68 | if File.exist?(machine.config.registration.ca_cert)
69 | cert_file_content = File.read(machine.config.registration.ca_cert)
70 | cert_file_name = File.basename(machine.config.registration.ca_cert)
71 | cert_file_name = "#{cert_file_name}.pem" unless cert_file_name.end_with? '.pem'
72 | machine.communicate.sudo("echo '#{cert_file_content}' > /etc/rhsm/ca/#{cert_file_name}")
73 | ui.info('Setting repo_ca_cert option in /etc/rhsm/rhsm.conf...')
74 | machine.communicate.sudo("sed -i 's|^repo_ca_cert\s*=.*|repo_ca_cert = /etc/rhsm/ca/#{cert_file_name}|g' /etc/rhsm/rhsm.conf")
75 | else
76 | ui.warn("WARNING: Provided CA certificate file #{machine.config.registration.ca_cert} does not exist, skipping")
77 | end
78 | end
79 |
80 | # Build registration command that skips registration if the system is registered
81 | def self.registration_command(command)
82 | "cmd=$(#{command}); if [ \"$?\" != \"0\" ]; then echo $cmd | grep 'This system is already registered' || (echo $cmd 1>&2 && exit 1) ; fi"
83 | end
84 |
85 | # Build additional subscription-manager options based on plugin configuration
86 | def self.configuration_to_options(config)
87 | config.force = true if config.force.nil?
88 |
89 | # --auto-attach cannot be used in case of org/activationkey registration
90 | # or if pools are specified
91 | if (config.org && config.activationkey) || config.pools
92 | config.auto_attach = false
93 | else
94 | config.auto_attach = true if config.auto_attach.nil?
95 | end
96 |
97 | options = []
98 | options << "--username='#{config.username}'" if config.username
99 | options << "--password='#{config.password}'" if config.password
100 | options << "--serverurl='#{config.serverurl}'" if config.serverurl
101 | options << "--baseurl='#{config.baseurl}'" if config.baseurl
102 | options << "--org='#{config.org}'" if config.org
103 | options << "--environment='#{config.environment}'" if config.environment
104 | options << "--name='#{config.name}'" if config.name
105 | options << '--auto-attach' if config.auto_attach
106 | options << "--activationkey='#{config.activationkey}'" if config.activationkey
107 | options << "--servicelevel='#{config.servicelevel}'" if config.servicelevel
108 | options << "--release='#{config.release}'" if config.release
109 | options << '--force' if config.force
110 | options << "--type='#{config.type}'" if config.type
111 | options << "--proxy='#{config.proxy}'" if config.proxy
112 | options << "--proxyuser='#{config.proxyUser}'" if config.proxyUser
113 | options << "--proxypassword='#{config.proxyPassword}'" if config.proxyPassword
114 | options.join(' ')
115 | end
116 |
117 | # Build subscription manager options for unregistering the Vagrant guest
118 | def self.configuration_to_options_unregister(config)
119 | options = []
120 | options << "--proxy='#{config.proxy}'" if config.proxy
121 | options << "--proxyuser='#{config.proxyUser}'" if config.proxyUser
122 | options << "--proxypassword='#{config.proxyPassword}'" if config.proxyPassword
123 | options.join(' ')
124 | end
125 |
126 | # Attach subscription pools
127 | def self.attach_pools(machine, pools)
128 | if pools
129 | command = "subscription-manager attach #{pools_to_options(pools)}"
130 | machine.communicate.sudo(command)
131 | end
132 | end
133 |
134 | # Return pools options for subscription-manager
135 | def self.pools_to_options(pools)
136 | pools = [pools] if pools.kind_of?(String)
137 | pools.map do |pool|
138 | "--pool=#{pool}"
139 | end.join(' ')
140 | end
141 | end
142 | end
143 | end
144 | end
145 |
--------------------------------------------------------------------------------
/plugins/guests/redhat/plugin.rb:
--------------------------------------------------------------------------------
1 | require 'vagrant'
2 |
3 | module VagrantPlugins
4 | module GuestRedHat
5 | class Plugin < Vagrant.plugin('2')
6 | guest_capability('redhat', 'registration_registered?') do
7 | require_relative 'cap/registration'
8 | Cap::Registration
9 | end
10 |
11 | guest_capability('redhat', 'registration_register') do
12 | require_relative 'cap/registration'
13 | Cap::Registration
14 | end
15 |
16 | guest_capability('redhat', 'registration_unregister') do
17 | require_relative 'cap/registration'
18 | Cap::Registration
19 | end
20 |
21 | guest_capability('redhat', 'registration_manager_installed') do
22 | require_relative 'cap/registration'
23 | Cap::Registration
24 | end
25 |
26 | guest_capability('redhat', 'registration_credentials') do
27 | require_relative 'cap/registration'
28 | Cap::Registration
29 | end
30 |
31 | guest_capability('redhat', 'registration_options') do
32 | require_relative 'cap/registration'
33 | Cap::Registration
34 | end
35 |
36 | guest_capability('redhat', 'registration_secrets') do
37 | require_relative 'cap/registration'
38 | Cap::Registration
39 | end
40 |
41 | guest_capability('redhat', 'registration_manager') do
42 | require_relative 'cap/registration'
43 | Cap::Registration
44 | end
45 |
46 | guest_capability('redhat', 'subscription_manager') do
47 | require_relative 'cap/subscription_manager'
48 | Cap::SubscriptionManager
49 | end
50 |
51 | guest_capability('redhat', 'subscription_manager_registered?') do
52 | require_relative 'cap/subscription_manager'
53 | Cap::SubscriptionManager
54 | end
55 |
56 | guest_capability('redhat', 'subscription_manager_register') do
57 | require_relative 'cap/subscription_manager'
58 | Cap::SubscriptionManager
59 | end
60 |
61 | guest_capability('redhat', 'subscription_manager_unregister') do
62 | require_relative 'cap/subscription_manager'
63 | Cap::SubscriptionManager
64 | end
65 |
66 | guest_capability('redhat', 'subscription_manager_credentials') do
67 | require_relative 'cap/subscription_manager'
68 | Cap::SubscriptionManager
69 | end
70 |
71 | guest_capability('redhat', 'subscription_manager_options') do
72 | require_relative 'cap/subscription_manager'
73 | Cap::SubscriptionManager
74 | end
75 |
76 | guest_capability('redhat', 'subscription_manager_secrets') do
77 | require_relative 'cap/subscription_manager'
78 | Cap::SubscriptionManager
79 | end
80 |
81 | guest_capability('redhat', 'rhn_register') do
82 | require_relative 'cap/rhn_register'
83 | Cap::RhnRegister
84 | end
85 |
86 | guest_capability('redhat', 'rhn_register_registered?') do
87 | require_relative 'cap/rhn_register'
88 | Cap::RhnRegister
89 | end
90 |
91 | guest_capability('redhat', 'rhn_register_register') do
92 | require_relative 'cap/rhn_register'
93 | Cap::RhnRegister
94 | end
95 |
96 | guest_capability('redhat', 'rhn_register_unregister') do
97 | require_relative 'cap/rhn_register'
98 | Cap::RhnRegister
99 | end
100 |
101 | guest_capability('redhat', 'rhn_register_credentials') do
102 | require_relative 'cap/rhn_register'
103 | Cap::RhnRegister
104 | end
105 |
106 | guest_capability('redhat', 'rhn_register_options') do
107 | require_relative 'cap/rhn_register'
108 | Cap::RhnRegister
109 | end
110 |
111 | guest_capability('redhat', 'rhn_register_secrets') do
112 | require_relative 'cap/rhn_register'
113 | Cap::RhnRegister
114 | end
115 | end
116 | end
117 | end
118 |
--------------------------------------------------------------------------------
/resources/rhn_unregister.py:
--------------------------------------------------------------------------------
1 | import argparse
2 | import xmlrpclib
3 | import os.path
4 | import sys
5 |
6 | def main():
7 | parser = argparse.ArgumentParser(description="Unregister the system from Spacewalk Server, Red Hat Satellite or Red Hat Network Classic.")
8 | parser.add_argument("-s", "--serverurl", dest="server_url", type=str, required=True,
9 | help="Specify a URL to as the server.")
10 | parser.add_argument("-f", "--file", dest="system_id", type=str, default='/etc/sysconfig/rhn/systemid',
11 | help="Specify a path to the RHN systemid file.")
12 |
13 | args = parser.parse_args()
14 |
15 | try:
16 | if not os.path.exists(args.system_id):
17 | print "System is not registered to RHN"
18 | return 1
19 | client = xmlrpclib.Server(args.server_url)
20 | client.system.delete_system(open(args.system_id).read())
21 | except xmlrpclib.ProtocolError as err:
22 | print "A fault occurred"
23 | print "Fault string: %s" % err
24 | return 1
25 | except xmlrpclib.Fault as err:
26 | print "A fault occurred"
27 | print "Fault code: %d" % err.faultCode
28 | print "Fault string: %s" % err.faultString
29 | return 1
30 | except IOError as err:
31 | print "A fault occurred"
32 | print "Fault string: %s" % err
33 | return 1
34 | except Exception as e:
35 | print "A fault occurred"
36 | print "Fault: %s" % e
37 | return 1
38 | print "Unregister successful"
39 | return 0
40 |
41 | if __name__ == "__main__":
42 | sys.exit(main())
43 |
--------------------------------------------------------------------------------
/test/support/fake_ui.rb:
--------------------------------------------------------------------------------
1 | class FakeUI
2 | def self.info(*args)
3 | end
4 | end
5 |
--------------------------------------------------------------------------------
/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | $:.push(File.expand_path('../../plugins', __FILE__))
2 | $:.push(File.expand_path('../../lib', __FILE__))
3 |
4 | require 'bundler/setup'
5 |
6 | require 'vagrant-registration'
7 | require 'guests/redhat/cap/subscription_manager'
8 | require 'guests/redhat/cap/rhn_register'
9 |
10 | require 'minitest/autorun'
11 | require 'mocha/mini_test'
12 |
13 | require_relative 'support/fake_ui.rb'
14 |
15 | def fake_environment(options = { enabled: true })
16 | { machine: fake_machine(options), ui: FakeUI }
17 | end
18 |
19 | class RecordingCommunicator
20 | attr_reader :commands, :responses
21 |
22 | def initialize
23 | @commands = Hash.new([])
24 | @responses = Hash.new('')
25 | end
26 |
27 | def stub_command(command, response)
28 | responses[command] = response
29 | end
30 |
31 | def sudo(command)
32 | #puts "SUDO: #{command}"
33 | commands[:sudo] << command
34 | responses[command]
35 | end
36 |
37 | def execute(command)
38 | #puts "EXECUTE: #{command}"
39 | commands[:execute] << command
40 | responses[command].split("\n").each do |line|
41 | yield(:stdout, "#{line}\n")
42 | end
43 | end
44 |
45 | def test(command)
46 | commands[:test] << command
47 | true
48 | end
49 |
50 | def ready?
51 | true
52 | end
53 | end
54 |
55 | module Registration
56 | class FakeProvider
57 | def initialize(*args)
58 | end
59 |
60 | def _initialize(*args)
61 | end
62 |
63 | def ssh_info
64 | end
65 |
66 | def state
67 | @state ||= Vagrant::MachineState.new('fake-state', 'fake-state', 'fake-state')
68 | end
69 | end
70 | end
71 |
72 | module Registration
73 | class FakeConfig
74 | def registration
75 | @registration_config ||= VagrantPlugins::Registration::Config.new
76 | end
77 |
78 | def vm
79 | VagrantPlugins::Kernel_V2::VMConfig.new
80 | end
81 | end
82 | end
83 |
84 | def fake_machine(options={})
85 | env = options.fetch(:env, Vagrant::Environment.new)
86 | machine = Vagrant::Machine.new(
87 | 'fake_machine',
88 | 'fake_provider',
89 | Registration::FakeProvider,
90 | 'provider_config',
91 | {}, # provider_options
92 | env.vagrantfile.config, # config
93 | Pathname('data_dir'),
94 | 'box',
95 | options.fetch(:env, Vagrant::Environment.new),
96 | env.vagrantfile
97 | )
98 |
99 | machine.instance_variable_set("@communicator", RecordingCommunicator.new)
100 | machine.config.vm.hostname = options.fetch(:hostname, 'somehost.vagrant.test')
101 | machine
102 | end
103 |
104 | module MiniTest
105 | class Spec
106 | alias_method :hush, :capture_io
107 | end
108 | end
109 |
110 |
111 |
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/test/vagrant-registration/cap/redhat/rhn_register_test.rb:
--------------------------------------------------------------------------------
1 | require_relative '../../../test_helper.rb'
2 |
3 | describe VagrantPlugins::GuestRedHat::Cap::RhnRegister do
4 | let(:machine) { fake_machine }
5 |
6 | describe 'options' do
7 | it 'supports proxy options' do
8 | supported_options = VagrantPlugins::GuestRedHat::Cap::RhnRegister.rhn_register_options(machine)
9 | supported_options.must_include :proxy
10 | supported_options.must_include :proxyUser
11 | supported_options.must_include :proxyPassword
12 | end
13 | end
14 |
15 | describe 'register' do
16 | it 'calls rhn_register with default options' do
17 | VagrantPlugins::GuestRedHat::Cap::RhnRegister.rhn_register_register(machine, FakeUI)
18 |
19 | assert_equal(2, machine.communicate.commands[:sudo].length, 'there should be only one recorded sudo command')
20 | registration_command = machine.communicate.commands[:sudo][1]
21 | assert_match(/rhnreg_ks/, registration_command, 'rhnreg_ks should have been called')
22 | end
23 |
24 | it 'passes username and password to rhn_register as specified via Vagrant config' do
25 | machine.config.registration.username = 'foo'
26 | machine.config.registration.password = 'bar'
27 |
28 | VagrantPlugins::GuestRedHat::Cap::RhnRegister.rhn_register_register(machine, FakeUI)
29 |
30 | registration_command = machine.communicate.commands[:sudo][1]
31 | assert_match(/--username='foo'/, registration_command, 'the username should have been set')
32 | assert_match(/--password='bar'/, registration_command, 'the password should have been set')
33 | end
34 | end
35 |
36 | it 'passes proxy settings to rhn_register as specified via Vagrant config' do
37 | machine.config.registration.proxy = 'mongo:8080'
38 | machine.config.registration.proxyUser = 'flash'
39 | machine.config.registration.proxyPassword = 'zarkov'
40 |
41 | VagrantPlugins::GuestRedHat::Cap::RhnRegister.rhn_register_register(machine, FakeUI)
42 |
43 | registration_command = machine.communicate.commands[:sudo][1]
44 | assert_match(/--proxy='mongo:8080'/, registration_command, 'the proxy server and port should have been set')
45 | assert_match(/--proxyUser='flash'/, registration_command, 'the proxy username have been set')
46 | assert_match(/--proxyPassword='zarkov'/, registration_command, 'the proxy password should have been set')
47 | end
48 | end
49 |
50 |
--------------------------------------------------------------------------------
/test/vagrant-registration/cap/redhat/subscription_manager_test.rb:
--------------------------------------------------------------------------------
1 | require_relative '../../../test_helper.rb'
2 |
3 | describe VagrantPlugins::GuestRedHat::Cap::SubscriptionManager do
4 | let(:machine) { fake_machine }
5 |
6 | describe 'options' do
7 | it 'supports proxy options' do
8 | supported_options = VagrantPlugins::GuestRedHat::Cap::SubscriptionManager.subscription_manager_options(machine)
9 | supported_options.must_include :proxy
10 | supported_options.must_include :proxyUser
11 | supported_options.must_include :proxyPassword
12 | end
13 | end
14 |
15 | describe 'register' do
16 | it 'calls subscription-manager register with default options' do
17 | VagrantPlugins::GuestRedHat::Cap::SubscriptionManager.subscription_manager_register(machine, FakeUI)
18 |
19 | # RecordingCommunicator keeps track of the commands executed
20 | assert_equal(1, machine.communicate.commands[:sudo].length, 'there should be only one recorded sudo command')
21 | registration_command = machine.communicate.commands[:sudo][0]
22 | assert_match(/subscription-manager register/, registration_command, 'subscription-manager register should have been called')
23 | end
24 |
25 | it 'passes username and password to subscription-manager as specified via Vagrant config' do
26 | machine.config.registration.username = 'foo'
27 | machine.config.registration.password = 'bar'
28 |
29 | VagrantPlugins::GuestRedHat::Cap::SubscriptionManager.subscription_manager_register(machine, FakeUI)
30 |
31 | registration_command = machine.communicate.commands[:sudo][0]
32 | assert_match(/--username='foo'/, registration_command, 'the username should have been set')
33 | assert_match(/--password='bar'/, registration_command, 'the password should have been set')
34 | end
35 | end
36 |
37 | it 'passes proxy settings to subscription-manager as specified via Vagrant config' do
38 | machine.config.registration.proxy = 'mongo:8080'
39 | machine.config.registration.proxyUser = 'flash'
40 | machine.config.registration.proxyPassword = 'zarkov'
41 |
42 | VagrantPlugins::GuestRedHat::Cap::SubscriptionManager.subscription_manager_register(machine, FakeUI)
43 |
44 | registration_command = machine.communicate.commands[:sudo][0]
45 | assert_match(/--proxy='mongo:8080'/, registration_command, 'the proxy server and port should have been set')
46 | assert_match(/--proxyuser='flash'/, registration_command, 'the proxy username have been set')
47 | assert_match(/--proxypassword='zarkov'/, registration_command, 'the proxy password should have been set')
48 | end
49 | end
50 |
51 |
--------------------------------------------------------------------------------
/vagrant-registration.gemspec:
--------------------------------------------------------------------------------
1 | $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
2 | require 'vagrant-registration/version'
3 |
4 | Gem::Specification.new do |s|
5 | s.name = 'vagrant-registration'
6 | s.version = VagrantPlugins::Registration::VERSION
7 | s.platform = Gem::Platform::RUBY
8 | s.license = 'GPL-2.0'
9 | s.authors = ['Langdon White', 'Josef Strzibny', 'et al']
10 | s.email = ['langdon@fedoraproject.org', 'strzibny@strzibny.name']
11 | s.summary = 'Automatic guest registration for Vagrant'
12 | s.description = 'Enables guests to be registered automatically which is especially useful for RHEL or SLES guests.'
13 | s.homepage = 'https://github.com/projectatomic/adb-vagrant-registration'
14 | s.required_rubygems_version = '>= 1.3.6'
15 |
16 | # Note that the entire gitignore(5) syntax is not supported, specifically
17 | # the '!' syntax, but it should mostly work correctly.
18 | root_path = File.dirname(__FILE__)
19 | all_files = Dir.chdir(root_path) do
20 | Dir.glob('lib/**/{*,.*}') +
21 | Dir.glob('plugins/**/{*,.*}') +
22 | Dir.glob('locales/**/{*,.*}') +
23 | Dir.glob('resources/**/{*,.*}') +
24 | ['Rakefile', 'Gemfile', 'README.adoc', 'CHANGELOG.adoc', 'LICENSE', 'vagrant-registration.gemspec']
25 | end
26 | all_files.reject! { |file| ['.', '..'].include?(File.basename(file)) }
27 | gitignore_path = File.join(root_path, '.gitignore')
28 | gitignore = File.readlines(gitignore_path)
29 | gitignore.map! { |line| line.chomp.strip }
30 | gitignore.reject! { |line| line.empty? || line =~ /^(#|!)/ }
31 |
32 | unignored_files = all_files.reject do |file|
33 | # Ignore any directories, the gemspec only cares about files
34 | next true if File.directory?(file)
35 |
36 | # Ignore any paths that match anything in the gitignore. We do
37 | # two tests here:
38 | #
39 | # - First, test to see if the entire path matches the gitignore.
40 | # - Second, match if the basename does, this makes it so that things
41 | # like '.DS_Store' will match sub-directories too (same behavior
42 | # as git).
43 | #
44 | gitignore.any? do |ignore|
45 | File.fnmatch(ignore, file, File::FNM_PATHNAME) ||
46 | File.fnmatch(ignore, File.basename(file), File::FNM_PATHNAME)
47 | end
48 | end
49 |
50 | s.files = unignored_files
51 | s.executables = unignored_files.map { |f| f[/^bin\/(.*)/, 1] }.compact
52 | s.require_path = 'lib'
53 | end
54 |
--------------------------------------------------------------------------------