forked from hajee/hajee.github.io
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathatom.xml
More file actions
2128 lines (1569 loc) · 156 KB
/
atom.xml
File metadata and controls
2128 lines (1569 loc) · 156 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><![CDATA[People & Software]]></title>
<link href="http://hajee.github.io/atom.xml" rel="self"/>
<link href="http://hajee.github.io/"/>
<updated>2014-09-27T10:08:16+02:00</updated>
<id>http://hajee.github.io/</id>
<author>
<name><![CDATA[Bert Hajee]]></name>
<email><![CDATA[hajee@moretIA.com]]></email>
</author>
<generator uri="http://octopress.org/">Octopress</generator>
<entry>
<title type="html"><![CDATA[Review of the book Mastering Puppet]]></title>
<link href="http://hajee.github.io/2014/09/26/review-of-the-book-mastering-puppet/"/>
<updated>2014-09-26T22:58:22+02:00</updated>
<id>http://hajee.github.io/2014/09/26/review-of-the-book-mastering-puppet</id>
<content type="html"><![CDATA[<h1>Review of the book ‘Mastering puppet’</h1>
<p>I’ve had the privilege of reviewing a new Puppet book. The book is called
<a href="https://www.packtpub.com/networking-and-servers/mastering-puppet">‘Mastering Puppet’</a> and it is published by <a href="https://www.packtpub.com/">Packt publishing</a> and written by Thomas Uphill.</p>
<p><img src="https://dgdsbygo8mp3h.cloudfront.net/sites/default/files/imagecache/ppv4_main_book_cover/2189OS_cov.jpg" title="The book cover" ></p>
<!-- more -->
<h2>Structure of the book</h2>
<p>The book is 251 pages that contain the following ten chapters:</p>
<ul>
<li>Dealing with Load/Scale</li>
<li>Organizing Your Nodes and Data</li>
<li>Git and Environments</li>
<li>Public Modules</li>
<li>Custom Facts and Modules</li>
<li>Custom Types</li>
<li>Reporting and Orchestration</li>
<li>Exported Resources</li>
<li>Roles and Profiles</li>
<li>Troubleshooting</li>
</ul>
<h2>Learning style</h2>
<p>All chapters contain lots of commands and screen output. This way you are taken through the commands needed to get the job done. Some people like this. Personally when I read the term “Mastering” in a book title, I expect the book to be a book written for people who are almost master. I find this book more of a Puppet cookbook than a book that explains the mastery details of Puppet.</p>
<p>Almost from the start of the chapter, it dives into the details and commands needed to get the job done. This without showing the big picture.</p>
<h2>Book content</h2>
<p>Most of the chapters in the book address existing challenges for using Puppet in big enterprise environments. Chapter 1 discusses how to scale puppet servers. Given the fact that Puppetlabs just announces a much better performing puppet server, shows that this used to be a real challenge. But it is uncertain if the tips and tricks in this chapter are still needed and if they still work.</p>
<p>I would have liked the chapter on roles and profiles to be a bit more elusive. I think that getting the roles and profiles right, helps big to keep enterprise environments manageable in puppet. The chapter in the book just scratches the surface and leaves a lot of important stuff to be discovered.</p>
<p>Same thing applies to the chapter on custom types. The chapter deals mostly with <code>defined types</code> and a small part of the chapter is on custom types. Again personally I would’ve liked these chapters to be more extensive. If you want to know more about custom types, you can always get the book <a href="http://shop.oreilly.com/product/0636920026860.do">Puppet Types and Providers</a> by <a href="http://www.oreillynet.com/pub/au/5593">Dan Bode</a> and <a href="http://www.oreilly.com/pub/au/5594">Nan Liu</a></p>
<h2>Conclusion</h2>
<p>Some of my comments are pretty harsh. This doesn’t mean the book isn’t useful. Like I said before, the book is more of a cookbook then a book explaining how to become a master at Puppet. But if you look at the book as a cookbook, it is a pretty extensive cookbook. A cookbook that takes the by the hand and guides it through a couple challenges of using Puppet in the enterprise.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Learning Puppet at the Puppet Pizza Place]]></title>
<link href="http://hajee.github.io/2014/06/26/pietros-puppet-pizza-place-1/"/>
<updated>2014-06-26T14:36:46+02:00</updated>
<id>http://hajee.github.io/2014/06/26/pietros-puppet-pizza-place-1</id>
<content type="html"><![CDATA[<h1>Learning Puppet at the Puppet Pizza Place</h1>
<p>In this set of blog posts, I will teach you the base concepts of the <a href="http://puppetlabs.com/puppet">puppet DSL</a>. Most of the time Puppet is taught within the context of IT configuration management. I’ve chosen not to do so. I’ve chosen baking pizza’s as the learning environment. It helps less technical people, like IT managers, for example, to get the concepts of Puppet.</p>
<!-- more -->
<h2>Pietro’s Puppet Pizza Place</h2>
<p>Pietro was worn out. He’d had a very busy day at his pizza place. Business was going well. Too well actually. Every evening he was totally worn out.To keep his business growing, but be less worn out at the end of the day, Pietro had started to look around for some help.</p>
<h3>Miss Piggy</h3>
<p>On the Internet, he’d run into this ad for <em>“Miss Piggy The Puppetized Pizza Robot”</em>. Miss Piggy was advertised as a robot able to make all sorts of Pizza’s. To control Miss Piggy, they used Puppet DSL. A DSL able to describe all the Pizza’s in the world. This looked like just the help Pietro needed, So he ordered it.</p>
<h3>Running along..</h3>
<p>All the examples in this blog post do really run. You can install the modules needed to do so by using the next commands:</p>
<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>$ puppet module install hajee/pizza</span></code></pre></td></tr></table></div></figure>
<p>Obviously you need to have Puppet installed first. Check the <a href="http://docs.puppetlabs.com/guides/install_puppet/pre_install.html">Puppet installation guide</a> for information on how to do this.</p>
<p>If you want more information about the Puppet pizza module, checkout <a href="https://forge.puppetlabs.com/hajee/pizza">the puppet forge page</a> for this module.</p>
<h3>Getting to know Miss Piggy</h3>
<p>Miss Piggy looked like an ordinary robot. It just didn’t do anything yet. Pietro needed to tell Miss Piggy what he wanted. What kind of pizza he would like Miss Piggy to make. Let’s first see what ingredients Miss Piggy knew. Pietro looked in the manual and typed the command:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>puppet describe -l
</span><span class='line'>These are the types known to puppet:
</span><span class='line'>anchovy - Add anchovy to the pizza or modify the amount ...
</span><span class='line'>bacon - Add bacon to the pizza or modify the amount o ...
</span><span class='line'>cheese - Add cheese to the pizza or modify the amount ...
</span><span class='line'>crust - Select the crust <span class="k">for </span>your pizza
</span><span class='line'>mushroom - Add mushrooms to the pizza or modify the amou ...
</span><span class='line'>salami - Add salami to the pizza or modify the amount ...
</span><span class='line'>tomato_sauce - Add tomato sauce to the pizza or modify the a ...
</span></code></pre></td></tr></table></div></figure>
<p>This showed a list of all components (ingredients) Miss Piggy new. In the manual, it stated that Puppet knows these ingredients as types.</p>
<p>Seeing this list of things Pietro knew about, he started to get enthusiasts. Let’s start with the crust. Again Pietro looked in the manual. It stated that in order to get to know a type intimately, you can ask Puppet for information. So Pietro typed:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>puppet describe crust
</span><span class='line'><span class="nv">crust</span>
</span><span class='line'><span class="o">=====</span>
</span><span class='line'>Select the crust <span class="k">for </span>your pizza. An example:
</span><span class='line'>crust<span class="o">{</span><span class="s2">"large_wholesome_pan_crust"</span>:
</span><span class='line'> <span class="nv">ensure</span> <span class="o">=</span>> baked,
</span><span class='line'> <span class="nv">size</span> <span class="o">=</span>> 20, <span class="c"># 10", 20"</span>
</span><span class='line'> <span class="nb">type</span> <span class="o">=</span>> <span class="s1">'pan'</span>, <span class="c"># thin</span>
</span><span class='line'> <span class="nv">dough</span> <span class="o">=</span>> <span class="s1">'wholesome'</span>, <span class="c"># wholesome ore white</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>Parameters
</span><span class='line'>----------
</span><span class='line'>
</span><span class='line'>- **dough**
</span><span class='line'> The <span class="nb">type </span>of dough to use <span class="k">for </span>your crust
</span><span class='line'> Valid values are <span class="sb">`</span>wholesome<span class="sb">`</span>, <span class="sb">`</span>white<span class="sb">`</span>, <span class="sb">`</span>regular<span class="sb">`</span>.
</span><span class='line'>
</span><span class='line'>- **ensure**
</span><span class='line'> is the crust baked or raw
</span><span class='line'>Valid values are <span class="sb">`</span>baked<span class="sb">`</span>, <span class="sb">`</span>absent<span class="sb">`</span>.
</span><span class='line'>
</span><span class='line'>- **name**
</span><span class='line'> The ingredient<span class="err">'</span>s name
</span><span class='line'>
</span><span class='line'>- **size**
</span><span class='line'> the size of the pizza crus in inches
</span><span class='line'>
</span><span class='line'>- **type**
</span><span class='line'> The <span class="nb">type </span>of crust
</span><span class='line'>Valid values are <span class="sb">`</span>thin<span class="sb">`</span>, <span class="sb">`</span>pan<span class="sb">`</span>, <span class="sb">`</span>regular<span class="sb">`</span>.
</span><span class='line'>
</span><span class='line'>Providers
</span><span class='line'>---------
</span><span class='line'> simple
</span></code></pre></td></tr></table></div></figure>
<h3>The first try</h3>
<p>He started to get more and more excited. He expected a lot of technical stuff, but instead he saw that Puppet knew about pizza’s. Puppet knew about pan and regular pizza’s and about regular and wholesome dough. So let’s get Miss Piggy to make a crust. Pietro opened a file and entered the instruction:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>crust<span class="o">{</span><span class="s2">"large_wholesome_pan_crust"</span>:
</span><span class='line'> <span class="nv">ensure</span> <span class="o">=</span>> baked,
</span><span class='line'> <span class="nv">size</span> <span class="o">=</span>> 20, <span class="c"># 10", 20"</span>
</span><span class='line'> <span class="nb">type</span> <span class="o">=</span>> <span class="s1">'pan'</span>, <span class="c"># thin</span>
</span><span class='line'> <span class="nv">dough</span> <span class="o">=</span>> <span class="s1">'wholesome'</span>, <span class="c"># wholesome ore white</span>
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>Then he saved it as <code>crust.pp</code> and told Puppet to go do it.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>puppet apply crust.pp
</span><span class='line'>Notice: Compiled catalog <span class="k">for </span>macintosh.local in environment production in 0.10 seconds
</span></code></pre></td></tr></table></div></figure>
<p>All of a sudden he saw Miss Piggy come to life. She started buzzing and beeping. Got some wholesome dough. Made it into a 20” slice, put it into a pizza pan and pushed it into a pizza oven. After 3 minutes, Pietro was staring at a perfect pizza crust. A bleep on then Puppet console showed that Puppet was ready.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>Notice: /Stage<span class="o">[</span>main<span class="o">]</span>/Main/Crust<span class="o">[</span>large_wholesome_pan_crust<span class="o">]</span>/ensure: ensure changed <span class="s1">'present'</span> to <span class="s1">'baked'</span>
</span><span class='line'>Notice: Finished catalog run in 181.10 seconds
</span></code></pre></td></tr></table></div></figure>
<h3>What did I do?</h3>
<p>Pietro took a while to take this all in. What exactly did he do? He described through a Pupped DSL how the pizza should look. He didn’t describe how to make it. Miss Piggy already knew that. She knew about the dough. She knew about pan pizza’s and about the pizza size. Pietro just had to describe it in the DSL. The DSL was actually very simple. Just name the resource (type/ingerdient) place a <code>{</code>, specify a name. Any name as long as it is unique for the resource. Close it of with a <code>:</code> sign and then start with the properties of the pizza. Every property contains a name like for example: <code>size</code> and a value like <code>20</code>. They are separated by a <code>=></code> sign. After the value, he placed a <code>,</code>. Even after the last value. After the last value, the description was closed off with a <code>}</code> sign.</p>
<h3>Add some sauce and cheese</h3>
<p>That was good, but not enough. A crust is not a pizza. Pietro needed to add some tomato sauce and cheese. He opened a new file named <code>pizza.pp</code> and entered all the ingredients for a real pizza.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'> crust<span class="o">{</span><span class="s2">"large_wholesome_thin_crust"</span>:
</span><span class='line'> <span class="nv">ensure</span> <span class="o">=</span>> baked,
</span><span class='line'> <span class="nv">size</span> <span class="o">=</span>> 20, <span class="c"># 10", 20"</span>
</span><span class='line'> <span class="nb">type</span> <span class="o">=</span>> <span class="s1">'thin'</span>, <span class="c"># thin</span>
</span><span class='line'> <span class="nv">dough</span> <span class="o">=</span>> <span class="s1">'wholesome'</span>, <span class="c"># wholesome ore white</span>
</span><span class='line'> <span class="o">}</span>
</span><span class='line'>
</span><span class='line'> tomato_sauce<span class="o">{</span><span class="s2">"thin_cristal"</span>:
</span><span class='line'> <span class="nv">ensure</span> <span class="o">=</span>> <span class="s1">'present'</span>,
</span><span class='line'> <span class="nb">type</span> <span class="o">=</span>> <span class="s1">'cristal'</span>,
</span><span class='line'> <span class="nv">composure</span> <span class="o">=</span>> <span class="s1">'thick'</span>,
</span><span class='line'> <span class="nv">amount</span> <span class="o">=</span>> 5,
</span><span class='line'> <span class="o">}</span>
</span><span class='line'>
</span><span class='line'> cheese<span class="o">{</span><span class="s2">"mozzarella_thick"</span>:
</span><span class='line'> <span class="nv">ensure</span> <span class="o">=</span>> <span class="s1">'present'</span>,
</span><span class='line'> <span class="nb">type</span> <span class="o">=</span>> <span class="s1">'mozzarella'</span>,
</span><span class='line'> <span class="nv">amount</span> <span class="o">=</span>> <span class="s1">'2'</span>,
</span><span class='line'> <span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>
<p></p>
<p>Just like before, Pietro instructed Miss Piggy to go and do it.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>puppet apply pizza.pp
</span><span class='line'>Notice: Compiled catalog <span class="k">for </span>macintosh.local in environment production in 0.14 seconds
</span><span class='line'>Notice: /Stage<span class="o">[</span>main<span class="o">]</span>/Main/Tomato_sauce<span class="o">[</span>thin_cristal<span class="o">]</span>/ensure: created
</span><span class='line'>Notice: /Stage<span class="o">[</span>main<span class="o">]</span>/Main/Crust<span class="o">[</span>large_wholesome_thin_crust<span class="o">]</span>/ensure: defined <span class="s1">'ensure'</span> as <span class="s1">'baked'</span>
</span><span class='line'>Notice: /Stage<span class="o">[</span>main<span class="o">]</span>/Main/Cheese<span class="o">[</span>mozzarella_thick<span class="o">]</span>/ensure: created
</span><span class='line'>Notice: Finished catalog run in 181.10 seconds
</span></code></pre></td></tr></table></div></figure>
<p>But now something strange happened. Miss Piggy started by putting tomato sauce on the table and then adding the crust dough afterwards. That was obviously <strong>not</strong> what Pietro wanted. There must be some defect in Miss Piggy. Everyone knows that the pizza crust must be available <strong>before</strong>* the tomato sauce and other ingredients can be added.</p>
<p>Pietro looked in the manual. Aah there it was. Miss Piggy knows a lot, but you have to tell it the order in which the ingredients are applied. To do this, add an explicit order in the description of the pizza. You can do this by using the <code>require</code> keyword. Let’s change the pizza description and save it as <code>pizza2.pp</code>. To make it more interesting, let’s change some ingredients as well. Let’s make medium thin pizza with thick cristal tomato sauce and a lot of mozzarella.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>crust<span class="o">{</span><span class="s2">"medium_wholesome_thin_crust"</span>:
</span><span class='line'> <span class="nv">ensure</span> <span class="o">=</span>> baked,
</span><span class='line'> <span class="nv">size</span> <span class="o">=</span>> 10, <span class="c"># 10", 20"</span>
</span><span class='line'> <span class="nb">type</span> <span class="o">=</span>> <span class="s1">'thin'</span>, <span class="c"># thin</span>
</span><span class='line'> <span class="nv">dough</span> <span class="o">=</span>> <span class="s1">'wholesome'</span>, <span class="c"># wholesome ore white</span>
</span><span class='line'><span class="o">}</span>
</span><span class='line'>
</span><span class='line'>tomato_sauce<span class="o">{</span><span class="s2">"thick_cristal"</span>:
</span><span class='line'> <span class="nv">ensure</span> <span class="o">=</span>> <span class="s1">'present'</span>,
</span><span class='line'> <span class="nb">type</span> <span class="o">=</span>> <span class="s1">'cristal'</span>,
</span><span class='line'> <span class="nv">composure</span> <span class="o">=</span>> <span class="s1">'thick'</span>,
</span><span class='line'> <span class="nv">amount</span> <span class="o">=</span>> 5,
</span><span class='line'> <span class="nv">require</span> <span class="o">=</span>> Crust<span class="o">[</span><span class="s2">"medium_wholesome_thin_crust"</span><span class="o">]</span>,
</span><span class='line'><span class="o">}</span>
</span><span class='line'>
</span><span class='line'>cheese<span class="o">{</span><span class="s2">"a_lot_of_mozzarella"</span>:
</span><span class='line'> <span class="nv">ensure</span> <span class="o">=</span>> <span class="s1">'present'</span>,
</span><span class='line'> <span class="nb">type</span> <span class="o">=</span>> <span class="s1">'mozzarella'</span>,
</span><span class='line'> <span class="nv">amount</span> <span class="o">=</span>> <span class="s1">'4'</span>,
</span><span class='line'> <span class="nv">require</span> <span class="o">=</span>> Tomato_sauce<span class="o">[</span><span class="s2">"thick_cristal"</span><span class="o">]</span>,
</span><span class='line'><span class="o">}</span>
</span></code></pre></td></tr></table></div></figure>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">$ </span>puppet apply pizza2.pp
</span><span class='line'>Notice: Compiled catalog <span class="k">for </span>macintosh.local in environment production in 0.15 seconds
</span><span class='line'>Notice: /Stage<span class="o">[</span>main<span class="o">]</span>/Main/Crust<span class="o">[</span>medium_wholesome_thin_crust<span class="o">]</span>/ensure: defined <span class="s1">'ensure'</span> as <span class="s1">'baked'</span>
</span><span class='line'>Notice: /Stage<span class="o">[</span>main<span class="o">]</span>/Main/Tomato_sauce<span class="o">[</span>thick_cristal<span class="o">]</span>/ensure: created
</span><span class='line'>Notice: /Stage<span class="o">[</span>main<span class="o">]</span>/Main/Cheese<span class="o">[</span>a_lot_of_mozzarella<span class="o">]</span>/ensure: created
</span><span class='line'>Notice: Finished catalog run in 182.08 seconds
</span></code></pre></td></tr></table></div></figure>
<p>Pietro waited anxiously. What would Miss Piggy do this time? After 3 minutes, Pietro was looking at a perfect pizza Napolitana. That was much better. First the crust, then the tomato sauce and last but not least the cheese.</p>
<h3>What did I do?</h3>
<p>To make this an optimal learning experience, again Pietro looked at what he had accomplished. To be sure the ingredients were added in the right order, he had to specify what the order was. He could do so using the <code>require</code> attribute on an ingredient. The value of the <code>require</code> keyword was a reference to another ingredient. To specify a reference, you needed to start it with a capital letter. So <code>tomato_sauce</code> became <code>Tomato_sauce</code>. To uniquely identify the ingredient, he used the name of the ingredient as specified before and put it between a <code>[</code> and <code>]</code> character. So the reference to the thick cristal tomato sauce became:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'><span class="nv">require</span> <span class="o">=</span>> Tomato_sauce<span class="o">[</span><span class="s2">"thick_cristal"</span><span class="o">]</span>,
</span></code></pre></td></tr></table></div></figure>
<p></p>
<h2>Next time…</h2>
<p>That was a lot of learning going on. Pietro was even more worn out than normal. But he had confidence the Miss Piggy Puppet Pizza Robot was going to help him a lot. Tomorrow he would start at making descriptions for the first half of his menu.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Using Puppet to manage Oracle]]></title>
<link href="http://hajee.github.io/2014/02/23/using-puppet-to-manage-oracle/"/>
<updated>2014-02-23T08:01:51+01:00</updated>
<id>http://hajee.github.io/2014/02/23/using-puppet-to-manage-oracle</id>
<content type="html"><![CDATA[<p>Russ looked at his screen. He started to get a bit weary. How in heavens name would he be able to manage this. He was looking at the requests he had for twenty applications that all had specific Oracle database needs. All different with regards to tablespaces, users, rights and services. And if that wasn’t bad enough in itself, all of the project teams building those applications, had up to 5 specific environments with different sizes and sometimes other settings. Russ definitely could use some help with this.</p>
<p>If you are like Russ in dire need of help manageing your Oracle databases, you should checkout this blog post. It describes a Puppet module we are building and already using to manage the dba objects of an Oracle database.</p>
<!-- more -->
<h2>The requirements</h2>
<p>After discovering the <a href="https://forge.puppetlabs.com/hajee/oracle">Puppet Oracle module</a>, Russ felt a little bit less anxious. This could really make life a bit more easy.</p>
<p>First Russ started to look at the PIO application. The requirements for installing the PIO application where:</p>
<ol>
<li>An Oracle tablespace named <code>PIO_DATA</code> with a size of 200 Gigabyte</li>
<li>An oracle user <code>PIO_USER</code> with the default tablespace set to <code>PIO_DATA</code> and only <code>connect</code>, <code>select any table</code> and <code>create table</code> rights. Also the user must have unlimited quota’s in the <code>PIO_DATA</code> tablespace</li>
<li>An Oracle role <code>PIO_APPLICATION_USER</code></li>
<li>A Service named like the application. So a <code>PIO</code> service.</li>
</ol>
<p><sup>(This list is slimmed down a bit to make it more readable.)</sup></p>
<h2>The PIO Tablespace</h2>
<p>Let’s start with the tablespace requirement. With the new found Oracle module, this looks like a strait forward Puppet definition. This code should do the trick:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">tablespace</span> <span class="p">{</span><span class="s1">'PIO_DATA'</span><span class="p">:</span>
</span><span class='line'> <span class="k">ensure</span> <span class="o">=></span> <span class="n">present</span><span class="p">,</span>
</span><span class='line'> <span class="n">bigfile</span> <span class="o">=></span> <span class="n">yes</span>
</span><span class='line'> <span class="n">datafile</span> <span class="o">=></span> <span class="s1">'pio_data.dbf'</span>
</span><span class='line'> <span class="n">size</span> <span class="o">=></span> <span class="mi">200</span><span class="n">G</span><span class="p">,</span>
</span><span class='line'> <span class="n">logging</span> <span class="o">=></span> <span class="n">yes</span><span class="p">,</span>
</span><span class='line'> <span class="n">autoextend</span> <span class="o">=></span> <span class="n">on</span><span class="p">,</span>
</span><span class='line'> <span class="k">next</span> <span class="o">=></span> <span class="mi">100</span><span class="n">M</span><span class="p">,</span>
</span><span class='line'> <span class="n">max_size</span> <span class="o">=></span> <span class="mi">12288</span><span class="n">M</span><span class="p">,</span>
</span><span class='line'> <span class="n">extent_management</span> <span class="o">=></span> <span class="n">local</span><span class="p">,</span>
</span><span class='line'> <span class="n">segment_space_management</span> <span class="o">=></span> <span class="n">auto</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>So that takes care of requirement 1. let’s test it.</p>
<p>Wait, the Oracle module doesn’t install Oracle itself. What good is a module like this if you haven’t gotten Oracle installed. Fortunately Russ found <a href="https://forge.puppetlabs.com/biemond/oradb">Edwin Biemond’s Oracle DB module</a> to take care of the installation.</p>
<h2>The PIO User</h2>
<p>The oracle user <code>PIO</code> is a little bit more difficult. It has a default tablespace. So we must make sure the tablespace already exist before we start creating the user.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">oracle_user</span><span class="p">{</span><span class="s1">'PIO'</span><span class="p">:</span>
</span><span class='line'> <span class="n">temporary_tablespace</span> <span class="o">=></span> <span class="n">temp</span><span class="p">,</span>
</span><span class='line'> <span class="n">default_tablespace</span> <span class="o">=></span> <span class="s1">'PIO_DATA'</span><span class="p">,</span>
</span><span class='line'> <span class="n">password</span> <span class="o">=></span> <span class="s1">'justapassword,</span>
</span><span class='line'><span class="s1"> require => Tablespace['</span><span class="no">PIO_DATA</span><span class="s1">'],</span>
</span><span class='line'><span class="s1"> grants => ['</span><span class="no">SELECT</span> <span class="no">ANY</span> <span class="no">TABLE</span><span class="s1">', '</span><span class="no">CONNECT</span><span class="s1">', '</span><span class="no">CREATE</span> <span class="no">TABLE</span><span class="s1">'],</span>
</span><span class='line'><span class="s1"> quotas => {</span>
</span><span class='line'><span class="s1"> '</span><span class="no">PIO_DATA</span><span class="s1">' => '</span><span class="n">unlimited</span><span class="err">'</span>
</span><span class='line'> <span class="p">},</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>Again this looks like a strait forward Puppet definition. No Exec’s no if’s, just an easy readable Puppet definition. Requirement 3 fulfilled.</p>
<h2>The PIO_APPLICATION_USER role and the PIO service</h2>
<p>Making sure the role and the service exist, s super easy. Just look at this code:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">role</span> <span class="p">{</span><span class="s1">'PIO_APPLICATION_ROLE'</span><span class="p">:</span>
</span><span class='line'> <span class="k">ensure</span> <span class="o">=></span> <span class="n">present</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="n">oracle_service</span><span class="p">{</span><span class="s1">'PIO'</span><span class="p">:</span>
</span><span class='line'> <span class="k">ensure</span> <span class="o">=></span> <span class="n">present</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>This completes the list of requirements for one application. But when Russ looked at the other application’s, he noticed a very similar pattern. A user, a tablespace a role and a service. Only the values of the different applications where different.</p>
<h2>Puppet defined types to the rescue</h2>
<p>Puppet has some nice mechanisms to handle just this kind of repeating pattern. A <code>defined typ[e</code> . let’s create this type to manage all of Russ’s applications.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">define</span> <span class="ss">db</span><span class="p">:</span><span class="ss">:app</span><span class="p">(</span>
</span><span class='line'> <span class="vg">$tablespace_name</span> <span class="o">=</span> <span class="s2">"${name}_data"</span><span class="p">,</span>
</span><span class='line'> <span class="vg">$password</span> <span class="o">=</span> <span class="vg">$name</span><span class="p">,</span>
</span><span class='line'> <span class="vg">$size</span> <span class="o">=</span> <span class="mi">3072</span><span class="n">M</span><span class="p">,</span>
</span><span class='line'> <span class="vg">$maxsize</span> <span class="o">=</span> <span class="mi">12288</span><span class="n">M</span><span class="p">,</span>
</span><span class='line'> <span class="vg">$next</span> <span class="o">=</span> <span class="mi">100</span><span class="n">M</span><span class="p">,</span>
</span><span class='line'> <span class="vg">$user_rights</span> <span class="o">=</span> <span class="o">[</span><span class="s1">'SELECT ANY TABLE'</span>
</span><span class='line'> <span class="p">,</span> <span class="s1">'CONNECT'</span>
</span><span class='line'> <span class="p">,</span> <span class="s1">'CREATE TABLE'</span>
</span><span class='line'> <span class="o">]</span>
</span><span class='line'><span class="p">){</span>
</span><span class='line'> <span class="c1"># include the class that installes Oracle. to make sure</span>
</span><span class='line'> <span class="c1"># This defined type is run after the Oracle installation</span>
</span><span class='line'>
</span><span class='line'> <span class="n">tablespace</span> <span class="p">{</span><span class="vg">$tablespace_name</span><span class="p">:</span>
</span><span class='line'> <span class="k">ensure</span> <span class="o">=></span> <span class="n">present</span><span class="p">,</span>
</span><span class='line'> <span class="n">size</span> <span class="o">=></span> <span class="vg">$size</span><span class="p">,</span>
</span><span class='line'> <span class="n">logging</span> <span class="o">=></span> <span class="n">yes</span><span class="p">,</span>
</span><span class='line'> <span class="n">autoextend</span> <span class="o">=></span> <span class="n">on</span><span class="p">,</span>
</span><span class='line'> <span class="k">next</span> <span class="o">=></span> <span class="mi">100</span><span class="n">M</span><span class="p">,</span>
</span><span class='line'> <span class="n">max_size</span> <span class="o">=></span> <span class="mi">12288</span><span class="n">M</span><span class="p">,</span>
</span><span class='line'> <span class="n">extent_management</span> <span class="o">=></span> <span class="n">local</span><span class="p">,</span>
</span><span class='line'> <span class="n">segment_space_management</span> <span class="o">=></span> <span class="n">auto</span><span class="p">,</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'> <span class="n">oracle_user</span><span class="p">{</span><span class="vg">$name</span><span class="p">:</span>
</span><span class='line'> <span class="n">temporary_tablespace</span> <span class="o">=></span> <span class="n">temp</span><span class="p">,</span>
</span><span class='line'> <span class="n">default_tablespace</span> <span class="o">=></span> <span class="vg">$tablespace_name</span><span class="p">,</span>
</span><span class='line'> <span class="n">password</span> <span class="o">=></span> <span class="vg">$password</span><span class="p">,</span>
</span><span class='line'> <span class="nb">require</span> <span class="o">=></span> <span class="no">Tablespace</span><span class="o">[</span><span class="vg">$tablespace_name</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'> <span class="n">grants</span> <span class="o">=></span> <span class="o">[</span><span class="vg">$user_rights</span><span class="o">]</span><span class="p">,</span>
</span><span class='line'> <span class="n">quotas</span> <span class="o">=></span> <span class="p">{</span>
</span><span class='line'> <span class="s2">"${tablespace_name}"</span> <span class="o">=></span> <span class="s1">'unlimited'</span>
</span><span class='line'> <span class="p">},</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'> <span class="vg">$app_role</span> <span class="o">=</span> <span class="s2">"${name}_application_user"</span>
</span><span class='line'>
</span><span class='line'> <span class="n">role</span> <span class="p">{</span><span class="vg">$app_role</span><span class="p">:</span>
</span><span class='line'> <span class="k">ensure</span> <span class="o">=></span> <span class="n">present</span><span class="p">,</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'> <span class="n">oracle_service</span><span class="p">{</span><span class="vg">$name</span><span class="p">:</span>
</span><span class='line'> <span class="k">ensure</span> <span class="o">=></span> <span class="n">present</span><span class="p">,</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<h2>The new and improved PIO definition</h2>
<p>With this defined type in place, the <code>PIO</code> definition becomes:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="n">pio</span> <span class="p">{</span>
</span><span class='line'> <span class="ss">db</span><span class="p">:</span><span class="ss">:app</span><span class="p">{</span> <span class="s1">'pio'</span><span class="p">:</span>
</span><span class='line'> <span class="n">size</span> <span class="o">=></span> <span class="mi">200</span><span class="n">G</span><span class="p">,</span>
</span><span class='line'> <span class="n">password</span> <span class="o">=></span> <span class="s1">'justapassword'</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>For all the other applications, you can make the same kind of definitions. Your <code>node.pp</code> file could read like this:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">node</span> <span class="s2">"basenode"</span> <span class="p">{</span>
</span><span class='line'> <span class="kp">include</span> <span class="n">pio</span>
</span><span class='line'> <span class="kp">include</span> <span class="n">axe</span>
</span><span class='line'> <span class="kp">include</span> <span class="n">bcc</span>
</span><span class='line'> <span class="o">.</span><span class="n">.</span><span class="o">.</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<h2>You want to start as well?</h2>
<p>The code in the blog post is based on the <a href="https://forge.puppetlabs.com/hajee/oracle">Puppet Oracle module</a>. Checkout the <a href="https://github.com/hajee/oracle">repository</a> if you want to see how we do it. This is a fresh project, so you might run into some bugs. Don’t hesitate to register them at <a href="https://github.com/hajee/oracle/issues">the issue log</a>.</p>
<h2>You can help?</h2>
<p>That would be great. We only have a couple of Oracle DBA objects covered right now. There are lot’s more. It would really be nice if we could get this module covering a lot of Oracle stuff. Clone the <a href="https://github.com/hajee/oracle">repository</a> make your enhancements and post a pull request.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Puppet Custom Types, the easy way (part 2)]]></title>
<link href="http://hajee.github.io/2014/02/08/puppet-custom-types-the-easy-way-part-2/"/>
<updated>2014-02-08T13:57:20+01:00</updated>
<id>http://hajee.github.io/2014/02/08/puppet-custom-types-the-easy-way-part-2</id>
<content type="html"><![CDATA[<p>In the <a href="http://hajee.github.io/2014/01/26/puppet-custom-types-the-easy-way/">last blog post</a>, we started with our own custom type. We added the <code>easy_type</code> module, created the files necessary for getting started and got our custom running without any errors. We then added two lines to get into a state where Puppet was able to do an inventory of our systems. But a custom type not able to create, delete or modify the state of your system, wouldnt be very helpful. So in the blog post we are going to add that functionality to our custom_package type.</p>
<!-- more -->
<h2>Let’s recap</h2>
<p>Let’s first look back at what we did last time. To get started with <a href="https://github.com/hajee/easy_type">easy_type</a>, we made sure <code>easy_type</code> is installed in the module path. We used <code>librarian-puppet</code> to get <code>easy_type</code> installed. After that, we created the right directories and created a scaffold. Since the last blog post, we have added the scaffold to the <code>easy_type</code>. This makes’s it even easier to get started. To get it, use the next command:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>cp -Rv easy_type/scaffold custom_package/lib/puppet
</span></code></pre></td></tr></table></div></figure>
<p>After we created the scaffold, we checked what puppet would do with the type and noticed <code>Puppet</code> didn’t do anything, but also didn’t complain. So a good start.</p>
<p>Then we added the 2 lines of code for getting the raw package information from the system. After that, we added the 1 line of code that picked the name and version information from the raw package information. Then we had a working Puppet custom type.</p>
<p><img src="http://hajee.github.io/images/custom_package_list.png" title="Index from custom_package" ></p>
<p>Wel working…Sort of. Because the type doesn’t know yet how it can create, delete and modify resources. So that’s what we’re going to do next.</p>
<h2>How to create a resource in real life?</h2>
<p>Like I said in the <a href="http://hajee.github.io/2014/01/26/puppet-custom-types-the-easy-way/">last blog post</a>, a design goal of <code>easy_type</code> is to let you focus on the resource knowledge and let us do the Puppet stuff. So what is needed to create a new <code>custom_package</code> instance. To create a new <code>custom_package</code> instance, we need to install a package.</p>
<p>For <code>easy_type</code>, it would be the easiest thing if we could use the same base command as we used to get an index. That would be the <code>rpm</code> command, but in this case the best way to install a package is a <code>yum</code> command.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>yum -q install a_package
</span></code></pre></td></tr></table></div></figure>
<p>This would install the latest version. But what if we needed a specific version? Then <code>a_package</code> needs to be both the name and the version number, concatenated with a dash. For example:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>yum -q install php-5.2.6-2
</span></code></pre></td></tr></table></div></figure>
<p>Will install php version 5.2.6-2</p>
<h2>And how to do it in the Puppet world?</h2>
<p>So how do we get this knowledge into our own custom type? First we have to add the extra command (<code>yum</code>) that is used. We do this by changing the <code>set_command</code> line to:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">set_command</span> <span class="o">[</span><span class="ss">:rpm</span><span class="p">,</span> <span class="ss">:yum</span><span class="o">]</span>
</span></code></pre></td></tr></table></div></figure>
<p>This line tells <code>easy_type</code> that we use <code>rpm</code> and <code>yum</code> as commands. Next we have to tell <code>easy_type</code> to use <code>yum</code> when we need to create a resource:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">on_create</span> <span class="k">do</span> <span class="o">|</span><span class="n">command_builder</span><span class="o">|</span>
</span><span class='line'> <span class="n">command_builder</span><span class="o">.</span><span class="n">add</span> <span class="k">do</span>
</span><span class='line'> <span class="n">yum</span> <span class="s2">"install -y </span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2">"</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>
<p>But wait. What about the version number? Don’t we need to do add it somewhere? And you are right. We need to add it at the definition of the property. At the property add the lines:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">on_apply</span> <span class="k">do</span> <span class="o">|</span><span class="n">command_builder</span><span class="o">|</span>
</span><span class='line'> <span class="n">command_builder</span><span class="o">.</span><span class="n">append</span> <span class="k">do</span>
</span><span class='line'> <span class="s2">"-</span><span class="si">#{</span><span class="n">version</span><span class="si">}</span><span class="s2">"</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>
<p>The method is only run when we need to create a resource or when the attribute value in the manifest is different from the attribute value on the system. So in this case, because we create a resource the method is called. With the <code>append</code> method, we tell the <code>command_builder</code> to add some text to the string created before by the <code>command_builder.add</code>.</p>
<p>So now we are able to create a <code>custom_package</code> resource.</p>
<p><img src="http://hajee.github.io/images/custom_package_created.png" title="Install a package using custom_package type" ></p>
<h2>And now some destruction</h2>
<p>Like we saw before, <code>yum</code> is the command used to install a package. <code>yum</code> is also used to uninstall a package and therefore delete a resource in the Puppet world. The command will be:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>yum -q erase a_package
</span></code></pre></td></tr></table></div></figure>
<p>To get this wisdom into our custom type, we need to add some code to the <code>on_destroy</code> handler.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">on_destroy</span> <span class="k">do</span> <span class="o">|</span> <span class="n">command_builder</span><span class="o">|</span>
</span><span class='line'> <span class="n">command_builder</span><span class="o">.</span><span class="n">add</span> <span class="k">do</span>
</span><span class='line'> <span class="n">yum</span> <span class="s2">"erase -y </span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2">"</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>
<p>So besides indexing and creating, now our custom type is also ready for to destroy a resource.</p>
<p><img src="http://hajee.github.io/images/custom_package_destroy.png" title="Install a package using custom_package type" ></p>
<h2>How about modifying?</h2>
<p>Like we did before, we want to focus on our knowledge of the resource. What do we do when we modify the version attribute?</p>
<blockquote><p>The on_modify handler is a naive implementation that does not handle downgrade properly. The correct implementation should compare against the installed software version and invoke package downgrade when appropriate. The code here is kept simple; for more complete examples, see the ~/src/puppet/lib/puppet/provider/packages directory.</p><footer><strong>Just like in the book Puppet Types and providers</strong></footer></blockquote>
<p>So in our simple case, we just install the specified version. Actually we just do an <code>on_create</code>. So let’s tell our type to behave like that.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">on_modify</span> <span class="k">do</span> <span class="o">|</span> <span class="n">command_builder</span><span class="o">|</span>
</span><span class='line'> <span class="n">on_create</span><span class="p">(</span><span class="n">command_builder</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>
<p>So now when we change the version number, a different package is installed.</p>
<p><img src="http://hajee.github.io/images/custom_package_modified.png" title="Install a package using custom_package type" ></p>
<h2>AND TA TAAHH</h2>
<p>Now we are ready. We have a Custom Puppet Type that has the ability to:</p>
<ul>
<li>Do an index</li>
<li>create a new resource</li>
<li>destroy/delete a resource</li>
<li>and modify an existing resource</li>
</ul>
<p>If we don’t count the boiler plate code, then we added just 18 lines of code to get this working. Not to bad.</p>
<h2>There’s a lot more</h2>
<p>Like I said in the introduction, this is really a simple example. Real life custom types are more difficult. So <code>easy_type</code> has some more functionality that is not shown in this examples.</p>
<ul>
<li>support for standard mungers</li>
<li>support for standard validators</li>
<li>A lot of tricks in the command_builder so it’s easy to build commands based on what Puppet thinks, needs to be done.</li>
<li>support for extracting the definition of attributes and properties</li>
</ul>
<p>If you would like to see more about <code>easy_type</code>, just let me know and I will see if we can do some more posts about it. For now, check the example source in the <a href="https://github.com/hajee/my_own_easy_type">github repository</a>. You can also check some <a href="https://github.com/hajee/oracle">Oracle Custom Types</a> which are build upon <code>easy_type</code>.</p>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[Puppet Custom Types, the easy way]]></title>
<link href="http://hajee.github.io/2014/01/26/puppet-custom-types-the-easy-way/"/>
<updated>2014-01-26T13:57:20+01:00</updated>
<id>http://hajee.github.io/2014/01/26/puppet-custom-types-the-easy-way</id>
<content type="html"><![CDATA[<p>Robert scratched his head. How would he get a Puppet class to manage a complex resource on his systems? I guess I’ll have to make a Custom Type, he thought. But last time I looked into that, I noticed you need to know a lot about Puppet Internals.</p>
<p>If you recognize this thought process, maybe it’s time to meet <a href="https://github.com/hajee/easy_type">easy_type</a>. Like the name says, easy type is designed to make it easy to build a Custom Puppet Type. In this article, we will introduce <a href="https://github.com/hajee/easy_type">easy_type</a>. We do this by taking you along on in the process of making a Custom Type. In the process, we explain how <code>easy_type</code> actually makes it…… well easy to build a Custom Type. In the first part, we will show you how to get Puppet to see and index all your resources. In the next blog posts, we will enhance the Custom Type to be able to create, remove and modify existing resources.</p>
<!-- more -->
<h2>When to build a Custom Type</h2>
<p>Well that’s an interesting question! The Puppet language is actually very versatile, and you can do anything with it. But why would you step out of puppet and into ruby to build a Custom Type? In one of his <a href="http://garylarizza.com/blog/2013/11/25/fun-with-providers/">excellent blog posts</a>, Gary Larizza explains it in one sentence: “Because 20 execs in a defined type… “. Another indication, you’d be better of on a Custom Type path instead of a defined type, is when you need to build one or more custom facts.</p>
<blockquote><p>What would drive someone to write a custom type and provider for Puppet anyhow? Afterall, you can do ANYTHING IMAGINABLE in the Puppet DSL*! After drawing back my sarcasm a bit, let me explain where the Puppet DSL tends to fall over and the idea of a custom type and provider starts becoming more than just an incredibly vivid dream:</p><p><ul><br/> <li>You have more than a couple of exec statements in a single class/defined type that have multiple conditional properties like ‘onlyif’ and/or ‘unless’.</li><br/> <li>You need to use pure Ruby to manipulate data and parse it through a system binary</li><br/> <li>Your defined type has more conditional logic than your pre-nuptual agreement</li><br/> <li>Any combination of similar arguments related to the above</li><br/></ul><br/>If the above sounds familiar to you, then you’re probably ready to build your own custom Puppet type and provider.</p><footer><strong>Gary Larizza in Fun With Puppet Providers</strong></footer></blockquote>
<h2>Let’s get started</h2>
<p>To get started, you first need to include <code>easy_type</code> in your <code>Puppetfile</code> or otherwise get it into your puppet directories. To add it to your <code>Puppetfile</code>, you can add the following line:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">mod</span> <span class="s2">"hajee/easy_type"</span><span class="p">,</span> <span class="ss">:git</span> <span class="o">=></span> <span class="s2">"git://github.com/hajee/easy_type.git"</span>
</span></code></pre></td></tr></table></div></figure>
<p>After that run the librarian to add the right modules to your puppet tree:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>librarian-puppet install
</span></code></pre></td></tr></table></div></figure>
<p>The <code>librarian</code> reads the <code>Puppetfile</code> and puts the nescecary files into your module tree. After this command, you can see <code>easy_type</code> in your list of modules.</p>
<p><img src="http://hajee.github.io/images/easy_type_added.png" title="easy_type added to modules" ></p>
<p>Well that was easy. Now we have all the basic requirements in place to start. What better time then now to think about the resource you want to manage.</p>
<h2>How to manage the resource?</h2>
<p>Because <code>easy_type</code> hides some of the Puppet intricacies from you, you can focus on the resource. To continue, you need to know how:</p>
<ul>
<li>get a list of all available resources?</li>
<li>what’s important in a resource?</li>
<li>to create a resource?</li>
<li>to modify an existing resource</li>
<li>to remove one</li>
</ul>
<p>This is the basic information you need to build a custom resource.</p>
<h1>An example please?</h1>
<p>As an example I’ve picked the same Custom Type as is described in the book <a href="http://shop.oreilly.com/product/0636920026860.do">“Puppet Types and Providers”</a>. This is an excellent book if you are into writing custom resources. It describes in great detail everything you must known and do to build a Custom Type in the standard puppet way. In the book they state:</p>
<blockquote><p>the `custom_package` type is not intended to serve as a replacement of Puppet’s existing package type. It serves as an example of how to take advantage of the features of the type and provider APIs.</p><footer><strong>Puppet Types and Providers By Dan Bode</strong> <cite>Nan Liu</cite></footer></blockquote>
<p>Of course, the same thing counts over here.</p>
<h2>A scaffold</h2>
<p>To get started, it would be helfull if we have a scafffold. Let’s say we want to name our own module <code>my_own_easy_type</code> and we name our own Custom Type <code>custom_package</code>. Let’s start with creating the right directories. Go over to your module directory and create the following directories:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='sh'><span class='line'>mkdir -p my_own_easy_type/lib/puppet/provider/custom_package
</span><span class='line'>mkdir -p my_own_easy_type/lib/puppet/type/custom_package
</span></code></pre></td></tr></table></div></figure>
<p></p>
<p>The first code we need, is the next scaffold:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="nb">require</span> <span class="s1">'easy_type'</span>
</span><span class='line'>
</span><span class='line'><span class="k">module</span> <span class="nn">Puppet</span>
</span><span class='line'>
</span><span class='line'> <span class="n">newtype</span><span class="p">(</span><span class="ss">:custom_package</span><span class="p">)</span> <span class="k">do</span>
</span><span class='line'> <span class="kp">include</span> <span class="no">EasyType</span>
</span><span class='line'>
</span><span class='line'> <span class="c1"># set_command(:the_righ_command)</span>
</span><span class='line'>
</span><span class='line'> <span class="n">to_get_raw_resources</span> <span class="k">do</span>
</span><span class='line'> <span class="c1"># What commando to give to get a list of all resource.</span>
</span><span class='line'> <span class="c1"># We need to return an Array of Hashes </span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'>
</span><span class='line'> <span class="n">on_create</span> <span class="k">do</span>
</span><span class='line'> <span class="c1"># What do we do to create a resource</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'>
</span><span class='line'> <span class="n">on_modify</span> <span class="k">do</span>
</span><span class='line'> <span class="c1"># What do we do to modify an existingresource</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'>
</span><span class='line'> <span class="n">on_destroy</span> <span class="k">do</span>
</span><span class='line'> <span class="c1"># What do we do to destroy/delete an existingresource</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'>
</span><span class='line'> <span class="n">newparam</span><span class="p">(</span><span class="ss">:name</span><span class="p">)</span> <span class="k">do</span>
</span><span class='line'> <span class="kp">include</span> <span class="no">EasyType</span>
</span><span class='line'> <span class="n">isnamevar</span>
</span><span class='line'>
</span><span class='line'> <span class="n">to_translate_to_resource</span> <span class="k">do</span> <span class="o">|</span> <span class="n">raw_resource</span><span class="o">|</span>
</span><span class='line'> <span class="c1"># how to translate from the Hash-like raw resource to get the name</span>
</span><span class='line'> <span class="c1"># raw_resource.column_data(:name)</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>
<p>Let’s put it in <code>my_own_easy_type/lib/puppet/type/custom_package.rb</code>. The next file we need is the provider file.</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>