为 Hashmap 和 Pyscript 模块的评级规则设置生存时间。

本规范建议在评级规则中添加一个规则生命周期,并添加审计功能。

问题描述

在计算资源不断更新以改进云平台的动态云环境中,我们看到云环境升级后计算资源的价格被修改;这意味着旧资源变得更便宜,用户可以选择最新的可用资源,通常价格更高。

因此,计算资源的价格不断变化,这意味着它们可能每年变化一次,甚至根据云升级的频率更高。

如今在 CloudKitty 中,当我们创建评级规则(对于哈希映射和 Pyscripts),规则在创建后立即生效,并且在被删除之前一直有效;评级规则的更新也是可能的,我们可以随时进行更新。

为了使资源价格保持最新,操作员需要更改每个创建的评级规则的成本,这在某些规则被遗漏/忘记更新时会造成一些麻烦。 这产生了执行数据重新处理的需求。 此外,由于评级规则的更新在更新时立即生效,操作员必须在特定时间点工作,这不太实用。 例如,如果价格在年初的非常开始发生变化,这将迫使某人必须在新年 1 月的午夜更新规则,等等。

提议的变更

为了方便操作员的工作,并使 Cloudkitty 评级规则创建过程更加动态和灵活,我们建议在 hashmap 和 Pyscript 评级规则模块中添加开始和结束日期。

此外,由于我们正在处理计费数据,这些数据将用于向云环境用户收费,我们还建议为评级规则创建一个审计机制;为此,我们将停止从数据库中删除评级规则;相反,我们将把它们标记为已删除,同时,我们将开始在某些特定情况下拒绝规则更新过程。 这些更改的目的是使系统更安全、可审计和可预测。 此外,我们将添加三列,一列用于存储创建规则的用户,一列用于存储删除规则的用户,最后一列用于存储更新规则的用户。

只有当规则从未被 CloudKitty 用于评级指标时,才能允许更新。 如果已经使用过,我们将不允许更新它。 原因是,我们不能在规则被使用时更改它,因此我们保持其一致性。 操作员始终可以删除评级规则以将其从处理和重新处理中删除。 如果评级规则的结束日期为 None,则我们允许更新(对于尚未使用的规则),这是可以设置为正在使用的评级规则的唯一更新。

对于尚未使用的评级规则,我们允许操作员更新他们希望的任何内容,包括价格、开始和结束日期。

我们允许操作员执行的另一个过程是创建在过去时间开始的评级规则。 只要他们发送一个额外的参数,表明他们理解过去的数据点如果没有执行重新处理,将不会应用此规则。

数据库更改

以下是 Cloudkitty 数据库模式中提出的更改。

hashmap_mappingspyscripts_scripts 表中添加新列

  • created_at: 时间戳,定义规则创建的时间;

  • start: 时间戳,定义规则何时开始被 CloudKitty 应用;

  • end: 时间戳,定义规则何时结束/完成/不再被 CloudKitty 使用。 如果使用 NULL,则表示无限;换句话说,它始终适用;

  • name: 评级规则名称,用于标识规则;

  • description: 评级规则描述;

  • deleted: 删除时间戳;

  • created_by: 创建规则的 keystone 用户的 ID;

  • updated_by: 更改规则的最后一个 keystone 用户的 ID;

  • deleted_by: 删除规则的 keystone 用户的 ID。

+---------------------+--------------+------+---------------------+
| Field               | Type         | Null | Default             |
+---------------------+--------------+------+---------------------+
| created_at          | timestamp    | NO   | CURRENT_TIMESTAMP   |
| start               | timestamp    | NO   | CURRENT_TIMESTAMP   |
| end                 | timestamp    | YES  |                     |
| name                | varchar(32)  | NO   |                     |
| description         | varchar(256) | YES  |                     |
| deleted             | timestamp    | YES  |                     |
| created_by          | varchar(32)  | NO   |                     |
| updated_by          | varchar(32)  | YES  |                     |
| deleted_by          | varchar(32)  | YES  |                     |
+---------------------+--------------+------+---------------------+

REST API

