掌桥专利:专业的专利平台
掌桥专利
首页

补救在云中的漂移

文献发布时间:2024-04-18 19:59:31


补救在云中的漂移

技术领域

本公开总体涉及云基础设施管理,并且更具体涉及补救云配置代码的漂移。

背景技术

云计算是计算机系统资源的按需可用性,诸如数据存储(“云存储”)和计算能力,无需用户直接主动管理。“云计算”通常用于描述在互联网上可供许多用户使用的数据中心。大型云的功能分布在离中央服务器的多个位置。“云”可能仅限于单个组织(被称为“企业云”),或者可能可用于多个组织(被称为“公有云”)。

云计算依靠于对资源的共享来实现一致性和规模经济,允许公司避免或者最小化前期IT基础设施成本,允许企业更快地启动和运行其应用(具有改善的可管理性和更少的维护),并且使得IT团队能够更快地调整资源以满足波动和不可预测的需求,由此提供突发计算能力,即,在需求高峰的特定时段的高计算能力。云计算增长的因素包括高容量网络的可用性、低成本计算机和存储设备,以及硬件虚拟化的广泛采用。

基础设施即代码(IAC)软件工具已经被开发出来,允许企业使用声明性配置语言来定义和提供数据中心基础设施。这样的软件工具的开源版本的示例是Terraform,而声明性配置语言的示例包括HashiCorp配置语言(HCL)和JavaScript Objection Notation(JSON)。

IAC是通过机器可读的定义文件而不是物理硬件配置或交互式配置工具来管理和供应计算机数据中心的过程。由该过程管理的IT基础设施包括物理设备(诸如裸金属服务器)以及虚拟机两者,并且包括相关联的配置资源。像对待代码一样对待基础设施和使用与任何其他软件项目相同的工具的能力允许开发人员快速地部署应用。

使用IAC软件工具(诸如Terraform)来管理和跟踪企业在云中的资源存在风险,漂移就是其中之一。当期望的基础设施偏离真实的基础设施时,就会发生“漂移”。例如,企业用户采用由托管企业云的云提供商所提供的用户界面来添加新数据库并且将数据加载到新数据库中。此时,企业资源的部署或“真实”基础设施已经偏离了在描述期望基础设施的IAC代码(例如,TerraForm)中反映的期望基础设施。采用由IAC软件工具提供的用户界面的另一企业用户可以对IAC代码进行更改,并且然后将所述更改应用到当前云。因为经修改的IAC代码不引用新数据库,所以应用经修改的IAC代码将使得擦除新数据库。如果经修改的IAC代码被应用在另一数据中心或结构中,则这样做将使得云基础设施缺乏新的数据库。因此,在云中所创建的资源可能无法被跟踪,从而导致多种潜在问题,诸如过度供应。作为过度供应的示例,假设企业用户利用Azure Cloud为企业创建了VMSS(虚拟机规模集)。然而,企业管理一百个订阅和数千个资源组,其中的每个资源组潜在地包含数百个资源。让人手动地跟踪资源并且确定哪些资源和资源组不再使用是困难的。

补救漂移,或者使期望的基础设施与实际的基础设施相一致,需要一个或多个人工操作者的人工干预。当利用数十万个云资源进行大规模操作时,补救会很快成为操作者的操作噩梦,操作者必须不断编辑基础设施代码。可以保留更改日志来跟踪对云提供商代码的更改。然而,熟悉配置代码(例如,Terraform)的人必须手动地查看日志,并且将每个更改转换为对配置代码的更改。

如果IAC代码不准确地反映真实的或实际的基础设施,那么使用IAC代码来推出新的结构将使得结构与真实的基础设施相比存在差异。如果真正基础设施中的关键服务没有被反映在IAC代码中,那么这些推出的结构可能导致中断。

在本节中所描述的方案是可以采用的方案,但是不一定是以前设想或采用的方法。因此,除非另有说明,否则不应当假定在本节中所描述的方案中的任意方案仅仅由于其包含在本节中而具有现有技术的资格。

附图说明

在附图中:

图1是描绘了在实施例中用于自动地执行漂移补救的示例性系统的框图;

图2是描绘了在实施例中基于IAC生成的示例性配置图的框图;

图3A-3B是描绘了在实施例中用于在配置图中传播声明的示例性过程的流程图;

图4是描绘了在实施例中用于遍历配置图的示例性过程的流程图;

图5A-5C是在实施例中描绘示例性配置图以及与配置图中的相同节点相关联的多个声明的框图;

图6是图示了可以在其上实现本发明的实施例的计算机系统的框图。

具体实施方式

在下文的描述中,出于解释的目的,阐述了许多具体细节,以便提供对本发明的透彻理解。然而,将显而易见的是,本发明可以在没有这些具体细节的情况下实践。在其他实例中,以框图形式示出了公知的结构和设备,以便避免不必要地模糊本发明。

一般概述

提供了一种用于补救基础设施代码中的漂移的系统和方法。在一种技术中,基于反映针对企业的期望云基础设施的第一基础设施代码来生成有向图。所述有向图包括:(1)表示诸如模块、资源和数据源等基础设施项的节点,以及(2)连接所述节点中的一些节点的边。基于当前状态数据和提供商模式来生成实际云基础设施的部署状态数据。一旦生成了有向图和部署状态数据,在部署状态数据中所指示的基础设施项就与在所述有向图中所指示的基础设施项相匹配。基于两个集合的基础设施项之间的差异,更新所述有向图以生成经更新的图。基于所述经更新的图,自动地生成与第一基础设施代码不同的第二基础设施代码,并且反映在期望的云基础设施与实际的云基础设施之间的差异。实施例通过自动地补救基础设施代码中的漂移来改进计算机相关的技术。实施例允许漂移被自动地固定并且数据中心的推出是一致的。

