SaltStack HTTP模块开发指南

原文链接: https://docs.saltstack.com/en/latest/topics/tutorials/http.html

本教程演示了Salt中可用的各种HTTP模块。 这些模块包装Python tornadourllib2requests库,使用与Salt工作流更一致的方式扩展它们。

您也可以参考在Github上维护的这一份技术资料:HTTP Modules

The salt.utils.http Library

该库构成了HTTP模块的核心。 由于它被设计为在minion上用作执行模块,除了可以作为master的runner之外,还被抽象到该多用途库中。 希望利用其扩展功能的第三方程序也可以导入该库。

执行、状态和运行程序模块的核心功能是从该库派生的,因此此处介绍了它们之间的常见用法。 每个模块的特定文档如下所述。

该库可以通过以下方式导入:

import salt.utils.http

Configuring Libraries - 基础类库配置

该库可以使用Salt所需的tornado,Python附带的urllib2或可以单独安装的requests。 默认情况下,将使用tornado。 为了切换到urllib2,需设置以下变量:

backend: urllib2

切换为使用 requests, 则需要设置以下变量:

backend: requests

可以在master配置文件或minion配置文件中进行设置,也可以将其作为选项直接传递给任何http.query()函数。

salt.utils.http.query()

该函数构成一个基本查询,但是有些组件在tornado、urllib2和requests库中不存在。 尚未添加这些库中当前可用的所有功能,但可以在将来的迭代中添加。

扫描二维码关注公众号,回复: 7627624 查看本文章
HTTPS Request Methods

可以通过一个URL调用此函数来执行基本查询:

salt.utils.http.query('http://example.com')

默认情况下,查询将使用GET方法执行。 可以使用method参数覆盖该方法:

salt.utils.http.query('http://example.com/delete/url', 'DELETE')

使用POST方法(以及其他方法,例如PUT)时,通常也会发送额外的数据。 该数据可以直接发送(必要时将进行URL编码),或以远程服务器要求的任何格式(XML,JSON,纯文本等)发送。

salt.utils.http.query(
    'http://example.com/post/url',
    method='POST',
    data=json.dumps(mydict)
)
Data Formatting and Templating - 数据格式化与使用模板

请记住,数据必须预先格式化后再发送; 此功能函数不会为您格式化。 但是,可以将存储在本地系统上的模板化文件以及变量进行传递。

仅传递数据文件(非模板):

salt.utils.http.query(
    'http://example.com/post/url',
    method='POST',
    data_file='/srv/salt/somefile.xml'
)

传递一个包含了 jinja + yaml 模板配置的数据文件 (这也是函数的默认设置):

salt.utils.http.query(
    'http://example.com/post/url',
    method='POST',
    data_file='/srv/salt/somefile.jinja',
    data_render=True,
    template_dict={'key1': 'value1', 'key2': 'value2'}
)

传递一个包含 mako 模板配置的数据文件:

salt.utils.http.query(
    'http://example.com/post/url',
    method='POST',
    data_file='/srv/salt/somefile.mako',
    data_render=True,
    data_renderer='mako',
    template_dict={'key1': 'value1', 'key2': 'value2'}
)

由于此功能使用Salt自己的渲染系统,因此可以使用任何Salt渲染器。 因为Salt的渲染器需要设置__opts__,所以应该传入opts字典。如果未设置,则将使用节点类型(master节点或minion节点)的默认__opts__值。 由于此库主要供minions使用,因此默认节点类型为minion。 但是,如有必要,可以将其更改为master

salt.utils.http.query(
    'http://example.com/post/url',
    method='POST',
    data_file='/srv/salt/somefile.jinja',
    data_render=True,
    template_dict={'key1': 'value1', 'key2': 'value2'},
    opts=__opts__
)

salt.utils.http.query(
    'http://example.com/post/url',
    method='POST',
    data_file='/srv/salt/somefile.jinja',
    data_render=True,
    template_dict={'key1': 'value1', 'key2': 'value2'},
    node='master'
)
Headers

Headers也可以作为header_listheader_dictheader_file传递。 与data_file一样,header_file也可以被模板化。 请注意,由于HTTP headers通常是语法正确的YAML,因此它们会自动作为Python字典导入。

salt.utils.http.query(
    'http://example.com/delete/url',
    method='POST',
    header_file='/srv/salt/headers.jinja',
    header_render=True,
    header_renderer='jinja',
    template_dict={'key1': 'value1', 'key2': 'value2'}
)

因为要在headers和数据之间模板化的许多数据可能是相同的,所以两者的template_dict是相同的。 纠正可能的变量名冲突由用户自行负责。

Authentication

query()函数支持基本的HTTP身份验证。 用户名和密码可以分别作为usernamepassword传递。

salt.utils.http.query(
    'http://example.com',
    username='larry',
    password=`5700g3543v4r`,
)
Cookies and Sessions

使用Python的内置cookielib也支持使用cookie。 但是,它们默认情况下处于关闭状态。 要打开cookie,请将cookie设置为True

salt.utils.http.query(
    'http://example.com',
    cookies=True
)