以下是 Cloudkitty REST API 中提出的更改。

  • 路径: /v1/rating/module_config/hashmap/mappings

    方法: GET

    更改

    • 按评级规则生存时间窗口过滤;

    • 按创建/更新/删除规则的用户过滤;

    • 按描述过滤;

    • 显示或不显示,通过一个标志,已删除的评级规则(标记为已删除,并带有删除日期);

    • 显示或不显示,通过一个标志,活动的评级规则(开始和结束日期期间包含当前日期);

  • 路径: /v1/rating/module_config/hashmap/mappings

    方法: POST

    更改

    • 创建规则时添加了四个新值

      start: 规则生效的时间戳;如果未提供,将使用当前时间戳;如果提供没有时间的日期,将使用午夜时间 (00:00:00);如果未提供时区,我们将使用系统的时区。 其值必须小于提供的结束日期,并且不能在过去;

      end: 规则不再生效的时间戳;如果未提供,则为无,表示这是一个无限规则(没有结束日期的规则);如果提供没有时间的日期,将使用第二天午夜前 1 分钟 (23:59:00)。 如果未提供时区,我们将使用系统的时区。 其值必须大于提供的开始时间,并且不能在过去;

      name: 规则名称,是必需值,必须是字符串。 该名称对于所有未删除的规则(未标记为已删除)必须是唯一的;

      description: 规则描述,是可选参数,必须是字符串;

      force: 可选值,允许用户创建开始和结束时间在过去的规则,用于重新处理目的;

    • 在创建规则时,将在后台处理一个新值

      created_by: 我们将使用请求中使用的 Keystone 身份验证令牌设置此值,我们将从令牌中获取用户 ID 并将其设置在此字段中;

  • 路径: /v1/rating/module_config/hashmap/mappings

    方法: PUT

    更改

    • 我们只允许更新规则的结束日期,其他任何内容都不允许,并且仅当当前结束日期未定义(无)时。 新的结束值必须是未来的值。

    • 我们还将允许更新开始日期仍在未来的规则,在这种情况下,允许更新的属性将是

      • start: 如果提供的日期在未来且小于 end;

      • end: 如果提供的日期在未来且大于 start;

      • cost;

      • description;

    • 在更新规则时,将在后台处理一个新值

      updated_by: 我们将使用请求中使用的 Keystone 身份验证令牌设置此值,我们将从令牌中获取用户 ID 并将其设置在此字段中;

  • 路径: /v1/rating/module_config/hashmap/mappings

    方法: DELETE

    更改

    • 我们不再删除规则,而是使用请求调用的当前日期将规则标记为已删除。

    • 在删除规则时,将在后台处理一个新值

      deleted_by: 我们将使用请求中使用的 Keystone 身份验证令牌设置此值,我们将从令牌中获取用户 ID 并将其设置在此字段中;

  • 路径: /v1/rating/module_config/pyscripts/scripts

    方法: GET

    更改

    • 按评级规则生存时间窗口过滤;

    • 按创建/更新/删除规则的用户过滤;

    • 按描述过滤;

    • 显示或不显示,通过一个标志,已删除的评级规则(标记为已删除,并带有删除日期);

    • 显示或不显示,通过一个标志,活动的评级规则(开始和结束日期期间包含当前日期);

  • 路径: /v1/rating/module_config/pyscripts/scripts

    方法: POST

    更改

    • 创建规则时,请求中添加了四个新值

      start: 规则生效的时间戳;如果未提供,将使用当前时间戳;如果提供没有时间的日期,将使用午夜时间 (00:00:00);如果未提供时区,我们将使用系统的时区。 其值必须小于提供的结束日期,并且不能在过去;

      end: 规则不再生效的时间戳;如果未提供,则为无,表示这是一个无限规则(没有结束日期的规则);如果提供没有时间的日期,将使用第二天午夜前 1 分钟 (23:59:00)。 如果未提供时区,我们将使用系统的时区。 其值必须大于提供的开始时间,并且不能在过去;

      name: 规则名称,是必需值,必须是字符串。 该名称对于所有未删除的规则(未标记为已删除)必须是唯一的;

      description: 规则描述,是可选参数,必须是字符串;

      force: 可选值,允许用户创建开始和结束时间在过去的规则,用于重新处理目的;

    • 在创建规则时,将在后台处理一个新值

      created_by: 我们将使用请求中使用的 Keystone 身份验证令牌设置此值,我们将从令牌中获取用户 ID 并将其设置在此字段中;

  • 路径: /v1/rating/module_config/pyscripts/scripts

    方法: PUT

    更改

    • 我们只允许更新规则的结束日期,其他任何内容都不允许,并且仅当当前结束日期未定义(无)时。 新的结束值必须是未来的值。

    • 我们还将允许更新开始日期仍在未来的规则,在这种情况下,允许更新的属性将是

      • start: 如果提供的日期在未来且小于 end;

      • end: 如果提供的日期在未来且大于 start;

      • cost;

      • description;

    • 在更新规则时,将在后台处理一个新值

      updated_by: 我们将使用请求中使用的 Keystone 身份验证令牌设置此值,我们将从令牌中获取用户 ID 并将其设置在此字段中;

  • 路径: /v1/rating/module_config/pyscripts/scripts

    方法: DELETE

    更改

    • 我们不再删除规则,而是使用请求调用的当前日期将规则标记为已删除。

    • 在删除规则时,将在后台处理一个新值

      deleted_by: 我们将使用请求中使用的 Keystone 身份验证令牌设置此值,我们将从令牌中获取用户 ID 并将其设置在此字段中;

