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

代码重用: class, module

  • 类的简单说明

    类是用于公共目的的一组资源,是命名的代码块,创建后可在puppet全局进行调用,类可以继承类是我们构建模块的基本组件

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

    写法举例一:

      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'],
    } }

    写法举例二:

      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': }
  • 类的声明

    有四种方法:

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

    1&3是最常用的

    第一种:include base::linux,apache 可以用逗号隔开声明多个类

    include nginx

    第二种: require apache这种方式很少用

    第三种:

      	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.

puppet(4)-类、模版语言、模块的更多相关文章

  1. SODBASE CEP学习(四)续:类SQL语言EPL与Storm或jStorm集成-使用分布式缓存

    流式计算在一些情况下会用到分布式缓存,从而实现(1)想把统计或计算结果保存在分布缓存中.供其他模块或其他系统调用. (2)某一滑动时间窗体上计数.比如实时统计1小时每一个Cookie的訪问量.实时统计 ...

  2. Django 模版语言

    传入变量 {{ 变量名 }} 在 view.py 的函数返回 render 时在html文件名后传入一个字典,字典的 key 对应html文件中的变量名,value 为传入的值 views.py: d ...

  3. django -- 模版语言之过滤器Filters和for循环

    前戏 在前面写的图书管理系统中,我们对模版语言应该已经不陌生了,使用{{ }}包裹起来的就是模版语言,只需要记住两种就可以了 {{ 变量名 }}            变量相关的 {% %}      ...

  4. Django模版语言 格式化显示 后台datatime()时间

    Django模版语言 格式化显示 后台datatime()时间 场景描述:

  5. c++ 类模版、成员函数模版、函数模版 用法

    C++函数模版与类模版. template <class T> void SwapFunction(T &first, T &second){ }//函数模版 templa ...

  6. Jinja2模版语言自定义filter的使用

    Jinja2模版语言,自带有一些filter,能够在前端的模版中控制数据按照相应的方式显示.比如以下两种filter,分别能在前端控制数字的近似精度显示和根据字符串长度补齐: round(value, ...

  7. Django模版语言的复用 1. include标签--模版导入 2.inclusion_tag自定义标签--模版导入 3.母版

    include标签--模版导入 ''' 前提:项目中,往往会出现多个页面拥有一个或几个相同的页面版块,或是一个页面多个页面版块是相同的 如何运用:可以将多个样式标签的集合进行封装,对外提供版块的名字( ...

  8. django -- url (模版语言 {% url 'test1' param1=5 param2=6 %})

    如果想让form表单提交的url是类似 action="/index-5-6.html" 这样的,可以在html模版语言中使用{% url 'test1' param1=5 par ...

  9. django -- url (模版语言{{ request.path_info }})

    在django的模版语言中中可以使用   {{ request.path_info }} 帮助生成url. urls.py from django.conf.urls import url, incl ...

随机推荐

  1. Centos 6 安装 Mysql 5.6

    参考:http://www.runoob.com/mysql/mysql-database-import.html 数据库 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库, 每个 ...

  2. 通过echarts的demo

    通过最近两天对echarts的了解,下面用echarts.js写了一个小效果: 效果的demo为: <!DOCTYPE html> <html lang="en" ...

  3. Vue相关开源项目库汇总(史上最全)

    偶尔在网上看到的,先保存着,以备不时之需 https://www.jianshu.com/p/e37f4dde49a2 better-scroll:是一款重点解决移动端(未来可能会考虑 PC 端)各种 ...

  4. HTML5 学习05—— 拖放(Drag 和 Drop)

    拖放(Drag 和 drop)是 HTML5 标准的组成部分.即抓取对象以后拖到另一个位置. 例:将w3cschool图标拖动到矩形框中. <script> function allowD ...

  5. python测试开发django-52.xadmin添加自定义的javascript(get_media)

    前言 我想使用xadmin在列表页每一行元素添加一个按钮,当点击这个按钮的时候,能发个请求出去,后台执行相关功能.于是想到添加自定义的javascript脚本能实现. 在/stackoverflow上 ...

  6. Android的Databinding-资源绑定

    databinding还能对布局的资源文件进行绑定. <data class="ResourceBinding"> <variable name="la ...

  7. java 使用CXF将wsdl文件生成客户端代码命令java调用第三方的webservice应用实例

    1.先下载cxf包https://download.csdn.net/download/suizhikuo/108112362.解压缩包,通过cmd命令进入到bin目录下(cd cxf\bin的路径) ...

  8. C# CountdownEvent实现

    关于CountdownEvent网上的介绍比较少,因为它是实现和使用都很简单,先看看网上的一些评论吧: CountDownEvent调用成员函数Wait()将阻塞,直至成员函数Signal() 被调用 ...

  9. 简单几步即可判断Linux系统有无被DDOS攻击的方法

    一般来说,服务器非常慢可能原因是多方面的,有可能是配置错误,脚本错误或者是一些奇诡的硬件.当然也有可能是有人对你的服务器进行 Dos (拒绝服务攻击)或者 DDOS (分布式拒绝服务攻击). Dos攻 ...

  10. mysql5 数据库连接丢失问题,autoReconnect=true不起作用

    The last packet successfully received from the server was 55,404,563 millise 方案1 定时器 方案2 修改连接池容量 mys ...