默认情况下,cookies作为名为cookies.txt的文件存储在Salt的缓存目录中,通常为/var/cache/salt。 但是,可以使用cookie_jar参数更改此位置:

salt.utils.http.query(
    'http://example.com',
    cookies=True,
    cookie_jar='/path/to/cookie_jar.txt'
)

默认情况下,cookie jar的格式为LWP(aka,lib-www-perl)。 选择该默认值是因为它是易于直接阅读的文本文件。 如果需要,可以将cookie jar的格式设置为Mozilla:

salt.utils.http.query(
    'http://example.com',
    cookies=True,
    cookie_jar='/path/to/cookie_jar.txt',
    cookie_format='mozilla'
)

因为Salt命令通常是一次性的命令,这些命令通过管道传递连接在一起,所以该库通常不能像普通浏览器那样运行,因为会话cookie会在多个HTTP请求中持续存在。 但是,可以将会话保留在单独的Cookie jar中。 在Salt的缓存目录中,此文件的默认文件名是cookies.session.p。 这也可以更改。

salt.utils.http.query(
    'http://example.com',
    persist_session=True,
    session_cookie_jar='/path/to/jar.p'
)

该文件的格式为msgpack,与Salt的其他大部分内部结构一致。 从历史上看,此文件的扩展名是.p。 当前没有计划使它可配置。

Proxy

如果使用tornado后端(默认值),则将使用__opts__字典中proxy_host、proxy_port、proxy_username、proxy_passwordno_proxy中配置的代理信息。 通常,这些是在minion配置文件中设置的。

proxy_host: proxy.my-domain
proxy_port: 31337
proxy_username: charon
proxy_password: obolus
no_proxy: ['127.0.0.1', 'localhost']
salt.utils.http.query(
    'http://example.com',
    opts=__opts__,
    backend='tornado'
)

Return Data - 返回数据

注意:返回数据的编码设置

如果decode设置为True,则query()将尝试解码返回数据。 decode_type默认为auto。 可以将其设置为特定的编码,例如xml,以覆盖自动检测。

因为Salt的http库被设计为与REST接口一起使用,所以当decode设置为True时,query()将尝试对从远程服务器接收的数据进行解码。 首先,它将检查Content-type header以尝试查找对XML的引用。 如果找不到任何内容,它将查找对JSON的引用。 如果找不到,它将退回到纯文本格式,不会被解码。

使用Python的内置json库将JSON数据转换为字典。 使用salt.utils.xml_util转换XML,该脚本将使用Python的内置XML库来尝试将XML转换为dict。 为了强制进行JSON或XML解码,可以设置decode_type

salt.utils.http.query(
    'http://example.com',
    decode_type='xml'
)

经过数据格式转换后,query()的返回字典将包含一个称为dict的字典。

如果不使用以上这些方法之一转换数据,则可以关闭解码功能。

salt.utils.http.query(
    'http://example.com',
    decode=False
)

如果打开了解码功能,并且找不到对JSON或XML的引用,则此模块将默认为使用纯文本,并以文本形式返回未解码的数据(即使将text设置为False,请参见下文)。

query()函数可以根据需要返回HTTP状态代码,headers和/或文本数据。 但是,需要每个功能控制项都必须单独打开。

salt.utils.http.query(
    'http://example.com',
    status=True,
    headers=True,
    text=True
)

这些返回的内容将在返回字典中分别以status, headerstext的形式显示。

WRITING RETURN DATA TO FILES - 将返回数据写入文件

一旦从服务器接收到响应,就可以将返回数据或headers写入文件,可以通过text_outheaders_out参数指定文件位置。 文本数据和headrs无需再返回给用户,直接写入指定的文件即可。

salt.utils.http.query(
    'http://example.com',
    text=False,
    headers=False,
    text_out='/path/to/url_download.txt',
    headers_out='/path/to/headers_download.txt',
)

SSL Verification

默认情况下,此功能将验证SSL证书。 但是,出于测试或调试目的,可以关闭SSL验证。

salt.utils.http.query(
    'https://example.com',
    verify_ssl=False,
)

CA Bundles

requests库具有自己的检测使用哪个CA(证书颁发机构)捆绑证书文件的方法。 通常,这是由打包程序针对您正在使用的特定操作系统发行版实现的。 但是,urllib2需要做更多的工作。 默认情况下,Salt将尝试自动检测此文件的位置。 但是,如果它不在预期的位置,或者需要指定其他路径,则可以使用ca_bundle变量来完成。

salt.utils.http.query(
    'https://example.com',
    ca_bundle='/path/to/ca_bundle.pem',
)

Updating CA Bundles

update_ca_bundle()函数可用于在指定位置更新证书捆绑文件。 如果未指定目标位置,则它将尝试自动检测捆绑文件的位置。 如果不存在用于下载捆绑软件的URL,则将从cURL网站下载捆绑软件。

注意:应始终指定target和source! 未指定目标可能会导致文件写入本地系统上的错误位置。 不指定来源可能会导致上游URL接收到多余的不必要流量,并可能导致危险或不满足用户需求的文件下载。