示例性基础设施配置代码

下文是针对企业的期望基础设施配置代码(被标记为“原始配置代码”)的简单示例,以便例示说明漂移修复:

原始配置代码

原始配置代码是Terraform IAC配置代码的示例。(在本文中提供了该配置代码的更新版本,其标题为“经更新的配置代码”,其可以使用在本文中所描述的技术来生成。)在该示例中,在位于规模集资源块内的预期状态块内有两个工作负荷块。在该示例中,云提供商是Microsoft Azure,但是其他示例性云提供商包括Google Cloud和Amazon WebServices。

IAC配置代码(或者基础设施配置代码,或者简称IAC)描述了一种配置。配置可能包括多个文件和目录。包含IAC的文件被称为配置文件。配置通知软件工具(诸如TerraForm)如何管理企业的基础设施。

IAC语言是围绕两个主要的语法结构而构建的:变元和配置块(或者简称“块”)。变元将值赋给特定名称,被称为变元名称或者属性名称。值可以是原始值(例如,字符串值、布尔值或者整数值)、引用(即,对另一块的引用)或者这两者中的任意一个的组合,诸如由运算符联接的两个原始值,或者原始值和引用的聚合。

块是针对内容的容器,并且具有类型。块类型的示例包括资源、局部变量、数据源和模块。模块是充当针对资源、局部变量和数据源的容器的特殊块。

每个块都包括类型名称,其指示块类型(例如,“资源”表示资源,“局部”表示局部变量,并且“数据”表示数据源)。模块可以是远程的或者本地的。本地模块具有本地源,并且远程模块具有远程源。例如,本地模块引用包含Terraform代码的本地目录中的配置代码路径,而远程模块引用包含Terraform代码的可下载目录。

每个块类型定义了类型名称后面的多个标签。例如,资源块类型需要两个标签。特定的块类型可以具有任意数量的所需标签,或者可能不需要标签,诸如嵌套的geo_location块类型。

在块类型名称和任意标签之后,块的主体由{and}字符定界。在块主体内,可以嵌套另外的变元和块,从而创建块以及其相关联的变元的层级。

对于在上文示例性IAC中的“tfaas_db”资源块,属性/变元名称包括“enable_automatic_failover”、“enable_nultiple_write_locations”和“ip_range_filters”,而consistency_policy块的属性/变元名称包括“consistency_level”和“max_interval_in_seconds”。在这些示例中,属性/变元名称(或者简称“属性”)的值是字符串。然而,属性的值可以是整数或者对另一块的引用。

系统概述

图1是描绘了在实施例中用于自动地执行漂移补救的示例性系统100的框图。系统100包括提供商模式数据110、当前状态数据120、基础设施即代码(IAC)130、补救引擎140和经更新的IAC 160。补救引擎140包括状态生成器142、部署状态数据144、图生成器146、配置图148、声明(claim)传播器150和声明解析器152。

状态生成器142将提供商模式数据110和当前状态数据120作为输入,并且生成部署状态数据144作为输出。图生成器146将IAC 130作为输入,并且生成配置图148作为输出。声明传播器150将配置图148和部署状态数据144作为输入,并且利用一个或多个声明来更新配置图148。声明是将属性值从部署状态数据144临时指派给配置图148中的节点的属性。在声明传播器150生成所有声明之后,配置图148中节点的一些属性可以与多个声明相关联。声明解析器152解析其中多个声明与配置图148中的同一节点相关联的任何情况,并且相应地更新配置图148。补救引擎140(或者其组件)获取配置图148的经更新的版本,并且生成经更新的IAC 160作为输出。

提供商模式数据

提供商模式数据110包括定义哪些属性会是配置的一部分以及哪些属性会不是配置的一部分的模式数据。提供商模式数据110被用于将当前状态数据120转换为等效配置代码。例如,从当前状态数据120中移除提供商模式数据110中对应的“'computed':'true'”字段是从当前状态到配置代码的转换的一部分。一旦完成了该步骤,结果就是以JSON形式在真实/实际基础设施中部署的所有内容的完整表示。

不同的云提供商具有不同的模式。因此,提供商模式数据110可以包含多个提供商模式。

对于提供商模式的每个实例,提供商模式数据110包含资源的字段类型(例如,字符串、布尔、数值)和资源的模式(例如,provider_schemas.registry.terraform.io/hashicorp/azurerm.resource_schemas.azurerm_coosdb_account,以及资源的属性是否不会是配置的一部分)。以下是示例性提供商模式的一部分:

/>

/>

/>

/>

/>

/>

提供商模式

当前状态数据

当前状态数据120是反映企业的基础设施的当前状态的配置代码,其格式对实现企业的基础设施的云提供商可识别。因此,当前状态数据120符合该云提供商的模式。如在本文中所描述的,不同的云提供商具有不同的配置代码模式。

当前状态数据120的示例如下:

/>

/>

/>

/>

/>

/>

当前状态

