pipe-cd / pipecd

The One CD for All {applications, platforms, operations}
https://pipecd.dev
Apache License 2.0
1.09k stars 153 forks source link

Make PipeCD control plane support plugin-arched piped #5252

Open ffjlabo opened 1 month ago

ffjlabo commented 1 month ago

What would you like to be added:

This issue tracks the progress for deprecating Platform Provider and Kind toward piped plugin architecture in pipedv1.

The purpose is to manage application kind and platform providers on the PipeCD plugin side in the future.

Considering the impact on users, pay attention to the following points:

current update process

  1. Update data for the pipedv1
    • Add the label kind based on the current Application Kind to the Application.
    • Add deployTarget based on the current Application Platform Provider to the Application.
  2. update to pipedv1 (users can use existing application at the time)

Details (under planning)

For Platform Provider

Instead of Platform Provider, we plan to introduce the config for the plugin and define deployTargets.

piped config

apiVersion: pipecd.dev/v1beta1
kind: Piped
spec:
...
  plugin:
    - name: k8s_plugin
      port: 8081
      deployTargets:
        - name: dev
          labels: 
            env: dev
          config: # depends on plugins
            masterURL: http://cluster-dev
            kubeConfigPath: ./kubeconfig-dev
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

message Application {
    reserved 3;
    ...
    // TODO: Add validation for this field.
    string platform_provider = 15;
    // 
    repeated string deploy_targets = 16;
    ...
}

Deployment

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

Before updating the piped, users should migrate the current data on DB.

Former idea 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` ```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.

apiVersion: pipecd.dev/v1beta1
kind: Application
metadata:
  labels:
    kind: KUBERNETES # <- like this
spec:
  name: myApp

For the builtin plugins, we define 5 labels as string.

For the backward compatibility

Before updating the piped, users should migrate the current data on DB.

Former idea 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! } ``` ```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() } ``` ```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() } ```

TODO

Firstly, I listed the target features to require some modifications. We need to further investigation to decide the way to fix.

investigation

implementation

Why is this needed:

ffjlabo commented 1 month ago

Platform Provider; Livestatestore

The purpose of the component

Modification idea

ffjlabo commented 1 month ago

Platform Provider; Livestatereporter

The purpose of the component

Modification idea

Concern

ffjlabo commented 1 month ago

Platform Provider; Detector

The purpose of the component

Modification idea

Concern

ffjlabo commented 3 weeks ago

Platform Provider; Plan Preview

The purpose of the component

Modification idea

Concern

ffjlabo commented 3 weeks ago

Platform Provider; Metrics

The metrics deployment_status is affected because it has the label platform_provider. https://github.com/pipe-cd/pipecd/blob/548a804d344d7c5faa70bcb6bd0889aa2a9269af/pkg/app/piped/controller/controllermetrics/metrics.go#L23C1-L40C2

deployment_status{application_id="xxxxxxxx",application_kind="KUBERNETES",application_name="simple",deployment="xxxxxxx",instance="127.0.0.1:9085",job="pipecd-ops",launcher_version="v0.49.2",pipecd_component="piped",piped="xxxxx",piped_version="v0.49.2",platform_provider="kubernetes",project="test",status="DEPLOYMENT_CANCELLED"}

Modification idea There are two ideas.

  1. Create new metrics like plugin_deployment_status
  2. Add a new label deployTarget to the deployment_status

Concern

For idea 1.

For idea 2.

ffjlabo commented 3 weeks ago

Kind; appconfigreporter

The purpose of the component

Modification idea

Concern

ffjlabo commented 3 weeks ago

Kind; event watcher

The purpose of the component

Modification Idea

ffjlabo commented 2 weeks ago

Kind; livestatereporter

The purpose of the component

Modification Idea

message ApplicationLiveStateSnapshot {
    reserved 2;
    ...
    ApplicationKind kind = 5 [(validate.rules).enum.defined_only = true];
    ...
    string plugin_kind = 16;
}
ffjlabo commented 2 weeks ago

Kind; detector

The purpose of the component

Modification idea

ffjlabo commented 2 weeks ago

Kind; notifier

The purpose of the component

Modification idea

ffjlabo commented 2 weeks ago

Kind; Plan preview

The purpose of the component

Modification idea

ffjlabo commented 1 week ago

Kind; trigger

Modification idea

ffjlabo commented 6 days ago

Kind; server

The purpose of the component

Modification idea

ffjlabo commented 6 days ago

Kind; Metrics

The purpose of the component The metrics deployment_status is affected because it has the label application_kind. https://github.com/pipe-cd/pipecd/blob/548a804d344d7c5faa70bcb6bd0889aa2a9269af/pkg/app/piped/controller/controllermetrics/metrics.go#L23C1-L40C2

deployment_status{application_id="xxxxxxxx",application_kind="KUBERNETES",application_name="simple",deployment="xxxxxxx",instance="127.0.0.1:9085",job="pipecd-ops",launcher_version="v0.49.2",pipecd_component="piped",piped="xxxxx",piped_version="v0.49.2",platform_provider="kubernetes",project="test",status="DEPLOYMENT_CANCELLED"}

Modification idea

ffjlabo commented 6 days ago

Kind; planner

The purpose of the component

Modification idea

ffjlabo commented 6 days ago

Kind; scheduler

The purpose of the component

Modification idea

khanhtc1202 commented 5 days ago

PlatformProvider; UI

Purpose

Mostly related to 2 model applications and deployment

Used in

The source fetched to used in the drawer is come from the piped configuration

https://github.com/pipe-cd/pipecd/blob/master/web/src/components/application-form/index.tsx#L58-L80

Modification idea