工作流程

以下是 Cloudkitty 编排器中处理和重新处理工作流程中提出的更改。

处理

  • 在检查哪些规则必须用于处理数据帧成本时,我们将有三个额外的过滤器(除了 tenant_id)

    • 检查规则的开始时间戳是否小于或等于当前时间戳;并且

    • 检查规则的结束时间戳是否大于当前时间戳;并且

    • 检查规则的删除字段中是否没有设置时间戳;

除了本提案中引入的更改,我们将过滤处理的规则外,其余的处理工作流程将保持不变。

重新处理

  • 在检查哪些规则必须用于处理数据帧成本时,我们将有三个额外的过滤器(除了 tenant_id)

    • 检查规则的开始时间戳是否小于或等于处理的数据帧时间戳;并且

    • 检查规则的结束时间戳是否大于处理的数据帧时间戳;并且

    • 检查规则的删除字段中是否没有设置时间戳;

除了本提案中引入的更改,我们将过滤处理的规则外,其余的重新处理工作流程将保持不变。

总结

通过此扩展,如果需要更新已经使用过的任何规则(开始值在过去),我们需要删除它并创建一个具有更新值的新规则;或者,可以设置结束日期,然后创建一个新规则。 通过使用这种方法,我们可以跟踪规则的所有更改,从而便于审计系统。

如果所有规则都已过期,那么我们将开始使用 0(零)值评级所有资源。 但是,这是预期的,因为不再有有效的评级规则。 为了避免这种情况,可以始终使用没有结束日期的规则。

备选方案

创建一些 cron 触发器来更新服务器中的评级规则成本;

数据模型影响

将在 hashmap_mappingspyscripts_scripts 表中添加新列;

REST API 影响

将在 /v1/rating/module_config/hashmap/mappings/v1/rating/module_config/pyscripts/scripts 端点中添加新字段

安全影响

通知影响

其他最终用户影响

性能影响

其他部署者影响

开发人员影响

实现

负责人

主要负责人

工作项

  1. 扩展数据库模型;

  2. 创建数据迁移过程以填充初始开始日期;

  3. 调整 REST API 以接受新字段;

    3.1) 调整 Hashmap 映射 REST API;3.2) 调整 Pyscript REST API;

  4. 创建新字段的验证机制;

  5. 更改删除 REST API 以不再删除规则;

  6. 调整处理工作流程以适应新规则/验证;

  7. 调整重新处理工作流程以适应新规则/验证;

  8. 更改 Cloudkitty CLI 以接受新字段。

依赖项

测试

单元测试

文档影响

参考资料