From a5ca8df0acaec17fd44d08db72d5037ddfab98b0 Mon Sep 17 00:00:00 2001 From: Yoshiki Fujikane <40124947+ffjlabo@users.noreply.github.com> Date: Thu, 21 Nov 2024 16:58:34 +0900 Subject: [PATCH] Add detail spec for platform provider and kind in the plugin architecture (#5357) * Add details for DeployTarget Signed-off-by: Yoshiki Fujikane * Add details for Kind Signed-off-by: Yoshiki Fujikane * Small fix Signed-off-by: Yoshiki Fujikane * Small fix Signed-off-by: Yoshiki Fujikane --------- Signed-off-by: Yoshiki Fujikane --- docs/rfcs/0015-pipecd-plugin-arch-meta.md | 140 +++++++++++++++++++++- 1 file changed, 137 insertions(+), 3 deletions(-) diff --git a/docs/rfcs/0015-pipecd-plugin-arch-meta.md b/docs/rfcs/0015-pipecd-plugin-arch-meta.md index c826b85723..73d2efdffe 100644 --- a/docs/rfcs/0015-pipecd-plugin-arch-meta.md +++ b/docs/rfcs/0015-pipecd-plugin-arch-meta.md @@ -19,7 +19,7 @@ At the time this RFC is writen, there was serveral issues created on PipeCD main After this line in the documentation, pipedv1 is a mention to plugin-arch piped, while pipedv0 is a mention to up-to-now piped. -### The approach +## The approach We agreed that pipedv0 will be supported as least until the end of 2025, which mean we have to find a way to ensure our single PipeCD control plane can work with both pipedv0 and pipedv1 at the same time. That leads to this issue at [pipecd/issues/5252](https://github.com/pipe-cd/pipecd/issues/5252). @@ -27,10 +27,11 @@ The key point of the control plane supports both pipedv0 and v1 approach is: pla As at this point, we have migration plan for platform related concepts in configuration as below -**For platform provider** +### For platform provider Instead of Platform Provider, we plan to introduce the config for the plugin and define deployTargets. +**piped config** ```yaml apiVersion: pipecd.dev/v1beta1 kind: Piped @@ -48,7 +49,85 @@ spec: kubeConfigPath: ./kubeconfig-dev ``` -**For kind** +```golang +type PipedDeployTarget struct { + Name string `json:"name"` + Labels map[string]string `json:"labels,omitempty"` + Config json.RawMessage `json:"config"` +} +``` + +We also plan to deploy the app to multiple targets at once in a multicluster feature for k8s. +So, we define `DeployTargets` as an array in Application and Deployment. + +**Application** + +```proto +message Application { + reserved 3; + ... + // TODO: Add validation for this field. + string platform_provider = 15; + // + repeated string deploy_targets = 16; + ... +} +``` + +**Deployment** + +```proto +message Deployment { + reserved 4; + ... + // The name of platform provider where to deploy this application. + // This must be one of the provider names registered in the piped. + string platform_provider = 11; + + repeated string deploy_targets = 12; +} +``` + +#### For the backward compatibility + +During the migration, there might be both platform providers and deploy targets in the piped config. +So we need to convert the platform providers to deploy targets internally. + +**Refer the Platform Provider or Deploy Target** + +- If the ApplicationKind is `Application`, just use `DeployTarget` +- If the ApplicationKind is old one, convert `PlatformProvider` to `DeployTarget` + +This is a draft function. +```golang +func (s *PipedSpec) FindDeployTarget(name string, t model.ApplicationKind) (*PipedDeployTarget, bool) { + // First, check the application is supported by the plugin architecture. It means that the kind is set to "Application". + // If not, the deploy target is the platform provider. + // For backward compatibility, the deploy target is the platform provider. + if t != model.ApplicationKind_APPLICATION { + p, found := s.FindPlatformProvider(name, t) + if !found { + return &PipedDeployTarget{}, false + } + return &PipedDeployTarget{ + Name: p.Name, + Labels: p.Labels, + Config: p.Config, + }, true + } + + // If the application is supported by the plugin architecture, the deploy target is the deploy target. + for _, dt := range s.DeployTargets { + if dt.Name == name { + return dt, true + } + } + + return &PipedDeployTarget{}, false +} +``` + +### For kind Instead of Kind, we plan to introduce the label to represent the application kind. @@ -62,6 +141,61 @@ spec: name: myApp ``` +For the builtin plugins, we define 5 labels as string. +- KUBERNETES +- ECS +- LAMBDA +- CLOUDRUN +- TERRAFORM + +#### For the backward compatibility + +We need to support both before and after creating plugin architecture for now. +So, I propose the way to decide the application kind like this. + +- Define `APPLICATION` as `ApplicationKind` +- Add new method to decide the actual kind for Application and Deployment. + +```proto +enum ApplicationKind { + KUBERNETES = 0; + TERRAFORM = 1; + LAMBDA = 3; + CLOUDRUN = 4; + ECS = 5; + APPLICATION = 6; <- new! +} +``` + +**Application** + +```golang +func (a * Application) GetKind() string { + // First, check the application is supported by the plugin architecture. It means that the kind is set to "Application". + // If so, return the kind from the labels. + if a.Kind == ApplicationKind_Application { + return a.Labels["kind"] + } + + // For backward compatibility, return the kind as string + return a.Kind.String() +} +``` + +**Deployment** +```golang +func (d *Deployment) GetKind() string { + // First, check the application is supported by the plugin architecture. It means that the kind is set to "Application". + // If so, return the kind from the labels. + if d.Kind == ApplicationKind_Application { + return d.Labels["kind"] + } + + // For backward compatibility, return the kind as string + return d.Kind.String() +} +``` + The control plane will be updated so that it can accept platform provider from pipedv0 and deployTargets from pipedv1. ### The protocol