因为能够通过被称为模块的容器对资源进行分组,所以当前状态数据120以特定格式(诸如JSON)按模块来组织资源。

当前状态数据120可以包括多个当前状态,每个当前状态描述不同云基础设施的当前状态,所述不同云基础设施可以是或者可以不是不同的企业。云基础设施的当前状态数据可以指示当前状态数据所符合的提供商模式。该信息辅助状态生成器142在给定当前状态数据的情况下识别正确的提供商模式数据。

状态生成

为了生成经更新的IAC 160,补救引擎140需要知道所部署的基础设施的状态。状态生成器142生成该状态,在本文中被称为部署状态数据144。状态生成器142采用两个集合的数据作为输入,以便生成部署状态数据144:提供商模式数据110和当前状态数据120。部署状态数据144的示例如下:

API serverlistening at:127.0.0.1:4961

&{Modules:map[:0xc00090b340]}

container

<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Containet>(0XC00059ee68)

Modules:

dsl/terraformdsl/state.Module>(length:l)

″″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Module>(0xc00090b340)

Addr:nil

Resources:

dsl/terraformdsl/state.Resource>(length:3)

″azurerm_cosmosdb_account.tfaas_db″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Resource>(0xc000le8000)

Addr:

targetable:

Module:nil

Resource:

referenceable:

Mode:ManagedResourceMode(77)

Type∶″azurerm_cosmosdb_account″

Name:″ffaas_db″

ProviderName:″registry.terraform.io/hashicorp/azurerm″

DependsOn:nil<[]github.com/hashicorp/hcl/v2.Traversal>

Instances:

igo-terraform-dsl/terraformdsl/state.ResourceInstance>(length:1)

nli

<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.ResourceInstance>(Oxc0008f77aO)

Block:

Attributes:

dsl/terraformdsl/state.Attribute>(length:19)

″read_endpoints″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0Xc000026180)

Type:

Description:″″

DescriptionKind:″plain″

Required:false

Optional:false

Computed:true

Sensitive:false

Deprecated:false

Value:

″enable_multiple_Write_locations″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc0000263c0)

″is_virtual_network_filter_enabled″:<*golang.linkedin.com/ligo-terraform

dsl/terraformdsl/state.Attribute>(0xc0000264e0)

″location″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc000026540)

″secondary_readonly_master_key″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc0000266c0)

″connection_strings″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc000026060)

″kind″:<*golang.linkedin.com/ligo-terrafoim-

dsl/terraformdsl/state.Attribute>(0xc0000260c0)

″offer_type″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc000026120)

″write_endpoints″:<*golanglinkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc0000261e0)

″endpoint″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc000026420)

″name″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc0000265a0)

″secondary_master_key″:<*golanglinkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc000026600)

″tags″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc000026720)

″ip_range_filter″:<*golanglinkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc000026240)

″primary_master_key″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc0000262a0)

″primary_readonly_master_key″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc000026300)

″enable_automatic_faliover″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc000026360)

″id″:<*golang.1inkedin.com/ligo-terrrraform-

dsl/terraformdsl/state.Attribute>(0xc000026480)

″resource_group_name″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc000026660)

BlockTypes:

dsl/terraformdsl/state.NestedBlock>(length:5)

″geo_location″:<*golang.linkedin.com/ligo-terrafoim-

dsl/terraformdsl/state.NestedBlock>(0xc00090b480)

″timeouts″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.NestedBlock>(0xc00090b4c0)

″virtual_network_rule″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.NestedBlock>(0xc00090b500)

″capabilities″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.NestedBlock>(0xc00090b540)

″consistency_policy″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.NestedBlock>(0xc00090b580)

Description″″

Deprecated:false

″azurerm_private_endpoint.db_endpoint″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Resource>(0xc0001e8070)

Addr:

targetable:

Module:nil

Resource:

referenceable:

Mode:ManagedResourceMode(77)

Type:″azurerm_private_endpoint″

Name:″db_endpoint″

ProviderName:″registry.terraform.io/hashicorp/azurerm″

DependsOn:nil<[]github.com/hashicorp/hcl/v2.Traversal>

Instances:

igo-terraform-dsl/terraformdsl/state.ResourceInstance>(length:1)

nil

<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.ResourceInstance>(0xc0008f7b90)

Block:

Attributes:

dsl/terraformdsl/state.Attribute>(length:8)

″name″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc000026d20)

″private_dns_zone_configs″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc000026d80)

″resource_group_name″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc000026de0)

″subnet_id″:<*golang.linkedin.com/ligo-terraform-

dsl/terraforrndsl/state.Attribute>(0xc000026e40)

″tags″:<*golang.linkedin.com/ligo-terraform-

dsl/terraforrndsl/state.Attribute>(0xc000026ea0)

″custom_dns_configs″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc000026f00)

″id″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc000026f60)

″location″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Attribute>(0xc0O0026fc0)

BlockTypes:

dsl/terraformdsl/state.NestedBlock>(length:3)

″private_dns_Zone_group″:<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.NestedBlock>(0xc00090b600)

″private_service_connection″:<*golanglinkedin.com/ligo-terraform-

dsl/terraformdsl/state.NestedBlock>(0xc00090b640)

″timeouts″:<*golang.linkedin.com/ligo-teirraform-

dsl/terraformdsl/state.NestedBlock>(0xc00090b680)

Description:″″

