puppet(4)-类、模版语言、模块

puppet(4)-类、模版语言、模块

代码重用: class, module

  • 类的简单说明
    类是用于公共目的的一组资源,是命名的代码块,建立后可在puppet全局进行调用,类能够继承类是咱们构建模块的基本组件node

    类:命名的puppet代码块,好处就是能够重复调用,须要时可经过名称进行调用;
          class my_class {
              ...puppet code...
          }
          puppet code: 包含变量赋值、各类条件判断语句、资源声明等等;
          注意: 类的名字只能以小写字母开头
          调用类:
              include class1, class2, ...
              class {'classname': }
  • 类的写法linux

    写法举例一:nginx

    class apache{
          package{'httpd':
              ensure => installed,
          }
          file{'httpd.conf':
              path => '/etc/httpd/conf/httpd.conf',
              ensure => file,
              require => Package['httpd'],
          }
          service{'httpd':
              ensure => running,
              require => Package['httpd'],
              subsribe => File['httpd.conf'],
          }
    
      }

    写法举例二:web

    class nginx{
          $webserver='nginx'
          package{$webserver:
              ensure => latest,
          }
          file{"/etc/$webserver/nginx.conf":
              ensure => file,
              source => "/opt/puppet/modules/$webserver/files/nginx.conf",
              require => Package[$webserver],
              # notify => Service['nginx'],
          }
          service{$webserver:
              ensure => running,
              enable => true,
              hasstatus => true,
              hasrestart => true,
              # restart => 'systemctl reload nginx.service',
              require => [ Package[$webserver], File["/etc/$webserver/nginx.conf"]],
              subscribe => File["/etc/$webserver/nginx.conf"],
          }
      }
      class {'nginx':
    
      }
  • 类的声明apache

    有四种方法:编程

    1.使用include
      2.使用require
      3.像声明一个资源同样声明类
      4.使用ENC的风格来声明一个类

    1&3是最经常使用的数组

    第一种:include base::linux,apache 能够用逗号隔开声明多个类
    include nginx
    第二种: require apache这种方式不多用
    第三种:ruby

    class {'nginx':
              version => '2.2.21'
          }

    能够传入参数,因此很经常使用服务器

    注意:
    类只有在声明后方才执行
    每一个类都会引入一个新的变量scope(做用域),这意味着在任什么时候候访问类的变量时,都得使用其彻底限定名称,不过,在本地scope能够从新为top scope中的变量赋于一个新值函数

  • 定义带参数的类:

    class my_class ($para1=value1, $para2=value2) {
              ...puppet code...
          }

    调用时,传递参数:

    class {'class_name':
              para1   =>  new_value1,
              para2   =>  new_value2,
          }

    写法举例一:

    class createuser ($grpname=testgrp,$username=testuser) {
                  group{"$grpname":
                          ensure  => present,
                  }
    
                  user{"$username":
                          ensure  => present,
                          gid     => $grpname,
                  }
          }
    
          class {'createuser':
                  grpname => mageedu,
                  username => mageedu,
          }

    写法举例二:

    class nginx ($webserver='nginx'){
              package{$webserver:
                  ensure => latest,
              }
              file{"/etc/$webserver/nginx.conf":
                  ensure => file,
                  source => "/opt/puppet/modules/$webserver/files/nginx.conf",
                  require => Package[$webserver],
                  # notify => Service['nginx'],
              }
              service{$webserver:
                  ensure => running,
                  enable => true,
                  hasstatus => true,
                  hasrestart => true,
                  # restart => 'systemctl reload nginx.service',
                  require => [ Package[$webserver], File["/etc/$webserver/nginx.conf"]],
                  subscribe => File["/etc/$webserver/nginx.conf"],
              }
          }
          class {'nginx':
              $webserver = ‘nginx’,
          }
  • 类的继承:
    定义方式:

    class base_class_name {
              ... puppet code ...
          }
          class base_class_name::class_name inherits base_class_name {
              ...puppet code...
          }

    base_class_name::class_name 这是继承类命名的一种规范,让你一眼就知道这是继承某个类的子类(它只是一个名字,没有任何做用,不这样写你会觉得它没有继承其余类,这种命名方式叫作彻底限定名称)

    inherits base_class_name 表示继承哪一个类

    类的继承这种写法的做用:继承一个已有的类,并实现覆盖资源属性,或向资源属性追加额外值
    好比说我以前定义了一个类,这个类就定义了一个package资源-安装了nginx, 而后我如今又想定义一个类 有修改配置文件和 启动服务的资源,这时候就能够继承类。

    (1) 继承资源属性;
              (2) 覆盖资源属性;
                  =>
              (3) 追加资源属性;
                  +>

    类在实现继承时有几个要点:

    (1) 声明子类时,其基类会被首先声明;
              (2) 基类成为子类的父做用域,由于基类变量和属性默认值会被子类直接复制一份
              (3) 子类能够覆盖父类中同一资源的相同属性值

    继承类的实例:

    class nginx {
              package {'nginx':
                  ensure => latest,
              } ->
              service {'nginx':
                  enable => true,
                  ensure => running,
                  hasrestart => true,
                  hasstatus => true,
                  restart => 'service nginx reload'
    
              }
          }
    
          class nginx::webserver inherits nginx {
              file{'/etc/nginx/nginx.conf':
                  source => '/opt/puppet/modules/nginx/files/nginx_web.conf'
                  ensure => file,
                  notify => Service['nginx'],
              }
          }
    
          class nginx::haproxy inherits nginx {
              file{'/etc/nginx/nginx.conf':
                  source => '/opt/puppet/modules/nginx/files/nginx_proxy.conf'
                  ensure => file,
                  notify => Service['nginx'],
              }
          }

    以上puppet code 定义了一个基类实现程序包的安装,此外咱们额外定义了两个子类,分别实现 webserver 和 proxy功能。

    可是一台机器上怎么声明呢?一个节点不能带两种角色,何时用呢?
    未来咱们作master/agent模型,两个node ,第一个node include nginx::webserver这个类,另一个node include nginx::haproxy

    能够引用测试:
      include nginx::webserver

    高级继承:
    继承后子类改父类资源中属性的值:

    class nginx {
              package {'nginx':
                  ensure => latest,
              } ->
              service {'nginx':
                  enable => true,
                  ensure => running,
                  hasrestart => true,
                  hasstatus => true,
                  restart => 'service nginx reload'
    
              }
          }
    
          class nginx::webserver inherits nginx {
              Package['nginx']{   ##这里是资源引用 大写['tittle']
                  name => 'tengine',
              }
              file{'/etc/nginx/nginx.conf':
                  source => '/opt/puppet/modules/nginx/files/nginx_web.conf'
                  ensure => file,
                  notify => Service['nginx'],
              }
          }
    
          class nginx::haproxy inherits nginx {
              file{'/etc/nginx/nginx.conf':
                  source => '/opt/puppet/modules/nginx/files/nginx_proxy.conf'
                  ensure => file,
                  notify => Service['nginx'],
              }
          }
      重新定义父资源中的属性时要使用资源引用 即
          Package['nginx']{
              name => 'tengine',
          }
      在子类总不只能够修改属性,还能够加 好比:
          Package['nginx']{
              name +> 'varnish',
          }

    有了类咱们就能够组织模块了,不过为了让模块功能更增强大,咱们能够在puppet中使用模版,那么咱们就要学习puppet的模版语言。

