Spinnaker第十节—如何开发一个新环节

前面几篇比较枯燥的介绍了orca、clouddriver、deck目录结构和核心代码,本篇将会作为这一系列的终篇为大家分享下如何在spinnaker中开发一个自定义的环节。

需求背景:

Spinnaker对于镜像自带了FindImageByTags环节,可以让我们在pipeline中通过tag为条件选中想要发布的镜像,流转到后续的deploy环节。但是腾讯云镜像不支持tag功能,所以为了达到同样的效果我们需要自开发一个findImageByName环节。

开发deck-(angular)

1 core部分:

   说明:core解决的是parent级别的环节问题,每个环节都必须从parent中继承,因为本次开发的环节是全新环节,parent也没有,所以需要先修改core

1.1 先从core中添加parent环节:

       modules\core\src\pipeline\config\stages\findImageFromName

       以及相关的文件findImageFromNameStage.js 和 findImageFromNameStage.module.js

1.2 修改stageConstants (个人觉得可能不是必须的)

       modules\core\src\pipeline\config\stages\stageConstants.ts

       修改IMAGE_PRODUCING_STAGES部分

1.3 修改pipeline.module注册

       modules\core\src\pipeline\pipeline.module.ts

1.4 修改Deploy环节的前置条件

       modules\core\src\pipeline\config\stages\deploy\deployStage.js

       因为deploy环节需要输入一个镜像id作为环节的前置条件,目前已知的有findImageByTag和bake,本次添加的环节也属于deploy的前置条件,所以此处需要修改。关键字"stageBeforeType"

2 tencent部分:

说明:解决的是厂商sub级别的环节问题,只有注册过的环节才可以在deck中被看到

2.1 厂商实现core中剩余部分

       modules\tencent\src\pipeline\stages\findImageFromName

       以及相关文件:

       tencentFindImageFromNameStage.js 自定义注册

       findImageFromNameExecutionDetails.html pipeline中看到的页面

       findImageFromNameStage.html stage的详细页面

2.2 添加进厂商配置文件

       modules\tencent\src\tencent.module.ts

3 前端效果

   到目前位置可以重启deck,可以看到基本的效果了。

4 核心问题思考

Q1:stage页面中,初始数据从哪来?

A1:两层:

       第一层:modules\core\src\pipeline\config\stages\stage.module.js中controller('StageConfigCtrl')

       第二层:modules\tencent\src\pipeline\stages\findImageFromName\tencentFindImageFromNameStage.js中又设置了一次,基本就是透传的第一层

   第一层没找到,合理的猜测:pipeline执行后相关的json保留在了redis中,所以此处不需要关心,先忽略。

Q2:stage的表单最终提交到哪里去?

A2:通过API这个module调用了gateway流入到了orca中,后面重点会去开发orca

 

开发orca-(java+groovy)

1 先开发公共部分:

1.1 先创建一个对应的stage

       FindImageFromNameStage.java,内容很简单,对task的组装,因为task对我们来说也是新的,所以要自己再创建task。

       注意:stage一定要实现StageDefinitionBuilder,具体原因后面详解

1.2 再创建一个对应的task

       FindImageFromNameTask.java 需要继承AbstractCloudProviderAwareTask并根据是否可以重复执行选择性的实现RetryableTask

       跟入AbstractCloudProviderAwareTask中

       abstract class AbstractCloudProviderAwareTask implements CloudProviderAware, Task {}

       其中CloudProviderAware中都有default的实现,此处可以暂时不管;

       Task中TaskResult execute(@Nonnull Stage stage)方法需要实现掉

1.3 扩展Reader和Writer

       发现task最终调用的Reader和Writer来做的业务处理,但是现有的接口方法不支持我的业务,所以需要添加方法,进行扩展.

       注意扩展时给自己新方法添加default实现,不要影响现有功能。

2 再开发云厂商部分

       云厂商实现在com\netflix\spinnaker\orca\clouddriver\tasks\providers下

3 核心问题思考

Q:deck中环节如何与orca映射起来的?

A:前文说过stage一定要实现StageDefinitionBuilder,核心代码在StageDefinitionBuilder中getType方法:

static String getType(Class<? extends StageDefinitionBuilder> clazz) {
   String className = clazz.getSimpleName();
   return className.substring(0, 1).toLowerCase() + className.substring(1).replaceFirst("StageDefinitionBuilder$", "").replaceFirst("Stage$", "");
}

然后DefaultStageDefinitionBuilderFactory中builderFor方法:

@Override
public @Nonnull StageDefinitionBuilder builderFor(
   @Nonnull Stage stage) throws NoSuchStageDefinitionBuilder {
   return stageDefinitionBuilders
     .stream()
     .filter((it) -> it.getType().equals(stage.getType()) || it.getType().equals(stage.getContext().get("alias")))
     .findFirst()
     .orElseThrow(() -> {
       List<String> knownTypes = stageDefinitionBuilders.stream().map(it -> it.getType()).sorted().collect(toList());
       return new NoSuchStageDefinitionBuilder(stage.getType(), knownTypes);
     });
}

其中stageDefinitionBuilders来在springIoc框架,所有子类或实现类的集合

private final Collection<StageDefinitionBuilder> stageDefinitionBuilders;

总结:只要实现了stageDefinitionBuilders并且按照命名规则定义类名,就会被认为是后端的一个stage。

 

开发clouddriver-(groovy)

1 controller层修改

找到orca中reader请求clouddriver的restful对应的controller,根据业务需求选择原基础上改造还是重新做一个restful入口

TencentNamedImageLookupController

2 编写核心业务逻辑

本次涉及到的是镜像查询逻辑变更,查询是直接从cache中获取的,cache的存储逻辑在TencentImageCachingAgent,根据需求进行改造,在查找后需要按照orca接收的json格式进行封装。

 

FindImageByName环节代码列表:

Deck:

新增:

   modules/core/src/pipeline/config/stages/findImageFromName/findImageFromNameStage.js

   modules/core/src/pipeline/config/stages/findImageFromName/findImageFromNameStage.module.js

   modules/tencent/src/pipeline/stages/findImageFromName/findImageFromNameStage.html

   modules/tencent/src/pipeline/stages/findImageFromName/findImageFromNameExecutionDetails.html

   modules/tencent/src/pipeline/stages/findImageFromName/tencentFindImageFromNameStage.js

修改:

   modules/core/src/pipeline/config/stages/deploy/deployStage.js

   modules/tencent/src/aws.module.ts

   modules/core/src/pipeline/config/stages/stageConstants.ts

   modules/core/src/pipeline/pipeline.module.ts

Orca:

新增:

   com.netflix.spinnaker.orca.clouddriver.pipeline.image.FindImageFromNameStage.java

   com.netflix.spinnaker.orca.clouddriver.tasks.image.FindImageFromNameTask.java

   com.netflix.spinnaker.orca.clouddriver.tasks.providers.tencent.TencentImageFinder.groovy

修改:

   com.netflix.spinnaker.orca.clouddriver.tasks.image.ImageFinder.java

CloudDriver:

新增:

   com.netflix.spinnaker.clouddriver.tencent.controllers.TencentNamedImageLookupController.groovy

修改:

   com.netflix.spinnaker.clouddriver.tencent.provider.agent.TencentImageCachingAgent.groovy

 

本文的项目地址:https://github.com/spinnaker-cn

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值