第 4 章 Red Hat Satellite API 入门


本章提供了如何使用 Red Hat Satellite API 执行不同任务的示例。这些示例侧重于将 HTTPS 用于端口 443 的 Satellite 服务器。您还可以通过 Satellite Capsule 访问 API,但您需要使用端口 8443 或 API 调用会失败。
您可以在脚本本身中满足这些不同的端口要求。例如,在 Ruby 中,您可以指定 Satellite 和 Capsule URL,如下所示:
url = 'https://satellite6.example.com/api/v2/'
capsule_url = 'https://capsule.example.com:8443/api/v2/'
katello_url = 'https://satellite6.example.com/katello/api/v2/'
Copy to Clipboard Toggle word wrap
如果主机订阅了 Satellite 服务器或 Capsule 服务器,您可以在 [server] 部分的 port 条目中确定从 /etc/rhsm/rhsm.conf 文件访问 API 所需的正确端口。您可以使用这些值来完全自动化脚本,无需验证要使用的端口。

4.1. 使用 Curl 的 API 示例

本节论述了如何使用 curl 使用 Satellite API 执行各种任务。

4.1.1. 执行简单查询

以下示例演示了如何使用 curl 搜索 Satellite 部署的信息。这些示例包括实际命令和一些示例输出,以及用户名和密码的示例值。每个部署都有不同的结果。这些示例也使用 python -m json.tool 命令格式化输出。
注意
Red Hat Satellite 需要使用 HTTPS,默认是主机识别的证书。如果您还没有添加 Satellite 服务器证书,如 第 3.1 节 “使用 SSL 身份验证” 所述,您可以使用 -k (不安全)选项绕过证书检查。
对于用户身份验证,您可以使用表单 -u 用户名:password 或者如果没有包含密码,命令会提示您输入它。红帽建议不要将密码包含在命令中,因为它会成为 shell 历史记录的一部分,并可能会存在安全风险。这些示例仅包含简单性的密码。
请注意,如果您在 curl 中使用 the -s (silent)选项,则不会看到进度计量或任何错误消息。

检索资源列表

以下是返回资源列表的基本查询。此类请求返回嵌套在元数据中的数据列表,而其他请求类型则仅返回实际对象。

$ curl -X GET -s -k -u sat_username:sat_password https://satellite6.example.com/api/v2/hosts | python -m json.tool