模版

  • 模版语言是什么
    学习模版语言以前咱们先想下,模版语言有什么做用?
    举个例子,前面咱们 定义了nginx类,类中定义了package资源,file资源,service资源。 其中file资源定义的是 nginx的配置文件,配置文件里有一个配置项须要根据服务器的cpu个数来配置运行nginx可使用的cpu数。如何灵活的根据服务器cpu的个数来配置nginx中的这一项参数呢?能够拷贝多个配置文件定义不一样的值,而后再定义不一样的子类,子类在从新定义file资源中的source属性,而后不一样的节点定义声明不一样的子类,这种方式实现起来很繁琐,因此咱们能够想象有这么一种方式,在nginx.conf文件中定义一个变量,变量的值就是取服务器的cpu个数,那么静态文件中定义变量,用什么来解释呢。在puppet中固然就由puppet来解释,而这种在静态文件中定义变量以及写逻辑判断的作法就叫作模版语言。因此我以为模版语言 其实就是针对file资源使用的语言。puppet是ruby语言开发的,因此puppet 模版文件中嵌套的语言也是ruby语言。

  • puppet模板语言的写法
    模版:基于ERB嵌入式的ruby模版语言,他表示在静态文件中使用变量等编程元素生成适用于多种环境的文本文件(配置文件)。Embedded Ruby简称ERB,它主要用于实如今文本文件嵌入ruby代码。原来的文本信息不回被改变,可是ruby代码会执行。执行的结果将直接替换原来的代码处:
    基本语法:

    <%= Ruby Expression %>: 替换为表达式的值;
          <% Ruby Expression %>: 仅执行代码,而不替换。
          <%# comment %>: 文本注视
          <%% 表示转义符 输出为<%这个符号,通常用不到
          %%>  输出为 %> ,用不到
          <%- Ruby code %>, 忽略空白字符
          <% Ruby code -%> ,忽略空白行。

    可以用到的只有第一种
    模版语言中可使用puppet中的任意可用变量,可是变量名要以@符号开头。
    在模版中还可使用循环 ,条件判断等各类复杂语法格式。
    条件判断:

    <% if condition -%>
                  some text
              <% else %>
                  some other text
              <% end %>

    迭代,像for循环

    <% @ArrayName.echo do | variable_name %>
                  some text with <%- variable_name %>
              <% end %>

    这里ArrayName是 puppet的一个数组变量。 variable_name 为赋值给的变量,至关于 for i in list ,list是ArrayName , i是 variable_name
    条件和迭代 不要求会,能看懂别人写的代码就行 了,关键咱们会使用变量就好了。好比上面说到nginx的配置文件问题。

    如何在资源定义中引用模版?

    首先咱们把file文件的source 改为关于启动进程的部分改为以下:

    user nginx;
          worker_processes <%= @processorcount %>;
          error_log /var/log/nginx/error.log;
          pid /run/nginx.pid;

    对于这种含有模版语言的文件,咱们应用到file资源属性要改变一下用法了,不能用source 属性,改用 content属性以及 puppet内置的模版函数template() ,具体以下:

    class nginx {
              package {'nginx':
                  ensure => latest,
              } ->
              service {'nginx':
                  enable => true,
                  ensure => running,
                  hasrestart => true,
                  hasstatus => true,
                  restart => 'service nginx reload'
    
              }
          }
    
          class nginx::webserver inherits nginx {
              Package['nginx']{
                  name => 'tengine',
              }
              file{'/etc/nginx/nginx.conf':
                  source => '/opt/puppet/modules/nginx/files/nginx_web.conf',
                  ensure => file,
                  notify => Service['nginx'],
              }
          }
    
          class nginx::haproxy inherits nginx {
              file{'/etc/nginx/nginx.conf':
                  #source => '/opt/puppet/modules/nginx/files/nginx_proxy.conf'
                  content => template('/opt/puppet/modules/nginx/files/nginx_proxy.conf'),
                  ensure => file,
                  notify => Service['nginx'],
              }
          }
          include  nginx::haproxy

    以上就是模版语言,以及模版语言是如何调用的。

