Salt Cloud在类似于主Salt项目的模块系统上运行。 saltcloud内部的模块位于salt源码的salt/cloud/clouds
目录中。
有两种基本类型的云模块。 如果云平台主机支持libcloud,则使用它是编写模块的最快方法。 Apache Libcloud项目位于:
http://libcloud.apache.org/
不是所有的云平台主机都受libcloud支持。 此外,libcloud不一定支持受支持的云平台主机中的所有功能。 在这两种情况下,都可以选择创建不依赖libcloud的模块。
您也可以参考在Github上维护的这一份技术资料:Extending Salt Cloud - Adding Cloud Providers
All Driver Modules - 所有驱动程序都需要实现的函数
所有驱动程序模块都需要以下功能,无论它们是否基于libcloud实现的。
The virtual() Function
此功能确定在执行时使该云模块是否可用。 通常,它使用get_configured_provider()
来确定是否已设置必要的配置。 它还可以检查必要的导入,以决定是否加载模块。 在大多数情况下,它将返回True或False值。 如果使用的驱动程序名称与文件名不匹配,则应返回该名称而不是True。 在Azure模块中可以看到一个示例:
https://github.com/saltstack/salt/tree/develop/salt/cloud/clouds/msazure.py
The get_configured_provider() Function
此函数使用config.is_provider_configured()
确定是否已为此驱动程序配置了所有必需的信息。 所需设置列表中的最后一个值应跟逗号。
Libcloud Based Modules - 基于Libcloud实现的函数
基于libcloud编写云模块有两个主要优点。 首先,libcloud项目已经完成了许多基础工作。 其次,Salt所需的大多数功能已经添加到Salt Cloud项目中。
The create() Function
需要手动编写的最重要的函数是create()
函数。 这是用于请求由云主机创建虚拟机并等待其可用,然后(可选)登录并在其上安装Salt的方法。
下面为Linode提供的模块是编写基于libcloud的云驱动程序模块的一个很好的例子:
https://github.com/saltstack/salt/tree/develop/salt/cloud/clouds/linode.py
create()函数的基本流程如下:
- 向云主机发送请求以创建虚拟机。
- 等待虚拟机可用。
- 生成用于部署Salt的kwarg。
- 登录到虚拟机并部署Salt。
- 返回描述新创建的虚拟机的数据结构。
在此功能函数的各个阶段,事件可能会在Salt事件总线上触发。这些事件中有四个是必需的,如下所述。用户可以在适当的地方添加其他事件。
调用create()
函数时,将传递一个名为vm_
的数据结构。该字典变量中包含描述要创建的虚拟机的信息的组合。 Salt还提供了一个称为__opts__
的字典,其中包含用于运行Salt Cloud的选项以及一组配置和环境变量。
create()
函数必须做的第一件事是触发一个事件,指出它已开始创建过程。该事件被标记为salt/cloud/<vm name>/creating
。有效负载包含VM、配置文件和驱动程序的名称。
然后通常会创建一组kwargs,以描述云主机请求虚拟机所需的参数。
然后触发一个事件,指出将要请求虚拟机。它被标记为salt/cloud/<vm name>/requesting
。有效负载包含将发送到云主机的大多数或所有参数。任何私人信息(例如密码)都不应在事件中发送。
发出请求后,将生成一组部署Kwargs。这些将用于在目标计算机上安装Salt。此时支持Windows选项,即使云主机当前不支持Windows,也应生成Windows选项。如果主机最终决定支持Windows,则这将节省将来的时间。
然后触发一个事件,指出部署过程即将开始。该事件被标记为salt/cloud/<vm name>/deploying
。事件的有效负载将包含一组部署Kwargs,可用于有目的的调试。在触发事件之前,应从部署参数删除所有私人数据,包括密码和密钥(包括公共密钥)。
如果传递了任何Windows选项,则将调用salt.utils.cloud.deploy_windows()
函数。否则,将假定目标是Linux或Unix计算机,并调用salt.utils.cloud.deploy_script()
。
这两个功能都将等待目标计算机可用,然后等待登录所需的端口,然后成功登录即可用于安装Salt。Minion配置和密钥随后将通过适当的功能上传到目标上的临时目录。在Windows目标主机上,Windows Minion Installer将以静默模式运行。在Linux/Unix目标上,将运行部署脚本(默认情况下为bootstrap-salt.sh
),该脚本将自动检测操作系统,并使用其本机软件包管理器安装Salt。这些不需要由云模块中的开发人员处理。
扩展了salt.utils.cloud.validate_windows_cred()
函数,以获取重试和retry_delay参数的数量,以防特定的云主机在提供Windows凭据和可用凭据之间存在延迟。在其create()
函数中,或作为在创建过程中调用的子函数,开发人员应使用驱动程序配置中的win_deploy_auth_retries
和win_deploy_auth_retry_delay
参数,以使最终用户能够为了他们的特定主机自定义尝试次数和尝试之间的延迟。
当部署功能完成后,将触发一个最终事件,该事件描述了刚刚创建的虚拟机。该事件被标记为salt/cloud/<vm name>/created
。有效负载包含VM、profile配置文件和provider驱动程序的名称。
最后,将描述新虚拟机的字典信息(从provider处查询)返回给用户。由于此数据未在事件总线上触发,因此它可以并且应该返回云主机返回的所有密码。在某些情况下(例如,Rackspace),这是用户唯一一次可以查询密码的时间。创建后的查询可能不会包含密码信息(这取决于主机)。
The libcloudfuncs Functions
所有云主机都需要许多其他功能。 但是,对于基于libcloud的模块,这些全部由libcloudfuncs库免费提供。 以下两行设置了导入:
from salt.cloud.libcloudfuncs import * # pylint: disable=W0614,W0401
import salt.utils.functools
然后,一系列调用声明将使必要的功能函数在云模块中可用。
get_size = salt.utils.functools.namespaced_function(get_size, globals())
get_image = salt.utils.functools.namespaced_function(get_image, globals())
avail_locations = salt.utils.functools.namespaced_function(avail_locations, globals())
avail_images = salt.utils.functools.namespaced_function(avail_images, globals())
avail_sizes = salt.utils.functools.namespaced_function(avail_sizes, globals())
script = salt.utils.functools.namespaced_function(script, globals())
destroy = salt.utils.functools.namespaced_function(destroy, globals())
list_nodes = salt.utils.functools.namespaced_function(list_nodes, globals())
list_nodes_full = salt.utils.functools.namespaced_function(list_nodes_full, globals())
list_nodes_select = salt.utils.functools.namespaced_function(list_nodes_select, globals())
show_instance = salt.utils.functools.namespaced_function(show_instance, globals())
如有必要,可以通过删除相应的声明行,然后正常添加函数来替换这些函数的实现。
所有云模块都需要这些功能函数,下一节将对其进行详细描述。
Non-Libcloud Based Modules - 非基于Libcloud库实现的功能函数
在某些情况下,不能选择使用libcloud。 这可能是因为libcloud尚未包含必需的驱动程序本身,或者可能是libcloud随附的驱动程序未包含开发人员所需的所有必需功能。 在这种情况下,可以替换libcloudfuncs中的部分或全部功能。 如果已全部替换,则应从Salt Cloud模块中缺少libcloud导入。
非libcloud驱动程序的一个很好的例子是DigitalOcean驱动程序:
https://github.com/saltstack/salt/tree/develop/salt/cloud/clouds/digitalocean.py
The create() Function
必须按照基于libcloud的模块文档中的说明创建create()函数。
The get_size() Function
此功能仅对于基于libcloud的模块是必需的,否则不需要存在。
The get_image() Function
此功能仅对于基于libcloud的模块是必需的,否则不需要存在。
The avail_locations() Function
如果云主机使用多个数据中心,则此函数返回可用位置的列表。 如果云主机仅使用一个数据中心,则没有必要。 通常使用–list-locations选项调用它。
salt-cloud --list-locations my-cloud-provider
The avail_images() Function
此函数返回可用于该云服务商的镜像列表。 当前尚没有任何不提供此功能的已知云提供商,尽管它们可能引用了不同名称的镜像(例如,“模板”)。 通常使用–list-images选项调用它。
salt-cloud --list-images my-cloud-provider
The avail_sizes() Function
此函数返回可用于该云服务商的配置规格大小的列表。 通常,这是指RAM、CPU和/或磁盘空间的组合。 某些云服务商可能没有此功能。 例如,Parallels模块将RAM、CPU和磁盘空间分解为单独的选项,而在其他驱动程序中,这些选项被嵌入到映像中。 通常使用–list-sizes选项调用它。
salt-cloud --list-sizes my-cloud-provider
The script() Function
此功能可构建需要在远程计算机上使用的部署脚本。 它很通用,很可能会在不久的将来移入salt.utils.cloud
库,通常这可以从另一个模块中批量复制使用。 一个很好的例子是Azure驱动程序。
The destroy() Function
此功能不可逆地销毁云平台上的虚拟机。 在这样做之前,它会在Salt事件总线上触发一个事件。 该事件的标签为salt/cloud/<vm name>/destroying
。 虚拟机销毁后,将触发另一个事件。 该事件的标签为salt/cloud/<vm name>/destroyed
。
通常使用-d选项调用此函数:
salt-cloud -d myinstance
The list_nodes() Function
此函数使用以下字段返回此云驱动程序上可用的节点列表:
- id (str)
- image (str)
- size (str)
- state (str)
- private_ips (list)
- public_ips (list)
此函数中不应返回任何其他字段,并且即使所有字段为空,也应返回所有这些字段。 即使为空,private_ips和public_ips字段也应始终为列表类型,其他字段应始终为str类型。 通常使用-Q选项调用此函数:
salt-cloud -Q
The list_nodes_full() Function
有关所有节点的所有可用信息都应在此函数中返回。 即使通常不由云提供商提供,也应返回list_nodes()函数中的字段。 这是因为如果没有期望的字段,Salt和3rd Party中的某些功能都会中断。 通常使用-F选项调用此函数:
salt-cloud -F
The list_nodes_select() Function
此函数仅返回/etc/salt/cloud
中query.selection
选项中指定的字段。 由于此功能是如此通用,因此所有繁重的工作都已移至salt.utils.cloud库中。
仍然需要存在一个调用list_nodes_select()
的函数。 通常,以下代码可以按原样使用:
def list_nodes_select(call=None):
'''
Return a list of the VMs that are on the provider, with select fields
'''
return salt.utils.cloud.list_nodes_select(
list_nodes_full('function'), __opts__['query.selection'], call,
)
但是,这取决于云提供商,可能会需要其他变量。 例如,某些模块使用conn对象,或者可能需要将其他选项传递到list_nodes_full()中。 在这种情况下,请确保适当地更新功能:
def list_nodes_select(conn=None, call=None):
'''
Return a list of the VMs that are on the provider, with select fields
'''
if not conn:
conn = get_conn() # pylint: disable=E0602
return salt.utils.cloud.list_nodes_select(
list_nodes_full(conn, 'function'),
__opts__['query.selection'],
call,
)
通常使用-S选项调用此函数:
salt-cloud -S
The show_instance() Function
此功能用于显示可从云提供商处获得的有关单个节点的所有信息。 提供此功能的最简单方法通常是调用list_nodes_full(),并仅返回所请求节点的数据。 通常称为action:
salt-cloud -a show_instance myinstance
Actions and Functions
可以以--action
或--function
的形式将额外的功能添加到云提供商。 针对云实例/虚拟机执行actions,针对云提供商执行functions。
Actions
Actions是针对特定实例或虚拟机执行的调用。 show_instance
操作应在所有云模块中可用。 通常使用-a
选项调用actions:
salt-cloud -a show_instance myinstance
Actions必须接受name
作为第一个参数,可以视情况选择支持任意数量的kwargs,并且必须接受call
参数,默认值为None
。
在执行任何其他工作之前,通常应先执行一项操作以验证它已被正确调用。 然后,它可以执行所需的功能,并将有用的信息返回给用户。 基本动作如下:
def show_instance(name, call=None):
'''
Show the details from EC2 concerning an AMI
'''
if call != 'action':
raise SaltCloudSystemExit(
'The show_instance action must be called with -a or --action.'
)
return _get_node(name)
请注意,一般的kwargs(如果使用)会以kwargs
而不是**kwargs
的形式传递给动作。 在Functions部分中可以看到一个示例。
Functions
调用针对特定云提供商执行的管理功能。 通常有用的可选功能是show_image
,它详细描述了镜像。 通常使用-f
选项调用函数:
salt-cloud -f show_image my-cloud-provider image='Ubuntu 13.10 64-bit'
函数可以接受任意数量的kwargs,并且必须接受默认值为None
的call
参数。
在执行任何其他工作之前,函数通常应验证是否已正确调用它。 然后,它可以执行所需的功能,并将有用的信息返回给用户。 基本功能如下:
def show_image(kwargs, call=None):
'''
Show the details from EC2 concerning an AMI
'''
if call != 'function':
raise SaltCloudSystemExit(
'The show_image action must be called with -f or --function.'
)
params = {'ImageId.1': kwargs['image'],
'Action': 'DescribeImages'}
result = query(params)
log.info(result)
return result
请注意,通用kwargs通过kwargs
传递给函数,而不是**kwargs
。