Deprecated:false

″azurerm_private_endpoint.db_endpoint_southcentral″:

<*golang.linkedin.com/ligo-terraform-

dsl/terraformdsl/state.Resource>(0xc0001e80e0)

Addr:

targetable:

Module:nil

Resource:

referenceable:

Mode:ManagedResourceMode(77)

Type:″azurerm_private_endpoint″

Name:″db_endpoint_southcentral″

ProviderName:″registry.terraform.io/hashicorp/azurerm″

DependsOn:nil<[]github.com/hashicorp/hcl/v2.Traversal>

Instances:

igo-terraform-dsl/terraformdsl/state.ResourceInstance>(length:1)

ChildModules:nil

dsl/terraformdsl/state.Module>

InputValues:nil

dsl/terraformdsl/state.InputValue>

OutputValues:nil

dsl/terraformdsl/state.OutputValue>

利用来自提供商模式数据110的信息(诸如字段类型和结构),状态生成器142使用静态类型化语言(诸如Golang)从当前状态数据120生成等效的数据结构。

因为能够按模块对资源进行分组,所以状态生成器142在数据结构(例如,Golang结构)内按模块对资源进行分组,使得在部署状态数据144中的每个单个资源都能够被恰当地映射到IAC中的全局独有资源标识符。该标识符映射到父模块地址加上每个资源的资源地址(例如,module.parentl module.parent2.azurerm_coosdb_account.some_db),允许IAC中匹配的资源块作为起始评估点。

数据结构(例如,Golang结构)可以被视为三层节点:(1)顶层容器节点,其包含若干(2)模块节点,其包含(3)资源节点。

图生成

图生成器146生成配置图148,配置图148是IAC 130的图表示。配置图148的目的是使得声明传播器150能够遍历所述图并且确定应当在哪里进行配置代码编辑。当前的IAC评估器(诸如Terraform)没有提供将状态信息向后传播到源的方案(即,从部署状态到IAC)。

配置图148包括节点和边。节点表示IAC 130中的块。节点可以是多种类型之一,每种类型对应于配置代码语言(例如,HCL或JSON)中的块类型之一。因此,节点类型的示例包括模块节点、资源节点、数据节点和本地节点。模块节点表示子资源的模块或容器,其示例包括资源、数据源和局部变量。因此,模块节点可以“包含”一个或多个资源节点、一个或多个数据节点和/或一个或多个本地节点,或者与之相关联。模块节点也与(1)表示对应模块的输入的输入节点和(2)表示对应模块的输出的输出节点相关联。

配置图148包括作为根节点的模块节点。配置图148中的每个其他模块节点是另一模块节点的子节点,并且具有其父模块节点的边。

连接图148中的一些节点具有连接它们的边。如果第二节点引用第一节点,则配置图148中的第一节点具有指向第二节点的有向边。每个边对应于不同的属性。

示例性配置图

图2是描绘了在实施例中基于IAC生成的示例性配置图200的框图。配置图200是配置图148的示例,并且可以由图生成器146生成。

配置图200包括根节点210、子模块(M1)节点230、子模块(M2)节点250以及远程模块(M3)节点270。根节点210包括资源节点212、本地节点214、数据源节点216和模块节点218。

M1节点230包括资源节点232、本地节点234、模块节点236和模块节点238。M1节点230也与M1输入节点240和M1输出节点242相关联。输入节点和输出节点对应于单个块属性,并且分别对应于输入变量和输出变量。来自IAC的输入变量的示例如下:

来自IAC的输出变量的示例如下:

/>

M2节点250包括资源节点252、本地节点254、模块节点256和模块节点258。M2节点250也与M2输入节点260和M2输出节点262相关联。M3节点270包括资源节点272、本地节点274、资源节点276和资源节点278。M3节点270也与M3输入节点280和M3输出节点282相关联。配置图200也具有多个边。边220指示资源节点212被本地节点214引用,边222指示资源节点212也被输出节点242引用,以及边224指示资源节点212也被数据源节点216引用。

类似地,边244指示输入节点240被模块节点218引用,边246指示M1节点230被M1输入节点240引用,边248指示输出节点242被M1节点230引用,以及边249指示模块节点238被M2输出节点262引用。

类似地,边264指示模块节点236被M2输入节点260引用,边266指示M2输入节点260被M2节点250引用,边268指示M2输入节点260也被资源节点252引用,以及边269指示M2节点250被M2输出节点262引用。

类似地,边284指示模块节点238被M3输入节点280引用,边286指示M3输入节点268被M3节点270引用,以及边288指示M3节点270被M3输出节点282引用。

利用配置图200(或者配置图148),使得跨模块、资源和表达式的状态传播成为可能。配置图200允许从(a)被跟踪的云实例的评估的资源值转换为(2)在(例如,Terraform)配置代码中的代码编辑。声明传播和声明解析详述了一种方法,通过这种方法,被跟踪的云实例的评估的资源值被映射到配置代码编辑。在声明传播之后,在配置图200中的节点的单个属性可以与多个声明相关联。针对该节点的声明解析是选择这些声明之一的过程,如在本文中更详细描述的。

声明传播器

