Update version according to OSCI-856
[packages/precise/mcollective.git] / doc / classes / MCollective / DDL.html
1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!DOCTYPE html 
3      PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
4      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
5
6 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
7 <head>
8   <title>Module: MCollective::DDL</title>
9   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
10   <meta http-equiv="Content-Script-Type" content="text/javascript" />
11   <link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
12   <script type="text/javascript">
13   // <![CDATA[
14
15   function popupCode( url ) {
16     window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
17   }
18
19   function toggleCode( id ) {
20     if ( document.getElementById )
21       elem = document.getElementById( id );
22     else if ( document.all )
23       elem = eval( "document.all." + id );
24     else
25       return false;
26
27     elemStyle = elem.style;
28     
29     if ( elemStyle.display != "block" ) {
30       elemStyle.display = "block"
31     } else {
32       elemStyle.display = "none"
33     }
34
35     return true;
36   }
37   
38   // Make codeblocks hidden by default
39   document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
40   
41   // ]]>
42   </script>
43
44 </head>
45 <body>
46
47
48
49     <div id="classHeader">
50         <table class="header-table">
51         <tr class="top-aligned-row">
52           <td><strong>Module</strong></td>
53           <td class="class-name-in-header">MCollective::DDL</td>
54         </tr>
55         <tr class="top-aligned-row">
56             <td><strong>In:</strong></td>
57             <td>
58                 <a href="../../files/lib/mcollective/ddl/discoveryddl_rb.html">
59                 lib/mcollective/ddl/discoveryddl.rb
60                 </a>
61         <br />
62                 <a href="../../files/lib/mcollective/ddl/agentddl_rb.html">
63                 lib/mcollective/ddl/agentddl.rb
64                 </a>
65         <br />
66                 <a href="../../files/lib/mcollective/ddl/validatorddl_rb.html">
67                 lib/mcollective/ddl/validatorddl.rb
68                 </a>
69         <br />
70                 <a href="../../files/lib/mcollective/ddl/base_rb.html">
71                 lib/mcollective/ddl/base.rb
72                 </a>
73         <br />
74                 <a href="../../files/lib/mcollective/ddl/dataddl_rb.html">
75                 lib/mcollective/ddl/dataddl.rb
76                 </a>
77         <br />
78                 <a href="../../files/lib/mcollective/ddl_rb.html">
79                 lib/mcollective/ddl.rb
80                 </a>
81         <br />
82             </td>
83         </tr>
84
85         </table>
86     </div>
87   <!-- banner header -->
88
89   <div id="bodyContent">
90
91
92
93   <div id="contextContent">
94
95     <div id="description">
96       <p>
97 A set of classes that helps create data description language files for
98 plugins. You can define meta data, actions, input and output describing the
99 behavior of your agent or other plugins
100 </p>
101 <p>
102 <a href="DDL.html">DDL</a> files are used for input validation,
103 constructing outputs, producing online help, informing the various display
104 routines and so forth.
105 </p>
106 <p>
107 A sample <a href="DDL.html">DDL</a> for an agent be seen below, you&#8216;d
108 put this in your agent dir as &lt;agent name&gt;.ddl
109 </p>
110 <pre>
111    metadata :name        =&gt; &quot;SimpleRPC Service Agent&quot;,
112             :description =&gt; &quot;Agent to manage services using the Puppet service provider&quot;,
113             :author      =&gt; &quot;R.I.Pienaar&quot;,
114             :license     =&gt; &quot;GPLv2&quot;,
115             :version     =&gt; &quot;1.1&quot;,
116             :url         =&gt; &quot;http://mcollective-plugins.googlecode.com/&quot;,
117             :timeout     =&gt; 60
118
119    action &quot;status&quot;, :description =&gt; &quot;Gets the status of a service&quot; do
120       display :always
121
122       input :service,
123             :prompt      =&gt; &quot;Service Name&quot;,
124             :description =&gt; &quot;The service to get the status for&quot;,
125             :type        =&gt; :string,
126             :validation  =&gt; '^[a-zA-Z\-_\d]+$',
127             :optional    =&gt; true,
128             :maxlength   =&gt; 30
129
130       output :status,
131              :description =&gt; &quot;The status of service&quot;,
132              :display_as  =&gt; &quot;Service Status&quot;
133   end
134 </pre>
135 <p>
136 There are now many types of <a href="DDL.html">DDL</a> and ultimately all
137 pugins should have <a href="DDL.html">DDL</a> files. The code is organized
138 so that any plugin type will magically just work - they will be an instane
139 of <a href="DDL/Base.html">Base</a> which has metadata and a few common
140 cases.
141 </p>
142 <p>
143 For plugin types that require more specific behaviors they can just add a
144 class here that inherits from <a href="DDL/Base.html">Base</a> and add
145 their specific behavior.
146 </p>
147 <p>
148 <a href="DDL/Base.html">Base</a> defines a specific behavior for input,
149 output and metadata which we&#8216;d like to keep standard across plugin
150 types so do not completely override the behavior of input. The methods are
151 written that they will gladly store extra content though so you add, do not
152 remove. See the <a href="DDL/AgentDDL.html">AgentDDL</a> class for an
153 example where agents want a :required argument to be always set.
154 </p>
155
156     </div>
157
158
159    </div>
160
161     <div id="method-list">
162       <h3 class="section-bar">Methods</h3>
163
164       <div class="name-list">
165       <a href="#M000156">load_and_cache</a>&nbsp;&nbsp;
166       <a href="#M000155">new</a>&nbsp;&nbsp;
167       <a href="#M000157">string_to_boolean</a>&nbsp;&nbsp;
168       <a href="#M000158">string_to_number</a>&nbsp;&nbsp;
169       <a href="#M000159">validation_fail!</a>&nbsp;&nbsp;
170       </div>
171     </div>
172
173   </div>
174
175
176     <!-- if includes -->
177
178     <div id="section">
179
180     <div id="class-list">
181       <h3 class="section-bar">Classes and Modules</h3>
182
183       Class <a href="DDL/AgentDDL.html" class="link">MCollective::DDL::AgentDDL</a><br />
184 Class <a href="DDL/Base.html" class="link">MCollective::DDL::Base</a><br />
185 Class <a href="DDL/DataDDL.html" class="link">MCollective::DDL::DataDDL</a><br />
186 Class <a href="DDL/DiscoveryDDL.html" class="link">MCollective::DDL::DiscoveryDDL</a><br />
187 Class <a href="DDL/ValidatorDDL.html" class="link">MCollective::DDL::ValidatorDDL</a><br />
188
189     </div>
190
191
192
193
194       
195
196
197     <!-- if method_list -->
198     <div id="methods">
199       <h3 class="section-bar">Public Class methods</h3>
200
201       <div id="method-M000156" class="method-detail">
202         <a name="M000156"></a>
203
204         <div class="method-heading">
205           <a href="#M000156" class="method-signature">
206           <span class="method-name">load_and_cache</span><span class="method-args">(*args)</span>
207           </a>
208         </div>
209       
210         <div class="method-description">
211           <p><a class="source-toggle" href="#"
212             onclick="toggleCode('M000156-source');return false;">[Source]</a></p>
213           <div class="method-source-code" id="M000156-source">
214 <pre>
215     <span class="ruby-comment cmt"># File lib/mcollective/ddl.rb, line 71</span>
216 71:     <span class="ruby-keyword kw">def</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">load_and_cache</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">args</span>)
217 72:       <span class="ruby-constant">Cache</span>.<span class="ruby-identifier">setup</span>(<span class="ruby-identifier">:ddl</span>, <span class="ruby-value">300</span>)
218 73: 
219 74:       <span class="ruby-identifier">plugin</span> = <span class="ruby-identifier">args</span>.<span class="ruby-identifier">first</span>
220 75:       <span class="ruby-identifier">args</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">&gt;</span> <span class="ruby-value">1</span> <span class="ruby-operator">?</span> <span class="ruby-identifier">type</span> = <span class="ruby-identifier">args</span>[<span class="ruby-value">1</span>].<span class="ruby-identifier">to_s</span> <span class="ruby-operator">:</span> <span class="ruby-identifier">type</span> = <span class="ruby-value str">&quot;agent&quot;</span>
221 76:       <span class="ruby-identifier">path</span> = <span class="ruby-value str">&quot;%s/%s&quot;</span> <span class="ruby-operator">%</span> [<span class="ruby-identifier">type</span>, <span class="ruby-identifier">plugin</span>]
222 77: 
223 78:       <span class="ruby-keyword kw">begin</span>
224 79:         <span class="ruby-identifier">ddl</span> = <span class="ruby-constant">Cache</span>.<span class="ruby-identifier">read</span>(<span class="ruby-identifier">:ddl</span>, <span class="ruby-identifier">path</span>)
225 80:       <span class="ruby-keyword kw">rescue</span>
226 81:         <span class="ruby-keyword kw">begin</span>
227 82:           <span class="ruby-identifier">klass</span> = <span class="ruby-constant">DDL</span>.<span class="ruby-identifier">const_get</span>(<span class="ruby-value str">&quot;%sDDL&quot;</span> <span class="ruby-operator">%</span> <span class="ruby-identifier">type</span>.<span class="ruby-identifier">capitalize</span>)
228 83:         <span class="ruby-keyword kw">rescue</span> <span class="ruby-constant">NameError</span>
229 84:           <span class="ruby-identifier">klass</span> = <span class="ruby-constant">Base</span>
230 85:         <span class="ruby-keyword kw">end</span>
231 86: 
232 87:         <span class="ruby-identifier">ddl</span> = <span class="ruby-constant">Cache</span>.<span class="ruby-identifier">write</span>(<span class="ruby-identifier">:ddl</span>, <span class="ruby-identifier">path</span>, <span class="ruby-identifier">klass</span>.<span class="ruby-identifier">new</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">args</span>))
233 88:       <span class="ruby-keyword kw">end</span>
234 89: 
235 90:       <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">ddl</span>
236 91:     <span class="ruby-keyword kw">end</span>
237 </pre>
238           </div>
239         </div>
240       </div>
241
242       <div id="method-M000155" class="method-detail">
243         <a name="M000155"></a>
244
245         <div class="method-heading">
246           <a href="#M000155" class="method-signature">
247           <span class="method-name">new</span><span class="method-args">(*args, &amp;blk)</span>
248           </a>
249         </div>
250       
251         <div class="method-description">
252           <p>
253 There used to be only one big nasty <a href="DDL.html">DDL</a> class with a
254 bunch of mashed together behaviors. It&#8216;s been around for ages and we
255 would rather not ask all the users to change their <a
256 href="DDL.html#M000155">DDL.new</a> calls to some other factory method that
257 would have this exact same behavior.
258 </p>
259 <p>
260 So we override the behavior of <a href="DDL.html#M000155">new</a> which is
261 a hugely sucky thing to do but ultimately it&#8216;s what would be least
262 disrupting to code out there today. We did though change <a
263 href="DDL.html">DDL</a> to a module to make it possibly a little less
264 suprising, possibly.
265 </p>
266           <p><a class="source-toggle" href="#"
267             onclick="toggleCode('M000155-source');return false;">[Source]</a></p>
268           <div class="method-source-code" id="M000155-source">
269 <pre>
270     <span class="ruby-comment cmt"># File lib/mcollective/ddl.rb, line 67</span>
271 67:     <span class="ruby-keyword kw">def</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">new</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">args</span>, <span class="ruby-operator">&amp;</span><span class="ruby-identifier">blk</span>)
272 68:       <span class="ruby-identifier">load_and_cache</span>(<span class="ruby-operator">*</span><span class="ruby-identifier">args</span>)
273 69:     <span class="ruby-keyword kw">end</span>
274 </pre>
275           </div>
276         </div>
277       </div>
278
279       <div id="method-M000157" class="method-detail">
280         <a name="M000157"></a>
281
282         <div class="method-heading">
283           <a href="#M000157" class="method-signature">
284           <span class="method-name">string_to_boolean</span><span class="method-args">(val)</span>
285           </a>
286         </div>
287       
288         <div class="method-description">
289           <p>
290 As we&#8216;re taking arguments on the command line we need a way to input
291 booleans, true on the cli is a string so this method will take the ddl,
292 find all arguments that are supposed to be boolean and if they are the
293 strings &quot;true&quot;/&quot;yes&quot; or
294 &quot;false&quot;/&quot;no&quot; turn them into the matching boolean
295 </p>
296           <p><a class="source-toggle" href="#"
297             onclick="toggleCode('M000157-source');return false;">[Source]</a></p>
298           <div class="method-source-code" id="M000157-source">
299 <pre>
300      <span class="ruby-comment cmt"># File lib/mcollective/ddl.rb, line 98</span>
301  98:     <span class="ruby-keyword kw">def</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">string_to_boolean</span>(<span class="ruby-identifier">val</span>)
302  99:       <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">true</span> <span class="ruby-keyword kw">if</span> [<span class="ruby-value str">&quot;true&quot;</span>, <span class="ruby-value str">&quot;t&quot;</span>, <span class="ruby-value str">&quot;yes&quot;</span>, <span class="ruby-value str">&quot;y&quot;</span>, <span class="ruby-value str">&quot;1&quot;</span>].<span class="ruby-identifier">include?</span>(<span class="ruby-identifier">val</span>.<span class="ruby-identifier">downcase</span>)
303 100:       <span class="ruby-keyword kw">return</span> <span class="ruby-keyword kw">false</span> <span class="ruby-keyword kw">if</span> [<span class="ruby-value str">&quot;false&quot;</span>, <span class="ruby-value str">&quot;f&quot;</span>, <span class="ruby-value str">&quot;no&quot;</span>, <span class="ruby-value str">&quot;n&quot;</span>, <span class="ruby-value str">&quot;0&quot;</span>].<span class="ruby-identifier">include?</span>(<span class="ruby-identifier">val</span>.<span class="ruby-identifier">downcase</span>)
304 101: 
305 102:       <span class="ruby-identifier">raise_code</span>(<span class="ruby-identifier">:PLMC17</span>, <span class="ruby-value str">&quot;%{value} does not look like a boolean argument&quot;</span>, <span class="ruby-identifier">:debug</span>, <span class="ruby-identifier">:value</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">val</span>)
306 103:     <span class="ruby-keyword kw">end</span>
307 </pre>
308           </div>
309         </div>
310       </div>
311
312       <div id="method-M000158" class="method-detail">
313         <a name="M000158"></a>
314
315         <div class="method-heading">
316           <a href="#M000158" class="method-signature">
317           <span class="method-name">string_to_number</span><span class="method-args">(val)</span>
318           </a>
319         </div>
320       
321         <div class="method-description">
322           <p>
323 a generic string to number function, if a number looks like a float it
324 turns it into a float else an int. This is naive but should be sufficient
325 for numbers typed on the cli in most cases
326 </p>
327           <p><a class="source-toggle" href="#"
328             onclick="toggleCode('M000158-source');return false;">[Source]</a></p>
329           <div class="method-source-code" id="M000158-source">
330 <pre>
331      <span class="ruby-comment cmt"># File lib/mcollective/ddl.rb, line 108</span>
332 108:     <span class="ruby-keyword kw">def</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">string_to_number</span>(<span class="ruby-identifier">val</span>)
333 109:       <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">val</span>.<span class="ruby-identifier">to_f</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">val</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/^\d+\.\d+$/</span>
334 110:       <span class="ruby-keyword kw">return</span> <span class="ruby-identifier">val</span>.<span class="ruby-identifier">to_i</span> <span class="ruby-keyword kw">if</span> <span class="ruby-identifier">val</span> <span class="ruby-operator">=~</span> <span class="ruby-regexp re">/^\d+$/</span>
335 111: 
336 112:       <span class="ruby-identifier">raise_code</span>(<span class="ruby-identifier">:PLMC16</span>, <span class="ruby-value str">&quot;%{value} does not look like a numeric value&quot;</span>, <span class="ruby-identifier">:debug</span>, <span class="ruby-identifier">:value</span> =<span class="ruby-operator">&gt;</span> <span class="ruby-identifier">val</span>)
337 113:     <span class="ruby-keyword kw">end</span>
338 </pre>
339           </div>
340         </div>
341       </div>
342
343       <div id="method-M000159" class="method-detail">
344         <a name="M000159"></a>
345
346         <div class="method-heading">
347           <a href="#M000159" class="method-signature">
348           <span class="method-name">validation_fail!</span><span class="method-args">(code, default, level, args={})</span>
349           </a>
350         </div>
351       
352         <div class="method-description">
353           <p>
354 Various <a href="DDL.html">DDL</a> implementations will validate and raise
355 on error, this is a utility method to correctly setup a <a
356 href="DDLValidationError.html">DDLValidationError</a> exceptions and raise
357 them
358 </p>
359           <p><a class="source-toggle" href="#"
360             onclick="toggleCode('M000159-source');return false;">[Source]</a></p>
361           <div class="method-source-code" id="M000159-source">
362 <pre>
363      <span class="ruby-comment cmt"># File lib/mcollective/ddl.rb, line 117</span>
364 117:     <span class="ruby-keyword kw">def</span> <span class="ruby-keyword kw">self</span>.<span class="ruby-identifier">validation_fail!</span>(<span class="ruby-identifier">code</span>, <span class="ruby-identifier">default</span>, <span class="ruby-identifier">level</span>, <span class="ruby-identifier">args</span>={})
365 118:       <span class="ruby-identifier">exception</span> = <span class="ruby-constant">DDLValidationError</span>.<span class="ruby-identifier">new</span>(<span class="ruby-identifier">code</span>, <span class="ruby-identifier">default</span>, <span class="ruby-identifier">level</span>, <span class="ruby-identifier">args</span>)
366 119:       <span class="ruby-identifier">exception</span>.<span class="ruby-identifier">set_backtrace</span> <span class="ruby-identifier">caller</span>
367 120: 
368 121:       <span class="ruby-identifier">raise</span> <span class="ruby-identifier">exception</span>
369 122:     <span class="ruby-keyword kw">end</span>
370 </pre>
371           </div>
372         </div>
373       </div>
374
375
376     </div>
377
378
379   </div>
380
381
382 <div id="validator-badges">
383   <p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
384 </div>
385
386 </body>
387 </html>