{
       "total" => 2,
    "subtotal" => 2,
        "page" => 1,
    "per_page" => 1000,
      "search" => nil,
        "sort" => {
           "by" => nil,
        "order" => nil
    },
     "results" => [
      ...
}
Copy to Clipboard Toggle word wrap

例 4.1. 列出用户

$ curl -X GET -s -k -u sat_username:sat_password https://satellite6.example.com/api/users
{
  "total": 1,
  "subtotal": 1,
  "page": 1,
  "per_page": 20,
  "search": null,
  "sort": {
    "by": null,
    "order": null
  },
  "results": [{"firstname":"Admin","lastname":"User","mail":"root@example.com","admin":true,"auth_source_id":1,"auth_source_name":"Internal","timezone":null,"locale":null,"last_login_on":"2017-02-08 23:25:51 UTC","created_at":"2017-01-09 12:10:02 UTC","updated_at":"2017-02-08 23:25:51 UTC","id":3,"login":"admin","default_location":null,"locations":[],"default_organization":{"id":1,"name":"Default Organization","title":"Default Organization","description":null},"organizations":[]}]
}
Copy to Clipboard Toggle word wrap

运行通用主机查询

以下查询返回主机 satellite6.example.com 的信息:

$  curl -X GET -s -k -u sat_username:sat_password https://satellite6.example.com/api/v2/hosts/satellite6.example.com | python -m json.tool
{
    "all_puppetclasses": [],
    "architecture_id": 1,
    "architecture_name": "x86_64",
    "build": false,
    "capabilities": [
        "build"
    ],
    "certname": "satellite6.example.com",
    "comment": null,
    "compute_profile_id": null,
    ...
}
Copy to Clipboard Toggle word wrap

为特定主机搜索事实

以下查询返回主机 satellite6.example.com 的所有事实:

$ curl -X GET -s -k -u sat_username:sat_password https://satellite6.example.com/api/v2/hosts/satellite6.example.com/facts | python -m json.tool
{
...
    "results": {
        "satellite6.example.com": {
            "augeasversion": "1.0.0",
            "bios_release_date": "01/01/2007",
            "bios_version": "0.5.1",
            "blockdevice_sr0_size": "1073741312",
            "facterversion": "1.7.6",
            ...
}
Copy to Clipboard Toggle word wrap

搜索所有主机匹配模式

以下查询返回与模式 "example" 匹配的所有主机:

$ curl -X GET -s -k -u sat_username:sat_password https://satellite6.example.com/api/v2/hosts?search=example | python -m json.tool
{
    ...
    "results": [
        {
            "name": "satellite6.example.com",
            ...
        }
    ],
    "search": "example",
    ...
}
Copy to Clipboard Toggle word wrap

搜索特定环境中的所有主机

以下查询返回 "production" 环境中的所有主机:

$ curl -X GET -s -k -u sat_username:sat_password https://satellite6.example.com/api/v2/hosts?search=environment=production | python -m json.tool
{
    ...
    "results": [
        {
            "environment_name": "production",
            "name": "satellite6.example.com",
            ...
        }
    ],
    "search": "environment=production",
    ...
}
Copy to Clipboard Toggle word wrap

使用特定事实值搜索所有主机

以下查询返回带有模型名称"RHEV Hypervisor"的所有主机:

$ curl -X GET -s -k -u sat_username:sat_password https://satellite6.example.com/api/v2/hosts?search=model=\"RHEV+Hypervisor\" | python -m json.tool
{
    ...
    "results": [
        {
            "model_id": 1,
            "model_name": "RHEV Hypervisor",
            "name": "satellite6.example.com",
            ...
        }
    ],
    "search": "model=\"RHEV Hypervisor\"",
    ...
}
Copy to Clipboard Toggle word wrap

删除主机

以下查询会删除带有名称 host1.example.com 的主机:

curl -k -u sat_username:sat_password -X DELETE https://satellite6.example.com/api/v2/hosts/host1.example.com
Copy to Clipboard Toggle word wrap

4.1.2. 创建和修改资源

您可以使用 Satellite API 来操作 Satellite 服务器上的资源。这些 API 调用要求您在要查询的简单用户名、密码和 URI 之外传递各种参数。例如,若要将内容上传到 Satellite 服务器,或修改 Satellite 资源,您需要在构建请求时在标头中包含额外信息。
您可以在标头中指定 API 的版本,如以下示例中所述,或作为 URL 的一部分。例如: https://satellite6.example.com/api/v2/architectures 等同于在请求标头中使用 Accept:version=2。URL 规格具有优先权。
以下是 POST 请求的基本语法:
$ curl -H "Accept:application/json,version=2" \
       -H "Content-Type:application/json" -X POST \
       -u username:password -k \
       -d json-formatted-data https://satellite6.example.com
Copy to Clipboard Toggle word wrap
例如,要创建新架构,您可以使用以下示例请求:
$ curl -H "Accept:application/json,version=2" \
       -H "Content-Type:application/json" -X POST -u sat_username:sat_password \
       -k -d "{\"architecture\":{\"name\":\"i686\"}}" \
       https://satellite6.example.com/api/architectures
Copy to Clipboard Toggle word wrap
这会返回类似如下的输出:
{"name":"i686","id":3,"created_at":"2015-10-29T13:21:09Z","updated_at":"2015-10-29T13:21:09Z","operatingsystems":[],"images":[]}
Copy to Clipboard Toggle word wrap
您可以使用以下命令来验证架构是否已创建:
$ curl -X GET -u sat_username:sat_password -k https://satellite6.example.com/api/v2/architectures | python -m json.tool
  {
      "page": 1,
      "per_page": 20,
      "results": [
          {
              "created_at": "2015-04-02T05:29:46Z",
              "id": 2,
              "name": "i386",
              "updated_at": "2015-04-02T05:29:46Z"
          },
          {
              "created_at": "2015-04-02T05:29:46Z",
              "id": 1,
              "name": "x86_64",
              "updated_at": "2015-04-02T05:29:46Z"
          },
          {
              "created_at": "2015-11-04T19:40:15Z",
              "id": 3,
              "name": "i686",
              "updated_at": "2015-11-04T19:40:15Z"
          }
      ],
      "search": null,
      "sort": {
          "by": null,
          "order": null
      },
      "subtotal": 3,
      "total": 3
  }
Copy to Clipboard Toggle word wrap
您还可以使用 Satellite 服务器上的 hammer 来验证结果:
$ hammer -u sat_username -p sat_password architecture list
---|-------
ID | NAME
---|-------
2  | i386
1  | x86_64
3  | i686
---|-------
Copy to Clipboard Toggle word wrap

例 4.2. 创建新用户

$ curl -H "Accept:application/json,version=2" \
-H "Content-Type:application/json" -X POST \
-u sat_username:sat_password -k \
-d "{\"firstname\":\"Test\",\"lastname\":\"API-User\",\"mail\":\"test@example.com\",\"login\":\"test_api\",\"password\":\"123456\",\"auth_source_id\":1}" \
https://satellite6.example.com/api/users
Copy to Clipboard Toggle word wrap

4.1.2.1. 将内容上传到 Satellite 服务器

本节论述了如何将 curl 与 Satellite 6 API 搭配使用,将大型文件上传到 Satellite 服务器。这个过程涉及四个步骤:
  1. 创建上传请求。
  2. 上传内容。
  3. 导入内容。
  4. 删除上传请求。
您可以上传的最大文件大小大约为 30 MB。要上传更大的内容,请参阅 例 4.3 “上传内容大概超过 30 MB”

过程 4.1. 将内容上传到 Satellite 服务器

  1. 创建上传请求。确保修改示例参数以适合您的部署:
    $ curl -H "Accept:application/json,version=2" \
           -H "Content-Type:application/json" \
           -X POST \
           -u sat_username:sat_password -k -d "{}" \
           https://satellite6.example.com/katello/api/repositories/3/content_uploads
    Copy to Clipboard Toggle word wrap
    这个命令返回类似如下的 upload_id
    {"upload_id":"0be156b1-f373-4cad-89d0-924f8f4491d2","_href":"/pulp/api/v2/content/uploads/0be156b1-f373-4cad-89d0-924f8f4491d2/"}
    Copy to Clipboard Toggle word wrap
  2. 上传您的内容。确保在上传数据时使用正确的 MIME 类型。"application/json" MIME 类型用于大多数对 Satellite 6 的请求。组合 upload_id、MIME 类型和其他参数以上传内容:
    $ curl -H "Accept:application/json,version=2" \
           -H "Content-Type:multipart/form-data" \
           -X PUT \
           -u sat_username:sat_password \
           -k --data-urlencode "content@/home/sat6user/rpmbuild/RPMS/noarch/python-scripttest-1.1.1-1.fc21.noarch.rpm" \
           --data-urlencode offset=0 \
           https://satellite6.example.com/katello/api/repositories/3/content_uploads/0be156b1-f373-4cad-89d0-924f8f4491d2
    Copy to Clipboard Toggle word wrap
  3. 将内容上传到 Satellite 服务器后,您需要将它导入到适当的存储库中。在完成此步骤前,Satellite 服务器不会了解新内容:
    $ curl -H "Accept:application/json,version=2" \
           -H "Content-Type:application/json" \
           -X PUT \
           -u sat_username:sat_password \
           -k -d "{\"upload_ids\":[\"0be156b1-f373-4cad-89d0-924f8f4491d2\"]}" \
           https://satellite6.example.com/katello/api/repositories/3/import_uploads
    Copy to Clipboard Toggle word wrap
  4. 成功上传并导入内容后,您可以删除上传请求。这会释放上传过程中使用的任何临时磁盘空间:
    $ curl -H "Accept:application/json,version=2" \
           -H "Content-Type:application/json" \
           -X DELETE -d "{}" \
           -u sat_username:sat_password \
           -k https://satellite6.example.com/katello/api/repositories/3/content_uploads/0be156b1-f373-4cad-89d0-924f8f4491d2
    Copy to Clipboard Toggle word wrap

例 4.3. 上传内容大概超过 30 MB

以下示例演示了如何将大型文件分成块,创建上传请求,上传单个文件,将它们导入到 Satellite,然后删除上传请求。请注意,本示例使用示例内容、主机名、用户名和文件名。
  1. 下载示例模块:
    $ wget https://forgeapi.puppetlabs.com/v3/files/theforeman-foreman-5.0.1.tar.gz?_ga=1.267255502.1792403825.1430297670 -O theforeman-foreman-5.0.1.tar.gz
    
    Copy to Clipboard Toggle word wrap
    将模块分成 50,000 字节块:
    $ split --bytes 50000 --numeric-suffixes --suffix-length=1 theforeman-foreman-5.0.1.tar.gz foreman_module.
    
    Copy to Clipboard Toggle word wrap
    查看生成的文件:
    $ ls -la theforeman-foreman-5.0.1.tar.gz foreman_module.*
    -rw-r--r--. 1 root root 50000 Nov  4 04:42 foreman_module.0
    -rw-r--r--. 1 root root 32928 Nov  4 04:42 foreman_module.1
    -rw-r--r--. 1 root root 82928 Nov  4 04:41 theforeman-foreman-5.0.1.tar.gz
    Copy to Clipboard Toggle word wrap
  2. 创建新的上传请求(这等同于 Satellite 服务器上的 cat )。
    $ curl -H "Accept:application/json,version=2" \
           -H "Content-Type:application/json" \
           -X POST \
           -u sat_username:sat_password -k -d "{}" \
           https://ibm-vm01.example.com/katello/api/repositories/2/content_uploads
    
    Copy to Clipboard Toggle word wrap
    以上命令返回一个上传 ID:
    {"upload_id":"9585528f-07ad-4bb1-9c80-ccece249b2b7","_href":"/pulp/api/v2/content/uploads/9585528f-07ad-4bb1-9c80-ccece249b2b7/"}
    Copy to Clipboard Toggle word wrap
  3. 上传您在第 1 步中创建的文件块。请注意,在本示例中使用 offset 参数,以及如何与文件大小相关:
    $ curl -H "Accept:application/json,version=2" \
           -H "Content-Type:multipart/form-data" \
           -X PUT \
           -u sat_username:sat_password \
           -k --data-urlencode "content@foreman_module.0" \
           --data-urlencode offset=0 \
           https://ibm-vm01.example.com/katello/api/repositories/2/content_uploads/9585528f-07ad-4bb1-9c80-ccece249b2b7
    
    Copy to Clipboard Toggle word wrap
    $ curl -H "Accept:application/json,version=2" \
           -H "Content-Type:multipart/form-data" \
           -X PUT \
           -u sat_username:sat_password \
           -k --data-urlencode "content@foreman_module.1" \
           --data-urlencode offset=50000 \
           https://ibm-vm01.example.com/katello/api/repositories/2/content_uploads/9585528f-07ad-4bb1-9c80-ccece249b2b7
    Copy to Clipboard Toggle word wrap
  4. 将完整上传到存储库:
    $ curl -H "Accept:application/json,version=2" \
           -H "Content-Type:application/json" \
           -X PUT \
           -u sat_username:sat_password \
           -k -d "{\"upload_ids\":[\"9585528f-07ad-4bb1-9c80-ccece249b2b7\"]}" \
           https://ibm-vm01.example.com/katello/api/repositories/2/import_uploads
    Copy to Clipboard Toggle word wrap
  5. 删除上传请求:
    $ curl -H "Accept:application/json,version=2" \
           -H "Content-Type:application/json" \
           -X DELETE -d "{}" \
           -u sat_username:sat_password \
           -k https://ibm-vm01.example.com/katello/api/repositories/2/content_uploads/9585528f-07ad-4bb1-9c80-ccece249b2b7
    Copy to Clipboard Toggle word wrap
  6. 登录到 Satellite 服务器,检查该文件是否已正确传输:
    $ ls -la /var/lib/pulp/content/puppet_module/theforeman-foreman-5.0.1.tar.gz
    -rw-r--r--. 1 apache apache 82928 Nov  4 04:55 /var/lib/pulp/content/puppet_module/theforeman-foreman-5.0.1.tar.gz
    
    Copy to Clipboard Toggle word wrap
    比较文件:
    $ cmp /var/lib/pulp/content/puppet_module/theforeman-foreman-5.0.1.tar.gz theforeman-foreman-5.0.1.tar.gz
    
    Copy to Clipboard Toggle word wrap
    $ echo $?
    0
    
    Copy to Clipboard Toggle word wrap

4.1.3. 覆盖智能类参数

您可以使用 API 搜索智能参数,并提供值来覆盖类中的智能参数。有关可修改的属性的完整列表,请访问 https://satellite6.example.com/apidoc/v2/smart_class_parameters/update.html 的内置 API 参考。
例如,若要列出所有智能类参数,API 路由显示为 GET /api/smart_class_parameters。使用 curl,命令如下:
$ curl -X GET -s -k -u sat_username:sat_password \
https://satellite6.example.com/api/smart_class_parameters
Copy to Clipboard Toggle word wrap
如果您知道 Puppet 类 ID,如 5,您可以限制范围,如下所示:
$ curl -X GET -s -k -u sat_username:sat_password https://satellite6.example.com/api/puppetclasses/5/smart_class_parameters
Copy to Clipboard Toggle word wrap
这两个调用都接受 search 参数。在搜索输入框中的 Web UI 中可以看到可搜索字段的完整列表。导航到 Configure Smart variables,再单击搜索查询框中以显示字段列表。
两个特别有用的搜索参数是 puppetclass_name,供您搜索特定参数。例如,使用 -d, --data 选项传递 URL 编码数据:
$ curl -X GET -s -k -u sat_username:sat_password https://satellite6.example.com/api/smart_class_parameters -d 'search=puppetclass_name = access_insights_client and key = authmethod'
Copy to Clipboard Toggle word wrap
支持标准 scoped-search 语法。
找到参数的 ID 后,您可以继续列出包括当前覆盖值在内的完整详情。例如,对于 ID 63,API 路由为 GET /api/smart_class_parameters/63。使用 curl,命令将是:
$ curl -X GET -s -k -u sat_username:sat_password \
https://satellite6.example.com/api/smart_class_parameters/63
Copy to Clipboard Toggle word wrap
现在,您可以使用 PUT 调用启用覆盖参数值:
$ curl -H "Accept:application/json,version=2" \
-H "Content-Type:application/json" -X PUT \
-s -k -u sat_username:sat_password \
-d '{"smart_class_parameter":{"override":true}}' \
https://satellite6.example.com/api/smart_class_parameters/63
Copy to Clipboard Toggle word wrap
请注意,无法手动创建或删除参数。用户只能修改其属性。只有在从代理导入类时,才会创建和删除参数。
启用覆盖后,您可以添加自定义覆盖匹配器:
$ curl -H "Accept:application/json,version=2" \
-H "Content-Type:application/json" -X PUT \
-s -k -u sat_username:sat_password \
-d '{"smart_class_parameter":{"override_value":{"match":"hostgroup=Test","value":"2.4.6"}}}' \
https://satellite6.example.com/api/smart_class_parameters/63
Copy to Clipboard Toggle word wrap
有关 API 调用的所有参数的详情,请参考:https://satellite6.example.com/apidoc/v2/override_values.html。
要删除覆盖值,请使用如下命令:
$ curl -X DELETE -s -u sat_username:sat_password \
https://satellite6.example.com/api/smart_class_parameters/63/override_values/3
Copy to Clipboard Toggle word wrap

4.1.3.1. 使用外部文件修改智能类参数

使用外部文件简化了使用 JSON 数据的过程。使用具有语法高亮显示功能的编辑器可帮助您避免和查找错误。

过程 4.2. 使用外部文件修改智能类参数

在本例中,我们将使用 MOTD Puppet 清单。
  1. 按名称搜索 Puppet 类,本例中为 motd
    $ curl -H "Accept:application/json,version=2" \
    -H "Content-Type:application/json" -X GET \
    -u sat_user:sat_passwd -k \
    "https://satellite6.example.com/api/smart_class_parameters?search=puppetclass_name=motd” \
    | python -m json.tool
    {
    "page": 1,
    "per_page": 20,
    "results": [
    {
    "avoid_duplicates": false,
    "created_at": "2017-02-06 12:37:48 UTC",
    "default_value": "",
    "description": "",
    "hidden_value": "*****",
    "hidden_value?": false,
    "id": 3,
    "merge_default": false,
    "merge_overrides": false,
    "override": false,
    "override_value_order": "fqdn\nhostgroup\nos\ndomain",
    "override_values_count": 0,
    "parameter": "content",
    "parameter_type": "string",
    "puppetclass_id": 3,
    "puppetclass_name": "motd",
    "required": false,
    "updated_at": "2017-02-07 13:08:42 UTC",
    "use_puppet_default": false,
    "validator_rule": null,
    "validator_type": ""
    },
    {
    "avoid_duplicates": false,
    "created_at": "2017-02-06 12:37:48 UTC",
    "default_value": true,
    "description": "",
    "hidden_value": "*****",
    "hidden_value?": false,
    "id": 1,
    "merge_default": false,
    "merge_overrides": false,
    "override": false,
    "override_value_order": "fqdn\nhostgroup\nos\ndomain",
    "override_values_count": 0,"parameter": "dynamic_motd",
    "parameter_type": "boolean",
    "puppetclass_id": 3,
    "puppetclass_name": "motd",
    "required": false,
    "updated_at": "2017-02-06 15:21:06 UTC",
    "use_puppet_default": null,
    "validator_rule": null,
    "validator_type": null
    },
    {
    "avoid_duplicates": false,
    "created_at": "2017-02-06 12:37:48 UTC",
    "default_value": "",
    "description": "",
    "hidden_value": "*****",
    "hidden_value?": false,
    "id": 2,
    "merge_default": false,
    "merge_overrides": false,
    "override": false,
    "override_value_order": "fqdn\nhostgroup\nos\ndomain",
    "override_values_count": 0,
    "parameter": "template",
    "parameter_type": "string",
    "puppetclass_id": 3,
    "puppetclass_name": "motd",
    "required": false,
    "updated_at": "2017-02-06 15:21:06 UTC",
    "use_puppet_default": null,
    "validator_rule": null,
    "validator_type": null
    }
    ],
    "search": "puppetclass_name=motd",
    "sort": {
    "by": null,
    "order": null
    },
    "subtotal": 3,
    "total": 66
    }
    Copy to Clipboard Toggle word wrap
    每个智能类参数都有一个 ID,对于同一 Satellite 实例是全局的。motd 类的 content 参数在此 Satellite 服务器中具有 id=3。不要将此功能与 Puppet 类名称前面出现的 Puppet 类 ID 混淆。
  2. 使用参数 ID 3 获取特定于 motd 参数的信息,并将输出重定向到文件,如 output_file.json
    $ curl -H "Accept:application/json,version=2" \
    -H "Content-Type:application/json" -X GET \
    -u sat_user:sat_passwd -k \
    "https://satellite6.example.com/api/smart_class_parameters/3 \
    | python -m json.tool > output_file.json
    Copy to Clipboard Toggle word wrap
  3. 将上一步中创建的文件复制到新文件以进行编辑,例如 changed_file.json。在编辑器中打开 文件,并修改所需的值。在本例中,我们希望将 motd 模块的 content 参数更改为 true,这需要 将覆盖 选项从 false 改为 true
    {
    "avoid_duplicates": false,
    "created_at": "2017-02-06 12:37:48 UTC", # This line must be removed.
    "default_value": "", # A new value should be supplied here.
    "description": "",
    "hidden_value": "*****",
    "hidden_value?": false,
    "id": 3,
    "merge_default": false,
    "merge_overrides": false,
    "override": false, # The override value must be set to true.
    "override_value_order": "fqdn\nhostgroup\nos\ndomain",
    "override_values": [], # This line must be removed.
    "override_values_count": 0,
    "parameter": "content",
    "parameter_type": "string",
    "puppetclass_id": 3,
    "puppetclass_name": "motd",
    "required": false,
    "updated_at": "2017-02-07 11:56:55 UTC", # This line must be removed.
    "use_puppet_default": false,
    "validator_rule": null,
    "validator_type": ""
    }
    Copy to Clipboard Toggle word wrap
  4. 编辑该文件后,验证是否如下所示,然后保存更改:
    {
    "avoid_duplicates": false,
    "default_value": "No Unauthorized Access Allowed",
    "description": "",
    "hidden_value": "*****",
    "hidden_value?": false,
    "id": 3,
    "merge_default": false,
    "merge_overrides": false,
    "override": true,
    "override_value_order": "fqdn\nhostgroup\nos\ndomain",
    "override_values_count": 0,
    "parameter": "content",
    "parameter_type": "string",
    "puppetclass_id": 3,
    "puppetclass_name": "motd",
    "required": false,
    "use_puppet_default": false,
    "validator_rule": null,
    "validator_type": ""
    }
    Copy to Clipboard Toggle word wrap
  5. 按如下所示使用 PUT 命令,将更改应用到 Satellite 服务器:
    $ curl -H "Accept:application/json,version=2" \
    -H "Content-Type:application/json" \
    -X PUT -u $user:$passwd \
    -d @changed_file.json \
    -k "https://satellite6.example.com/api/smart_class_parameters/3
    Copy to Clipboard Toggle word wrap

4.1.4. 将勘误应用到主机或主机集合

您可以将 curl 与 PUT 命令一起使用,以将勘误表应用到主机、主机组或主机集合。以下是 PUT 请求的基本语法:
$ curl -H "Accept:application/json,version=2" \
                   -H "Content-Type:application/json" -X PUT \
                   -u sat_username:sat_password -k \
                   -d json-formatted-data https://satellite6.example.com
Copy to Clipboard Toggle word wrap
您可以浏览内置的 API 文档(https://satellite6.example.com/apidoc/v2.html),以查找用于应用勘误的 URL。您可以使用 Satellite Web UI 来帮助发现搜索查询的格式。导航到 Hosts Host Collections,再选择主机集合。前往 Collection Actions Errata Installation,并注意搜索查询框内容。例如,对于名为 my-collection 的 Host Collection,搜索框包含 host_collection="my-collection"。这将在以下示例中为 Host Collections 使用。

例 4.4. 将勘误应用到主机

在这个示例中,使用批量操作的 API URL /katello/api/hosts/bulk/install_content 来显示简单搜索所需的格式。
$ curl -H "Accept:application/json,version=2" \
       -H "Content-Type:application/json" -X PUT \
       -u sat_username:sat_password -k \
       -d "{\"organization_id\":1,\"included\":{\"search\":\"my-host\"},\"content_type\":\"errata\",\"content\":[\"RHBA-2016:1981\"]}" https://satellite6.example.com/api/v2/hosts/bulk/install_content
Copy to Clipboard Toggle word wrap

例 4.5. 将勘误应用到主机集合

在本例中,请注意传递搜索字符串 host_collection="my-collection" 所需的转义级别,如 Satellite web UI 中所示。
$ curl -H "Accept:application/json,version=2" \
       -H "Content-Type:application/json" -X PUT \
       -u sat_username:sat_password -k \
       -d "{\"organization_id\":1,\"included\":{\"search\":\"host_collection=\\\"my-collection\\\"\"},\"content_type\":\"errata\",\"content\":[\"RHBA-2016:1981\"]}" https://satellite6.example.com/api/v2/hosts/bulk/install_content
Copy to Clipboard Toggle word wrap

4.2. 使用 Ruby 的 API 示例

以下示例演示了如何使用 Ruby 执行各种任务来与 Satellite API 通信。
重要
这些是示例脚本和命令。在使用之前,请确定您仔细查看这些脚本,并替换任何变量、用户名、密码和其他信息,以适应您自己的部署。

4.2.1. 使用 Ruby 创建对象

以下脚本连接到 Red Hat Satellite 6 API 并创建一个新机构,然后在新组织中创建三个环境。如果机构已存在,该脚本将使用该组织。如果组织中已存在任何环境,该脚本将引发错误并退出。
#!/usr/bin/ruby

require 'rest-client'
require 'json'

url = 'https://satellite6.example.com/api/v2/'
katello_url = "#{url}/katello/api/v2/"

$username = 'admin'
$password = 'changeme'

org_name = "MyOrg"
environments = [ "Development", "Testing", "Production" ]

# Performs a GET using the passed URL location
def get_json(location)
  response = RestClient::Request.new(
    :method => :get,
    :url => location,
    :user => $username,
    :password => $password,
    :headers => { :accept => :json,
    :content_type => :json }
  ).execute
  JSON.parse(response.to_str)
end

# Performs a POST and passes the data to the URL location
def post_json(location, json_data)
  response = RestClient::Request.new(
    :method => :post,
    :url => location,
    :user => $username,
    :password => $password,
    :headers => { :accept => :json,
    :content_type => :json},
    :payload => json_data
  ).execute
  JSON.parse(response.to_str)
end

# Creates a hash with ids mapping to names for an array of recods
def id_name_map(records)
  records.inject({}) do |map, record|
    map.update(record['id'] => record['name'])
  end
end

# Get list of existing organizations
orgs = get_json("#{katello_url}/organizations")
org_list = id_name_map(orgs['results'])

if !org_list.has_value?(org_name)
  # If our organization is not found, create it
  puts "Creating organization: \t#{org_name}"
  org_id = post_json("#{katello_url}/organizations", JSON.generate({"name"=> org_name}))["id"]
else
  # Our organization exists, so let's grab it
  org_id = org_list.key(org_name)
  puts "Organization \"#{org_name}\" exists"
end

# Get list of organization's lifecycle environments
envs = get_json("#{katello_url}/organizations/#{org_id}/environments")
env_list = id_name_map(envs['results'])
prior_env_id = env_list.key("Library")

# Exit the script if at least one life cycle environment already exists
environments.each do |e|
  if env_list.has_value?(e)
    puts "ERROR: One of the Environments is not unique to organization"
    exit
  end
end

 # Create life cycle environments
environments.each do |environment|
  puts "Creating environment: \t#{environment}"
  prior_env_id = post_json("#{katello_url}/organizations/#{org_id}/environments", JSON.generate({"name" => environment, "organization_id" => org_id, "prior_id" => prior_env_id}))["id"]
end
Copy to Clipboard Toggle word wrap

4.2.2. 使用 Apipie Bindings

apipie 绑定是 apipie 记录的 API 的 Ruby 绑定,它们从 Satellite 获取并缓存 API 定义,然后按需生成 API 调用。使用 apipie 绑定可让您简化 Ruby API 查询。apipie 通常会报告 "appy-pie",到 rhyme with "happy" without the h。
以下示例创建新组织,然后在新组织中创建三个环境。如果机构已存在,该脚本将使用该组织。如果组织中已存在任何环境,该脚本将引发错误并退出。
#!/usr/bin/tfm-ruby

require 'apipie-bindings'

org_name = "MyOrg"
environments = [ "Development", "Testing", "Production" ]

# Create an instance of apipie bindings
@api = ApipieBindings::API.new({
  :uri => 'https://satellite6.example.com/',
  :username => 'admin',
  :password => 'changeme',
  :api_version => 2
})

# Performs an API call with default options
def call_api(resource_name, action_name, params = {})
  http_headers = {}
  apipie_options = { :skip_validation => true }
  @api.resource(resource_name).call(action_name, params, http_headers, apipie_options)
end

# Creates a hash with IDs mapping to names for an array of records
def id_name_map(records)
  records.inject({}) do |map, record|
    map.update(record['id'] => record['name'])
  end
end

# Get list of existing organizations
orgs = call_api(:organizations, :index)
org_list = id_name_map(orgs['results'])

if !org_list.has_value?(org_name)
  # If our organization is not found, create it
  puts "Creating organization: \t#{org_name}"
  org_id = call_api(:organizations, :create, {'organization' => { :name => org_name }})['id']
else
  # Our organization exists, so let's grab it
  org_id = org_list.key(org_name)
  puts "Organization \"#{org_name}\" exists"
end

# Get list of organization's life cycle environments
envs = call_api(:lifecycle_environments, :index, {'organization_id' => org_id})
env_list = id_name_map(envs['results'])
prior_env_id = env_list.key("Library")

# Exit the script if at least one life cycle environment already exists
environments.each do |e|
  if env_list.has_value?(e)
    puts "ERROR: One of the Environments is not unique to organization"
    exit
  end
end

 # Create life cycle environments
environments.each do |environment|
  puts "Creating environment: \t#{environment}"
  prior_env_id = call_api(:lifecycle_environments, :create, {"name" => environment, "organization_id" => org_id, "prior_id" => prior_env_id })['id']
end
Copy to Clipboard Toggle word wrap

4.3. 使用 Python 的 API 示例

以下示例演示了如何使用 Python 执行各种任务来与 Satellite API 通信。
重要
这些是示例脚本和命令。在使用之前,请确定您仔细查看这些脚本,并替换任何变量、用户名、密码和其他信息,以适应您自己的部署。
以下脚本不使用 SSL 验证与 REST API 交互,此处仅作为演示提供。

4.3.1. 使用 Python 创建对象

以下脚本连接到 Red Hat Satellite 6 API 并创建一个新机构,然后在新组织中创建三个环境。如果机构已存在,该脚本将使用该组织。如果组织中已存在任何环境,该脚本将引发错误并退出。
#!/usr/bin/python

import json
import sys

try:
    import requests
except ImportError:
    print "Please install the python-requests module."
    sys.exit(-1)

# URL to your Satellite 6 server
URL = "https://satellite6.example.com"
# URL for the API to your deployed Satellite 6 server
SAT_API = "%s/katello/api/v2/" % URL
# Katello-specific API
KATELLO_API = "%s/katello/api/" % URL
POST_HEADERS = {'content-type': 'application/json'}
# Default credentials to login to Satellite 6
USERNAME = "admin"
PASSWORD = "changeme"
# Ignore SSL for now
SSL_VERIFY = False

# Name of the organization to be either created or used
ORG_NAME = "MyOrg"
# Name for life cycle environments to be either created or used
ENVIRONMENTS = ["Development", "Testing", "Production"]


def get_json(location):
    """
    Performs a GET using the passed URL location
    """

    r = requests.get(location, auth=(USERNAME, PASSWORD), verify=SSL_VERIFY)

    return r.json()


def post_json(location, json_data):
    """
    Performs a POST and passes the data to the URL location
    """

    result = requests.post(
        location,
        data=json_data,
        auth=(USERNAME, PASSWORD),
        verify=SSL_VERIFY,
        headers=POST_HEADERS)

    return result.json()


def main():
    """
    Main routine that creates or re-uses an organization and
    life cycle environments. If life cycle environments already
    exist, exit out.
    """

    # Check if our organization already exists
    org = get_json(SAT_API + "organizations/" + ORG_NAME)

    # If our organization is not found, create it
    if org.get('error', None):
        org_id = post_json(
            SAT_API + "organizations/",
            json.dumps({"name": ORG_NAME}))["id"]
        print "Creating organization: \t" + ORG_NAME
    else:
        # Our organization exists, so let's grab it
        org_id = org['id']
        print "Organization '%s' exists." % ORG_NAME

    # Now, let's fetch all available life cycle environments for this org...
    envs = get_json(
        SAT_API + "organizations/" + str(org_id) + "/environments/")

    # ... and add them to a dictionary, with respective 'Prior' environment
    prior_env_id = 0
    env_list = {}
    for env in envs['results']:
        env_list[env['id']] = env['name']
        prior_env_id = env['id'] if env['name'] == "Library" else prior_env_id

    # Exit the script if at least one life cycle environment already exists
    if all(environment in env_list.values() for environment in ENVIRONMENTS):
        print "ERROR: One of the Environments is not unique to organization"
        sys.exit(-1)

    # Create life cycle environments
    for environment in ENVIRONMENTS:
        new_env_id = post_json(
            SAT_API + "organizations/" + str(org_id) + "/environments/",
            json.dumps(
                {
                    "name": environment,
                    "organization_id": org_id,
                    "prior": prior_env_id}
            ))["id"]

        print "Creating environment: \t" + environment
        prior_env_id = new_env_id


if __name__ == "__main__":
    main()
Copy to Clipboard Toggle word wrap

4.3.2. 使用 Python 运行查询

您可以创建并运行 Python 脚本,以达到与 第 4.1 节 “使用 Curl 的 API 示例” 中描述的结果相同。以下示例脚本描述了此方法。首先,创建一个名为 sat6api.py 的可执行文件,然后添加以下内容:
#!/usr/bin/python
import json
import sys
try:
    import requests
except ImportError:
    print "Please install the python-requests module."
    sys.exit(-1)

SAT_API = 'https://satellite6.example.com/api/v2/'
USERNAME = "admin"
PASSWORD = "password"
SSL_VERIFY = False   # Ignore SSL for now

def get_json(url):
    # Performs a GET using the passed URL location
    r = requests.get(url, auth=(USERNAME, PASSWORD), verify=SSL_VERIFY)
    return r.json()

def get_results(url):
    jsn = get_json(url)
    if jsn.get('error'):
        print "Error: " + jsn['error']['message']
    else:
        if jsn.get('results'):
            return jsn['results']
        elif 'results' not in jsn:
            return jsn
        else:
            print "No results found"
    return None

def display_all_results(url):
    results = get_results(url)
    if results:
        print json.dumps(results, indent=4, sort_keys=True)

def display_info_for_hosts(url):
    hosts = get_results(url)
    if hosts:
        for host in hosts:
            print "ID: %-10d Name: %-30s IP: %-20s OS: %-30s" % (host['id'], host['name'], host['ip'], host['operatingsystem_name'])

def main():
    host = 'satellite6.example.com'
    print "Displaying all info for host %s ..." % host
    display_all_results(SAT_API + 'hosts/' + host)

    print "Displaying all facts for host %s ..." % host
    display_all_results(SAT_API + 'hosts/%s/facts' % host)

    host_pattern = 'example'
    print "Displaying basic info for hosts matching pattern '%s'..." % host_pattern
    display_info_for_hosts(SAT_API + 'hosts?search=' + host_pattern)

    environment = 'production'
    print "Displaying basic info for hosts in environment %s..." % environment
    display_info_for_hosts(SAT_API + 'hosts?search=environment=' + environment)

    model = 'RHEV Hypervisor'
    print "Displaying basic info for hosts with model name %s..." % model
    display_info_for_hosts(SAT_API + 'hosts?search=model="' + model + '"')

if __name__ == "__main__":
    main()
Copy to Clipboard Toggle word wrap
然后,您可以从命令行运行 ./sat6api.py 来显示结果。

4.4. 使用扩展搜索

您可以使用 Web UI 确定可用于构建查询的其他搜索术语。Satellite 6 支持有范围搜索和 tab 自动完成功能,使此任务变得更加容易。
例如,若要根据其操作系统搜索主机,请导航到 Hosts All Hosts,再单击 Search 文本框中的搜索文本框以显示搜索词的列表。对于操作系统的一个搜索术语是 os_description,您可以在 API 查询中使用,如下所示:
$ curl -s -k -u sat_username:sat_password https://satellite6.example.com/api/v2/hosts?search=os_description=\"RHEL+Server+6.6\" | python -m json.tool
  {
    ...
    "results": [
        {
            "name": "satellite6.example.com",
            "operatingsystem_id": 1,
            "operatingsystem_name": "RHEL Server 6.6",
            ...
        }
    ],
    "search": "os_description=\"RHEL Server 6.6\"",
}
Copy to Clipboard Toggle word wrap

4.5. 使用带有 Pagination Control 的搜索

您可以使用 per_pagepage 分页参数来限制 API 搜索查询返回的搜索结果。per_page 参数指定每个页面的数量,以及 page 参数指定根据 per_page 参数计算的页面,要返回。
当您没有指定任何分页参数时,要返回的默认项目数量被设置为 1000,但 per_page 值的默认值是 20,当您指定 page 参数时应用它。

例 4.6. 列出内容视图

本例显示列出每个页面的第三个页面为 10 个结果:
$ curl -X GET --user sat_username:sat_password \
"https://satellite6.example.com/katello/api/content_views?per_page=10&page=3"
Copy to Clipboard Toggle word wrap

例 4.7. 列出激活码

本例显示 ID 为 1 的机构的 Activation Keys,每个页面返回了 30 个键的第二个页面:
$ curl -X GET --user sat_username:sat_password \
"https://satellite6.example.com/katello/api/activation_keys?organization_id=1&per_page=30&page=2"
Copy to Clipboard Toggle word wrap
要获得多个结果页面,您可以使用 for loop 结构。

例 4.8. 返回多个页面

这个示例将第 1 页的 Content Views 的 3 页返回,每个页为 5 个结果:
$ for i in `seq 1 3`; do curl -X GET --user sat_username:sat_password \
"https://satellite6.example.com/katello/api/content_views?per_page=5&page=$i"; done
Copy to Clipboard Toggle word wrap

4.6. 使用生命周期环境

架构指南 的生命周期环境部分中所述,应用程序生命周期被分为不同的 生命周期环境,这代表应用程序生命周期的每个阶段。https://access.redhat.com/documentation/zh-cn/red_hat_satellite/6.3/html/architecture_guide/chap-red_hat_satellite-architecture_guide-org_loc_and_life_cycle_environments#life_cycle_environments生命周期环境从 环境路径 链接到。要使用 API 创建链接生命周期环境,请使用 prior_id 参数。
您可以参阅 生命周期环境的内置 API 参考,地址为 https://satellite6.example.com/apidoc/v2/lifecycle_environments.html。API 路由包括 /katello/api/environments/katello/api/organizations/:organization_id/environments
您可以列出 Satellite 上针对默认机构 1 的所有当前生命周期环境,如下所示:
$ curl -H "Accept:application/json,version=2" \
-H "Content-Type:application/json" -X GET \
-u sat_user:sat_password -k \
https://satellite6.example.com/katello/api/organizations/1/environments | python -m json.tool
Copy to Clipboard Toggle word wrap
新安装的 Satellite 会有一个类似如下的部分的输出:
      output omitted
   "description": null,
   "id": 1,
   "label": "Library",
   "library": true,
   "name": "Library",
   "organization": {
        "id": 1,
        "label": "Default_Organization",
        "name": "Default Organization"
   },
   "permissions": {
       "destroy_lifecycle_environments": false,
       "edit_lifecycle_environments": true,
       "promote_or_remove_content_views_to_environments": true,
       "view_lifecycle_environments": true
   },
   "prior": null,
   "successor": null,
      output truncated
Copy to Clipboard Toggle word wrap
在以下流程中,默认的库环境 ID 为 1,用作创建生命周期环境的起点。

过程 4.3. 创建链接的生命周期环境

  1. 选择您要用作起点的现有生命周期环境。使用其 ID 列出环境,本例中为 ID 为 1 的环境:
    $ curl -X GET -s -k -u sat_user:sat_password \
    https://satellite6.example.com/katello/api/environments/1 | python -m json.tool
    	output omitted
       "id": 1,
       "label": "Library",
    	output omitted
        "prior": null,
        "successor": null,
    	output truncated
    Copy to Clipboard Toggle word wrap
  2. 使用 prior 选项设置为 1 创建新的生命周期环境:
    1. 创建包含以下内容的 JSON 文件,如 life-cycle.json,其内容如下: {"organization_id":1,"label":"api-dev","name":"API Development","prior":1}
    2. 按照如下所示输入命令:
      $ curl -H "Accept:application/json,version=2" \
      -H "Content-Type:application/json" -X POST \
      -u sat_user:sat_password -k \
      -d @life-cycle.json \
      https://satellite6.example.com/katello/api/environments \
      | python -m json.tool
            output omitted
          "description": null,
          "id": 2,
          "label": "api-dev",
          "library": false,
          "name": "API Development",
          "organization": {
              "id": 1,
              "label": "Default_Organization",
              "name": "Default Organization"
          },
          "permissions": {
              "destroy_lifecycle_environments": true,
              "edit_lifecycle_environments": true,
              "promote_or_remove_content_views_to_environments": true,
              "view_lifecycle_environments": true
          },
         "prior": {
              "id": 1,
              "name": "Library"
          },
      	output truncated
      Copy to Clipboard Toggle word wrap
    在命令输出中,您可以看到此生命周期环境的 ID 是 2,在此前的生命周期环境为 1。这表明,生命周期环境 12 均链接。创建此环境的后续版本 ID 2 时使用生命周期环境 ID 2。
  3. 使用 prior 选项设置为 2 来创建另一个生命周期环境:
    1. 编辑之前创建的 life-cycle.json,更新 标签name 和 before 值 :{organization_id":1,"label":"api-qa","name":"API QA"," prior ":2}
    2. 按照如下所示输入命令:
      $ curl -H "Accept:application/json,version=2" \
      -H "Content-Type:application/json" -X POST \
      -u sat_user:sat_password -k \
      -d @life-cycle.json \
      https://satellite6.example.com/katello/api/environments \
      | python -m json.tool
            output omitted
         "description": null,
         "id": 3,
          "label": "api-qa",
          "library": false,
          "name": "API QA",
          "organization": {
              "id": 1,
              "label": "Default_Organization",
              "name": "Default Organization"
          },
          "permissions": {
              "destroy_lifecycle_environments": true,
              "edit_lifecycle_environments": true,
              "promote_or_remove_content_views_to_environments": true,
              "view_lifecycle_environments": true
          },
         "prior": {
              "id": 2,
              "name": "API Development"
          },
          "successor": null,
      	output truncated
      Copy to Clipboard Toggle word wrap
    在命令输出中,您可以看到此生命周期环境的 ID 是 3,在此前的生命周期环境为 2。这表明,生命周期环境 23 均链接。

更新生命周期环境

可以使用 PUT 命令更新生命周期环境。例如:
$ curl -H "Accept:application/json,version=2" \
-H "Content-Type:application/json" -X POST \
-u sat_user:sat_password -k \
 -d '{"description":"Quality Acceptance Testing"}' \
https://satellite6.example.com/katello/api/environments/3 \
| python -m json.tool
      output omitted
 "description": "Quality Acceptance Testing",
    "id": 3,
    "label": "api-qa",
    "library": false,
    "name": "API QA",
    "organization": {
        "id": 1,
        "label": "Default_Organization",
        "name": "Default Organization"
    },
    "permissions": {
        "destroy_lifecycle_environments": true,
        "edit_lifecycle_environments": true,
        "promote_or_remove_content_views_to_environments": true,
        "view_lifecycle_environments": true
    },
    "prior": {
        "id": 2,
        "name": "API Development"
    },
	output truncated
Copy to Clipboard Toggle word wrap

删除生命周期环境

可以删除生命周期环境,只要没有后续环境。因此,使用以下格式的命令以相反的顺序删除它们:
curl -X DELETE -s -k -u sat_user:sat_password https://satellite6.example.com/katello/api/environments/:id
Copy to Clipboard Toggle word wrap
返回顶部
Red Hat logoGithubredditYoutubeTwitter

学习

尝试、购买和销售

社区

关于红帽文档

通过我们的产品和服务,以及可以信赖的内容,帮助红帽用户创新并实现他们的目标。 了解我们当前的更新.

让开源更具包容性

红帽致力于替换我们的代码、文档和 Web 属性中存在问题的语言。欲了解更多详情,请参阅红帽博客.

關於紅帽

我们提供强化的解决方案,使企业能够更轻松地跨平台和环境(从核心数据中心到网络边缘)工作。

Theme

© 2025 Red Hat