声明传播器150将配置图148和部署状态数据144作为输入,并且利用一个或多个声明来更新配置图148。声明是属性值从部署状态数据144到配置图148中的节点的属性的建议的编辑或临时指派。在声明传播器150生成所有声明之后,配置图148中的节点的一些属性可能与多个声明相关联。声明传播的目的是尽可能在配置图148上传播与资源配置指定(或者无法确定)不同的任何属性值(来自部署状态)。这是因为IAC(例如,Terraform代码)是按照模块来构造的,并且在Terraform代码的标准评估期间,用户可配置的值在配置图148的源处(或者在根处或者在根附近)。作为特定示例,到IAC 130的输入被定义在“tfvars”或“tfvars.json”文件中,并且用户可以定义包含多个节点(terraform配置文件)的多个模块(或者文件系统目录)。因此,在漂移补救阶段期间,重要的是“去评估(de-evaluate)”或者确保已经偏离IAC的任何值被传播,只要可能,靠近于定义“tfvars”文件的地方,或者在可能的情况下向上传播到父模块。所述传播路径是基于配置图148来确定的。企业用户意图将可配置的输入设置得尽可能地靠近于定义rfvars文件的位置。策略是基于属性值(在配置图148中的匹配节点中)是对另一节点的属性的引用还是原始值自身来传播属性值(来自部署状态)。总是传播与引用有关的声明(因为引用所指向的节点更接近于用户输入),而不传播原始值(因为没有明确的更高的引用)。例如,如果M3节点270是配置图200中的匹配节点(即,其匹配来自部署状态数据144的所选择的资源),并且M3节点270中的特定属性的属性值是引用,则边286跟随到输入变量280,并且然后边284跟随到模块节点238。如果模块节点238包括特定属性并且其值是原始值,则对模块节点238的特定属性进行声明。如果特定属性的值相反是引用,则边249和边269跟随到M2节点250,并且再次进行原始值/引用检查。

图3A-3B是描绘了在实施例中用于在配置图中传播声明的示例性过程300的流程图。过程300可以由声明传播器150和/或补救引擎140的其他组件来执行。

在框310处,选择在部署状态数据144中所指示的资源。框310中的选择可以是随机的,或者可以通过以特定顺序选择资源来执行,诸如选择在部署状态数据144中所指示的、尚未被选择的第一资源。在框320处,确定所选择的资源的资源名称是否与配置图148中所指示的资源的资源名称/标识符(也被称为“资源地址”)相匹配。如果否,则过程300进行到框330。(在这种情况下,假定所选择的资源是新的或者是在IAC 130被创建之后添加的。)否则,过程300进行到框340。

框320可以涉及将所选择的资源的资源名称与配置图148的每个节点中所指示的每个资源名称进行比较,直到找到匹配为止。在配置图148中对匹配节点的搜索可以继续,直到已经考虑了尚未被匹配的(配置图148的)所有节点。一旦找到匹配节点,基于所选择的资源的配置图148的搜索结束。匹配节点将是配置图148中的叶节点。

在框320中搜索配置图148的节点的顺序可以是随机的,或者可以从根节点或者尚未匹配的最高级别节点(在配置图148中)开始,并且然后进行到较低级别节点。

在框330处,更新配置图148以包括与所选择的资源相对应的新节点。所述新节点包括从部署状态数据144中选择的资源中所指示的属性名称和值。确定所选择的资源的父资源并且将其匹配到配置图148中的节点。所述新节点成为该节点的子节点。过程300进行到框360。

在框340处,确定所选择的资源的第一集合的属性是否与配置图148中的匹配节点的第二集合的属性相匹配。例如,第一集合的属性可以大于或者小于第二集合的属性。作为另一示例,在所述第一集合的属性中的一个属性可能不存在于所述第二集合的属性中,和/或反之亦然。如果两个集合的属性不匹配,则过程300进行到框350;否则,过程300进行到框360。框340也可以涉及标记匹配节点以指示存在匹配,或者以其他方式存储将匹配节点标识为匹配的一部分的数据。稍后,在框370中使用该数据来确定是否存在与部署状态数据144中的资源没有经历任何匹配的任何节点。

在框350处,更新配置图148中的匹配节点以包括所述第一集合的属性。例如,删除所述第二集合的属性中的一个属性和/或将属性添加到所述第二集合的属性中。然后,过程300进行到框360。

在框360处,确定是否存在尚未从部署状态数据144中选择的任何更多的资源。如果是,则过程300返回到框310。否则,过程300进行到框365,其开始涉及框365和框370的修剪阶段。

在框365处,确定配置图148中是否存在尚未与来自部署状态数据144的资源相匹配的任何节点。如果是,则过程300进行到框370;否则,过程300进行到框380。框365可以涉及检查配置图148中的每个节点以确定其是否与指示来自部署状态数据144的资源与该节点相匹配的匹配数据相关联。

在框370处,从配置图148中删除框365中的识别出的节点。在修剪阶段之后,过程300进入声明生成阶段,包括框375-395。

在框375处,选择配置图148中的匹配节点。

在框380处,对于匹配节点中对应于来自部署状态的资源的每个属性,确定(匹配节点的)该属性的属性值是引用还是原始值。原始值的示例包括特定字符串、特定整数或者特定布尔值。事实上,在JSON中,仅有的属性值是字符串、布尔值和整数。配置图148中的匹配节点指示属性是引用还是原始值。如果属性是原始值,则过程300进行到框385;否则,过程300进行到框390。

在框385处,对匹配节点进行来自所选择的资源的属性值的声明。换言之,来自所选择的资源的属性值(至少暂时)与匹配节点相关联。声明也可以包括匹配节点的标识符。