modules

  • 什么是modules
    puppet模块:为了实现某种完备功能而组织成的一个独立的、自我包含的目录结构

  • puppet中模块的目录结构

    模块名:目录名

    目录结构:

    modules/
          module_name/:
              manifests/
                  init.pp: 必须声明一个类,类名与模块名相同;
                  *.pp:
                      MODULE_NAME::[SUBDIR_NAME]::MANIFESTS_FILE_NAME
              files/:
                  静态文件
                      puppet url:
                          puppet:///modules/MODULE_NAME/[SUBDIR_NAME]/FILE_NAME
    
                  file{'nginx.conf':
                      source  => puppet:///modules/nginx/nginx.conf
                  }
              templates/:
                  模板文件:*.erb
                      template('MODULE_NAME/TEMPLATE_FILE_NAME');
    
    
                      file{'nginx.conf':
                          content     => template('模板文件'),
                      }
    
              lib/: 插件
              tests/: 模块使用说明文档,以及事例example
              spec/: lib目录下的插件使用说明文档
  • puppet 模块相关的命令

    puppet model <action>命令
          ACTIONS:
            build        Build a module release package.
            changes      Show modified files of an installed module.
            generate     Generate boilerplate for a new module.
            install      Install a module from the Puppet Forge or a release archive.
            list         List installed modules
            search       Search the Puppet Forge for a module.
            uninstall    Uninstall a puppet module.
            upgrade      Upgrade a puppet module.
相关文章
相关标签/搜索