salt.utils.http.update_ca_bundle(
    target='/path/to/ca-bundle.crt',
    source='https://example.com/path/to/ca-bundle.crt',
    opts=__opts__,
)

还应该始终指定opts参数。 如果是,则还有一种替代方法是targetsource可以在相关的配置文件(master服务器或minion服务器)中分别指定为ca_bundleca_bundle_url

ca_bundle: /path/to/ca-bundle.crt
ca_bundle_url: https://example.com/path/to/ca-bundle.crt

如果Salt无法自动检测CA证书捆绑包的位置,则会引发错误。

还可以向update_ca_bundle()函数传递表示本地系统上文件的字符串或字符串列表,这些字符串或字符串列表应(按指定顺序)附加到CA bundle文件的末尾。 这在需要提供私有证书的环境中很有用,并且在其他情况下将其添加到捆绑文件中是不合理的。

salt.utils.http.update_ca_bundle(
    opts=__opts__,
    merge_files=[
        '/etc/ssl/private_cert_1.pem',
        '/etc/ssl/private_cert_2.pem',
        '/etc/ssl/private_cert_3.pem',
    ]
)

Test Mode

此功能可以在测试模式下运行。此模式将执行所有工作,直到实际的HTTP请求为止。默认情况下,不执行请求,而是返回空dict。在TRACE日志记录已打开的情况下使用此功能将显示标头的内容和要发送的POST数据。

可能会传入一个替代的test_url,而不是返回一个空的dict。如果检测到此错误,则测试模式将用test_url替换该url,在返回数据中将test设置为True,并照常执行其余请求的操作。这允许在必要时使用自定义的非破坏性URL进行测试。

EXECUTION MODULE - 执行模块

http执行模块是salt.utils.http库的一个非常轻的包装。 opt也可以传递使用,但如果未指定,则将在必要时使用默认选项。

因为从命令行传递完整的数据结构是比较棘手的,而在发生执行注入攻击方面也很危险,所以data_fileheader_file在这里可能会得到更多使用。

该库的所有方法在执行模块中都可用,如kwargs。

salt myminion http.query http://example.com/restapi method=POST \
    username='larry' password='5700g3543v4r' headers=True text=True \
    status=True decode_type=xml data_render=True \
    header_file=/tmp/headers.txt data_file=/tmp/data.txt \
    header_render=True cookies=True persist_session=True

Runner Module - 运行器模块

类似于执行模块,http runner程序模块也是salt.utils.http库的一个非常轻的包装。 唯一的显著差异是,因为runners是在master服务器上执行而不是在minions上执行,所以不需要目标参数,并且默认选项将从master配置而不是从Minion配置中派生。

该库的所有方法都可以在runner程序模块中使用,如kwargs。

salt-run http.query http://example.com/restapi method=POST \
    username='larry' password='5700g3543v4r' headers=True text=True \
    status=True decode_type=xml data_render=True \
    header_file=/tmp/headers.txt data_file=/tmp/data.txt \
    header_render=True cookies=True persist_session=True

State Module - 状态模块

http 状态模块是runner程序模块的一个包装器,该模块将状态逻辑应用于查询。 上面列出的所有kwargs通常是在状态文件中指定,但是还有两个kwargs可用于应用有状态逻辑。 必需的参数是match,该参数指定要在返回文本中匹配查找的模式。 默认情况下,这将执行字符串比较,以在返回文本中符合匹配查找match的值。 用Python 伪代码描述时看起来像这样:

if match in html_text:
    return True

如果需要更复杂的模式匹配,则可以通过指定match_type来使用正则表达式。 默认情况下,它设置为string,但是可以手动将其设置为pcre。 请注意,尽管名称相似,但它仍将使用Python的re.search()而不是re.match()

因此,以下状态是有效的:

http://example.com/restapi:
  http.query:
    - match: 'SUCCESS'
    - username: 'larry'
    - password: '5700g3543v4r'
    - data_render: True
    - header_file: /tmp/headers.txt
    - data_file: /tmp/data.txt
    - header_render: True
    - cookies: True
    - persist_session: True

http://example.com/restapi:
  http.query:
    - match_type: pcre
    - match: '(?i)succe[ss|ed]'
    - username: 'larry'
    - password: '5700g3543v4r'
    - data_render: True
    - header_file: /tmp/headers.txt
    - data_file: /tmp/data.txt
    - header_render: True
    - cookies: True
    - persist_session: True

除匹配模式外,还可以使用其它代替匹配模式,如检查URL的状态码。 这是使用status参数完成的:

http://example.com/:
  http.query:
    - status: '200'

如果同时指定了两者,则将同时检查两者,但是如果只有一个值为True,另一个为False,则将返回False。 在这种情况下,返回数据中的注释将包含故障排除信息。

因为这是一个服务监视的状态定义,所以它将额外的数据返回到期望它的代码中。 此数据将始终包含textstatus。 可选地,还可以通过分别将headersdecode参数设置为True来请求headersdict

猜你喜欢

转载自blog.csdn.net/watermelonbig/article/details/102760427
今日推荐