在框390处,遍历配置图148中的匹配节点的一个或多个祖先节点,以识别其对应块具有所述属性的祖先节点,并且该属性被分配原始值。框390导致创建对该祖先节点的声明。换言之,来自所选择的资源的属性值与该祖先节点相关联。声明包括匹配节点的标识符、祖先节点的标识符和识别在匹配节点与祖先节点之间遍历的任何节点的路径。在图4中更详细地解释了框390。

在框395处,确定在(配置图148)中是否存在尚未在框375中选择的匹配节点。如果是,则过程300返回到框375;否则,进程300结束。

遍历配置图

图4是描绘了在实施例中基于特定属性从匹配节点遍历配置图148的示例性过程400的流程图,所述特定属性在IAC块中被分配了对应于匹配节点的引用。“遍历”指代跟随配置图148中的一个或多个边和节点,从基于部署状态数据144中所指示的所选择的资源而识别的匹配节点开始。所述匹配节点被称为关于特定属性的“源”。为所选的资源分配针对特定属性的值。如在本文中所提到的,遍历的目的是识别最高级别节点以进行原始值编辑,其涉及(1)将所选择的资源的属性的原始值分配给(2)配置图148中所指示的节点中的属性,其中,所述节点要么是匹配节点,要么是在配置图148向上(即,朝向根节点)比匹配节点更高的节点。使原始值编辑在配置图148中尽可能高使得维护IAC 130/160更可管理,因为最终用户和自动化程序期望在这些属性可能被定义的地方(即,尽可能靠近于根节点)为这些属性提供输入。

在框410处,识别配置图148中的当前节点的边。在框410的第一迭代中,当前节点是源或匹配节点。在框410的后续迭代中,当前节点是源的祖先节点。

边从当前节点指向另一节点。这样的边被称为相对于框410的节点的传出边。在一些情况下,节点具有多个传出边。例如,资源节点212具有多个传出边。因此,框410可以涉及选择所述多个传出边中的一个传出边。

在框420处,基于在框410中识别出的边来识别祖先节点。如果祖先节点是模块输入节点或者模块输出节点,则跟随来自该节点的传出边,直到识别出非输入/非输出祖先节点。

在框430处,确定祖先节点是否具有与特定属性(所讨论的)相匹配的属性。如果是,则过程400进行到框440。否则,过程400进行到框470。

在框440处,祖先节点的标识符被记录在路径数据中,所述路径数据指示基于特定属性而遍历的节点的路径(从源开始)以及来自触发当前遍历的部署状态的对应所选择的资源。

在框450处,确定祖先节点的属性值是否是引用。如果否,则过程400进行到框460。否则,过程400进行到框470,其中,祖先节点成为当前节点。

在框460处,创建对祖先节点的声明。换言之,来自所选择的资源的属性值暂时与该祖先节点相关联。声明也指示属性的名称、源的标识符、祖先节点的标识符和路径数据。祖先节点被称为“汇(sink)”。

例如,所选择的资源匹配与资源节点252相对应的配置节点。如果资源节点252的资源包括被分配给引用的属性,则边268跟随至M2输入节点260,并且(只要M2输入节点260不具有属性的定义)边266跟随至模块节点236。如果模块节点236包括该属性,则确定所述属性被分配引用还是原始值。如果是前者,那么所述边被跟随,并且重复该遍历过程;如果是后者,则模块节点236暂时与来自所选择的资源的对应属性值相关联。

在框470处,当前节点成为祖先节点。然后,当过程400返回到框410时,将识别祖先节点的边。

声明解决

在分析部署状态数据144中的每个资源之后,配置图148中的一个或多个节点可以包括关于同一属性的多个声明。例如,模块节点218可以包括多个声明,每个声明对应于相同的属性。作为特定示例,IAC 130中的配置块可以包括其名称为“计数”的属性和关于计数属性的值的不同声明。

声明解析从叶节点(例如,资源节点)开始并且向上传播到根模块节点。声明解析器152选择配置图148中的节点,并且确定所述节点是否与关于同一属性的多个声明相关联。如果是,则声明解析器152考虑一个或多个因素以选择多个声明之一应用于节点的属性。“将声明应用到节点”涉及更新所述节点以将声明的值分配给节点的对应属性。如果存在多个因素,则可以对所述因素进行分层或优先化,从而按照从最高优先级到最低优先级的顺序考虑所述因素。

声明解析的原则是确定哪个声明是最不可改变的。例如,第一因素是声明是否在源上。换言之,声明的源和汇是同一节点。因此,声明不能够向上传播或者在配置图148上进一步向上。该第一因素可以是最高优先级因素,并且因此可以首先应用。属性上的任何其他声明都向后/向下传播到这些(一个或多个)声明的源。

第二因素是声明是否在计算的属性上。计算的属性是在服务器侧计算值而不是在IAC 130中作为输入提供值的属性。如果声明的值与计算的属性的值相匹配,那么该声明将获得下一最高的优先级。否则,所述声明是无效的并且向后传播,因为计算的字段通常是只读的。

第三因素是声明是否在取决于远程源的属性上。远程源是未在IAC 130中配置的源。例如,所述属性可以是对云中的其他地方的源或者对基础设施之外的存储库的引用。这样的声明被从属性中移除(或者解除关联),并且声明的路径数据被用于向后(或者向下朝向叶节点)传播。因此,路径数据被用于识别声明路径中的在前节点,并且声明与该在前节点相关联。

如果仍然存在与节点的属性相关联的多个声明,则用于选择多个声明之一的第四因素确定多个声明中的任何声明是否具有以下路径:所述路径是多个声明中的另一声明的路径的子路径。具有子路径的声明将始终具有优先级;否则,具有子路径的声明将无法对节点进行引用。

如果仍然有与节点相关联的多个声明,那么第五因素是选择具有最短路径的声明。例如,如果(1)声明A具有从声明的汇到声明A的源的长度为三个节点的路径,并且(2)声明B具有从声明的汇到声明B的源的长度为五个节点的路径,那么声明A被应用于当前节点。如果在考虑了所有这些因素之后,仍然存在与节点相关联的多个声明,则随机地选择声明中的一个声明,并且沿着其相应路径向后传播(一个或多个)其他声明。

在将这些因素中的一个或多个因素应用于具有多个声明的节点之后,所述节点将具有单个声明。该单个声明被应用于节点。对该节点的所有其他声明基于其相应的路径向下传播一个节点。相应路径可以相同或不同的。例如,节点X是针对声明A、B和C的汇。在应用所述一个或多个因素之后,声明A被应用到节点X。然后,声明B被分配给节点Y,并且声明C被分配给节点Z,其中,节点Y和Z是节点X的子节点。节点Y在声明B的路径中,并且节点Z在声明C的路径中。

图5A-5C是在实施例中描绘了示例性配置图500并且图示了可以如何解析与配置图500中的相同节点相关联的多个声明的框图。配置图500包括N1 502(根节点)、N2 504、N3506、N4 508、N5 510和N6 512。N2 504是N1 502的子节点,N3 506和N4 508是N2 504的子节点,N5 510是N4 508的子节点,并且N6 512是N5 510的子节点。

图5A指示在声明传播之后,存在与N1 502相关联的三个声明:声明A-C。每个声明指示其源和汇。针对每个的汇都是相同的:N1 502。因为针对声明B的汇和源是相同的,所以声明B被应用到N1 502,并且其他两个声明被沿配置图500向下传播到N1 502的子节点,即N2 504,其被反映在图5B中。

图5B指示存在与N2 504相关联的两个声明:声明A和C。因为针对声明A的源(即,N3506)比针对声明B的源(即,N6 512)更接近N2 504,所以声明A被应用于N2 504,并且声明C沿配置图500向下传播到声明C的源,其在该示例是N4 508。

图5C指示存在与N4 508相关联的一个声明。配置图500中没有与多个声明相关联的节点。因此,声明解析是完整的。

生成经更新的基础设施配置代码

在实施例中,在配置图148中的每个节点处考虑这些因素中的一个或多个因素,直到没有节点与多个声明相关联。在所有声明被应用到配置图148中的其相应的节点之后,补救引擎140(或者其另一组件)基于配置图148的经更新的版本来生成经更新的IAC 160。例如,对于配置图148中的每个节点,生成配置块并且将其包括在IAC 160中,所述配置块最初可以是空的,即,没有任何数据。如果节点具有任何属性,那么这些属性就被包含在配置块中。可选的、没有值的或者被计算出的属性不被包含在配置块中。模块节点是一种特殊情况,其相应属性被存储在具有特定文件扩展名的文件中,诸如a.tfvars扩展名。在配置图中的每个节点都带有资源地址,所述资源地址在(例如,Terraform)文件中独有地标识资源。资源地址的格式可以是..元素映射到文件系统中的目录。.元素映射到该目录内的资源块。通过这种映射,获知针对配置图中的每个节点的资源所在的确切文件和在文件中的位置。目录路径和.元素在维护针对特定模块的所有资源的位置的实现方式中就足够了。

以下是与上文的原始配置代码相对应的示例性IAC代码,但是基于部署状态进行更新:

经更新的配置代码

在该经更新的配置代码与原始配置代码之间的差异包括经更新的配置代码具有新的geo_location故障转移以及用+标记的经更新的max_interval_in_seconds。

硬件概述

根据一个实施例,在本文中所描述的技术由一个或多个专用计算设备实现。专用计算设备可以是硬连线的以执行所述技术,或者可以包括数字电子设备,例如一个或多个专用集成电路(ASIC)或现场可编程门阵列(FPGA),其被持续地编程以执行所述技术,或者可以包括一个或多个通用硬件处理器,其被编程以根据固件、存储器、其他存储设备或组合中的程序指令执行所述技术。这样的专用计算设备还可以将定制的硬连线逻辑、ASIC或FPGA与定制编程相结合来实现这些技术。专用计算设备可以是台式计算机系统、便携式计算机系统、手持设备、网络设备或结合了硬连线和/或程序逻辑以实现所述技术的任何其他设备。例如,图6是示出可以在其上实现本发明的实施例的计算机系统600的框图。计算机系统600包括用于通信信息的总线602或者其他通信机制,以及与总线602耦合用于处理信息的硬件处理器604。硬件处理器604可以是例如通用微处理器。

计算机系统600还包括耦合到总线602的主存储器606,例如随机存取存储器(RAM)或者其他动态存储设备,用于存储要由处理器604执行的信息和指令。主存储器606还可用于在执行将由处理器604执行的指令期间存储临时变量或者其他中间信息。当这样的指令存储在处理器604可访问的非暂时性存储介质中时,将计算机系统600渲染为被定制为执行指令中指定的操作的专用机器。

计算机系统600还包括与总线602耦合的只读存储器(ROM)608或者其他静态存储设备,用于存储用于处理器604的静态信息和指令。存储设备610(例如磁盘、光盘或固态驱动器)被提供并且耦合到总线602,用于存储信息和指令。

计算机系统600可以经由总线602耦合到显示器612,例如阴极射线管(CRT),用于向计算机用户显示信息。包括字母数字和其他键的输入设备614耦合到总线602,用于将信息和命令选择通信到处理器604。另一类型的用户输入设备是光标控件616,例如鼠标、轨迹球或光标方向键,用于将方向信息和命令选择通信到处理器604并且用于控制显示器612上的光标移动。该输入设备通常在两个轴上具有两个自由度,第一轴(例如,x)和第二轴(例如,y),这允许设备指定平面中的位置。

计算机系统600可以使用定制的硬连线逻辑、一个或多个ASIC或FPGA、固件和/或程序逻辑来实现在本文中所描述的技术,其与计算机系统结合使计算机系统600成为或将其编程为专用机器。根据一个实施例,计算机系统600响应于执行包含在主存储器606中的一个或多个指令的一个或多个序列的处理器604执行在本文中所描述的技术。这样的指令可以从另一存储介质(例如,存储设备610)读入主存储器606。主存储器606中包含的指令序列的执行使得处理器604执行在本文中所描述的过程步骤。在替代实施例中,可以使用硬连线电路来代替软件指令或与软件指令结合使用。

在本文中所使用的术语“存储介质”指的是存储导致机器以特定方式操作的数据和/或指令的任何非暂时性介质。这种存储介质可以包括非易失性介质和/或易失性介质。非易失性介质包括例如光盘、磁盘或固态驱动器(例如,存储设备610)。易失性介质包括动态存储器,例如主存储器606。常见形式的存储介质包括,例如,软盘、软磁盘、硬盘、固态驱动器、磁带或任何其他磁性数据存储介质、CD-ROM、任何其他光学数据存储介质、具有孔图案的任何物理介质、RAM、PROM和EPROM、FLASH-EPROM、NVRAM、任何其他存储器芯片或磁带盒。

存储介质不同于传输介质,但是可以与传输介质结合使用。传输介质参与存储介质之间的信息传输。例如,传输介质包括同轴电缆、铜线和光纤,包括具有总线602的电线。传输介质也可以采取声波或光波的形式,例如在无线电波和红外数据通信中生成的声波或光波。

在将一个或多个指令的一个或多个序列传送到处理器604以供执行时,可以涉及各种形式的介质。例如,指令最初可能被携带在远程计算机的磁盘或固态驱动器上。远程计算机可以将指令加载到其动态存储器中,并且使用调制解调器通过电话线发送指令。计算机系统600本地的调制解调器可以接收电话线上的数据,并且使用红外转换器将数据转换为红外信号。红外检测器可以接收红外信号中携带的数据,并且适当的电路可以将数据放置在总线602上。总线602将数据传送到主存储器606,处理器604从其取回并且执行指令。主存储器606接收的指令可选地在处理器604执行之前或之后存储在存储设备610上。

计算机系统600还包括耦合到总线602的通信接口618。通信接口618提供到连接到本地网络622的网络链路620的双向数据通信耦合。例如,通信接口618可以是集成服务数字网络(ISDN)卡、电缆调制解调器、卫星调制解调器或调制解调器,以提供到对应类型的电话线的数据通信连接。作为另一示例,通信接口618可以是局域网(LAN)卡,以提供到兼容LAN的数据通信连接。无线链路也可以在任何这样的实现方式中实现,通信接口618发送和接收携带表示各种类型信息的数字数据流的电、电磁或光信号。

网络链路620通常通过一个或多个网络向其他数据设备提供数据通信。例如,网络链路620可以通过本地网络622提供到主机计算机624或到由互联网服务提供商(ISP)626操作的数据设备的连接。ISP 626又通过现在通常被称为“互联网”628的全球分组数据通信网络提供数据通信服务。本地网络622和互联网628都使用携带数字数据流的电、电磁或光信号。将数字数据传送到/自计算机系统600的通过各种网络的信号以及在网络链路620上和通过通信接口618的信号是传输介质的示例性形式。

计算机系统600可以通过网络、网络链路620和通信接口618发送消息和接收数据,包括程序代码。在互联网示例中,服务器630可以通过互联网628、ISP 626、本地网络622和通信接口618传输应用程序的请求代码。

接收到的代码可以在被接收时由处理器604执行,和/或存储在存储设备610或者其他非易失性存储设备中以供以后执行。

在前述说明书中,已经参考许多具体细节描述了本发明的实施例,这些具体细节可能因实现方式而异。因此,说明书和附图被视为说明性的而不是限制性的。本发明范围的独有和排他性指示物,以及申请人希望成为本发明范围的,是由本申请发出的权利要求集的字面和等效范围,这些权利要求以特定形式发出,包括任何随后的更正。

相关技术
  • 去蜂窝系统导频分配方法及装置
  • 一种用于去蜂窝大规模MIMO系统的导频分配方法
技术分类

06120116521457