Skip to content

Commit 936879c

Browse files
Warashit-kikuc
andauthored
Prepare Plugin SDK (#5529)
* Add initial implementation of pipedsdk for PipeCD plugins Signed-off-by: Shinnosuke Sawada-Dazai <[email protected]> * Implement pipedsdk client and deployment plugin interfaces Signed-off-by: Shinnosuke Sawada-Dazai <[email protected]> * Add version support and common fields to deployment and pipeline sync plugins Signed-off-by: Shinnosuke Sawada-Dazai <[email protected]> * Refactor pipedsdk deployment and sdk packages for improved code organization Signed-off-by: Shinnosuke Sawada-Dazai <[email protected]> * Enhance pipedsdk client and deployment plugin interfaces with additional identification fields and unimplemented method stubs Signed-off-by: Shinnosuke Sawada-Dazai <[email protected]> * Update piped-plugin-service flag description for clarity Signed-off-by: Shinnosuke Sawada-Dazai <[email protected]> * Add clarification to DeploymentPlugin interface regarding Config parameter Signed-off-by: Shinnosuke Sawada-Dazai <[email protected]> * Apply suggestions from code review Co-authored-by: Tetsuya KIKUCHI <[email protected]> Signed-off-by: Shinnosuke Sawada-Dazai <[email protected]> * Fix build Signed-off-by: Shinnosuke Sawada-Dazai <[email protected]> * Update copyright notice year Signed-off-by: Shinnosuke Sawada-Dazai <[email protected]> --------- Signed-off-by: Shinnosuke Sawada-Dazai <[email protected]> Co-authored-by: Tetsuya KIKUCHI <[email protected]>
1 parent 2b78122 commit 936879c

File tree

3 files changed

+410
-0
lines changed

3 files changed

+410
-0
lines changed

pkg/plugin/pipedsdk/client.go

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2025 The PipeCD Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package pipedsdk
16+
17+
import "github.com/pipe-cd/pipecd/pkg/plugin/pipedapi"
18+
19+
// Client is a toolkit for interacting with the piped service.
20+
// It provides methods to call the piped service APIs.
21+
// It's a wrapper around the raw piped service client.
22+
type Client struct {
23+
base *pipedapi.PipedServiceClient
24+
25+
// applicationID is used to identify the application that the client is working with.
26+
applicationID string
27+
// deploymentID is used to identify the deployment that the client is working with.
28+
// This field exists only when the client is working with a specific deployment; for example, when this client is passed as the deployoment plugin's argument.
29+
deploymentID string
30+
// stageID is used to identify the stage that the client is working with.
31+
// This field exists only when the client is working with a specific stage; for example, when this client is passed as the ExecuteStage method's argument.
32+
stageID string
33+
}

pkg/plugin/pipedsdk/deployment.go

+181
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// Copyright 2025 The PipeCD Authors.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package pipedsdk
16+
17+
import (
18+
"context"
19+
20+
"go.uber.org/zap"
21+
"google.golang.org/grpc"
22+
"google.golang.org/grpc/codes"
23+
"google.golang.org/grpc/status"
24+
25+
config "github.com/pipe-cd/pipecd/pkg/configv1"
26+
"github.com/pipe-cd/pipecd/pkg/plugin/api/v1alpha1/deployment"
27+
"github.com/pipe-cd/pipecd/pkg/plugin/logpersister"
28+
"github.com/pipe-cd/pipecd/pkg/plugin/pipedapi"
29+
)
30+
31+
var (
32+
deploymentServiceServer interface {
33+
Plugin
34+
35+
Register(server *grpc.Server)
36+
setCommonFields(commonFields)
37+
deployment.DeploymentServiceServer
38+
}
39+
)
40+
41+
// DeploymentPlugin is the interface that be implemented by a full-spec deployment plugin.
42+
// This kind of plugin should implement all methods to manage resources and execute stages.
43+
// The Config parameter is the plugin's config defined in piped's config.
44+
type DeploymentPlugin[Config any] interface {
45+
PipelineSyncPlugin[Config]
46+
47+
// DetermineVersions determines the versions of the resources that will be deployed.
48+
DetermineVersions(context.Context, *Config, *Client, TODO) (TODO, error)
49+
// DetermineStrategy determines the strategy to deploy the resources.
50+
DetermineStrategy(context.Context, *Config, *Client, TODO) (TODO, error)
51+
// BuildQuickSyncStages builds the stages that will be executed during the quick sync process.
52+
BuildQuickSyncStages(context.Context, *Config, *Client, TODO) (TODO, error)
53+
}
54+
55+
// PipelineSyncPlugin is the interface implemented by a pipeline sync plugin.
56+
// This kind of plugin may not implement quick sync stages, and will not manage resources like deployment plugin.
57+
// It only focuses on executing stages which is generic for all kinds of pipeline sync plugins.
58+
type PipelineSyncPlugin[Config any] interface {
59+
Plugin
60+
61+
// FetchDefinedStages returns the list of stages that the plugin can execute.
62+
FetchDefinedStages() []string
63+
// BuildPipelineSyncStages builds the stages that will be executed by the plugin.
64+
BuildPipelineSyncStages(context.Context, *Config, *Client, TODO) (TODO, error)
65+
// ExecuteStage executes the given stage.
66+
ExecuteStage(context.Context, *Config, *Client, logpersister.StageLogPersister, TODO) (TODO, error)
67+
}
68+
69+
// RegisterDeploymentPlugin registers the given deployment plugin.
70+
// It will be used when running the piped.
71+
func RegisterDeploymentPlugin[Config any](plugin DeploymentPlugin[Config]) {
72+
deploymentServiceServer = &DeploymentPluginServiceServer[Config]{base: plugin}
73+
}
74+
75+
// RegisterPipelineSyncPlugin registers the given pipeline sync plugin.
76+
// It will be used when running the piped.
77+
func RegisterPipelineSyncPlugin[Config any](plugin PipelineSyncPlugin[Config]) {
78+
deploymentServiceServer = &PipelineSyncPluginServiceServer[Config]{base: plugin}
79+
}
80+
81+
type logPersister interface {
82+
StageLogPersister(deploymentID, stageID string) logpersister.StageLogPersister
83+
}
84+
85+
type commonFields struct {
86+
config *config.PipedPlugin
87+
logger *zap.Logger
88+
logPersister logPersister
89+
client *pipedapi.PipedServiceClient
90+
}
91+
92+
// DeploymentPluginServiceServer is the gRPC server that handles requests from the piped.
93+
type DeploymentPluginServiceServer[Config any] struct {
94+
deployment.UnimplementedDeploymentServiceServer
95+
commonFields
96+
97+
base DeploymentPlugin[Config]
98+
}
99+
100+
// Name returns the name of the plugin.
101+
func (s *DeploymentPluginServiceServer[Config]) Name() string {
102+
return s.base.Name()
103+
}
104+
105+
func (s *DeploymentPluginServiceServer[Config]) Version() string {
106+
return s.base.Version()
107+
}
108+
109+
// Register registers the server to the given gRPC server.
110+
func (s *DeploymentPluginServiceServer[Config]) Register(server *grpc.Server) {
111+
deployment.RegisterDeploymentServiceServer(server, s)
112+
}
113+
114+
func (s *DeploymentPluginServiceServer[Config]) setCommonFields(fields commonFields) {
115+
s.commonFields = fields
116+
}
117+
118+
func (s *DeploymentPluginServiceServer[Config]) FetchDefinedStages(context.Context, *deployment.FetchDefinedStagesRequest) (*deployment.FetchDefinedStagesResponse, error) {
119+
return &deployment.FetchDefinedStagesResponse{Stages: s.base.FetchDefinedStages()}, nil
120+
}
121+
func (s *DeploymentPluginServiceServer[Config]) DetermineVersions(context.Context, *deployment.DetermineVersionsRequest) (*deployment.DetermineVersionsResponse, error) {
122+
return nil, status.Errorf(codes.Unimplemented, "method DetermineVersions not implemented")
123+
}
124+
func (s *DeploymentPluginServiceServer[Config]) DetermineStrategy(context.Context, *deployment.DetermineStrategyRequest) (*deployment.DetermineStrategyResponse, error) {
125+
return nil, status.Errorf(codes.Unimplemented, "method DetermineStrategy not implemented")
126+
}
127+
func (s *DeploymentPluginServiceServer[Config]) BuildPipelineSyncStages(context.Context, *deployment.BuildPipelineSyncStagesRequest) (*deployment.BuildPipelineSyncStagesResponse, error) {
128+
return nil, status.Errorf(codes.Unimplemented, "method BuildPipelineSyncStages not implemented")
129+
}
130+
func (s *DeploymentPluginServiceServer[Config]) BuildQuickSyncStages(context.Context, *deployment.BuildQuickSyncStagesRequest) (*deployment.BuildQuickSyncStagesResponse, error) {
131+
return nil, status.Errorf(codes.Unimplemented, "method BuildQuickSyncStages not implemented")
132+
}
133+
func (s *DeploymentPluginServiceServer[Config]) ExecuteStage(context.Context, *deployment.ExecuteStageRequest) (*deployment.ExecuteStageResponse, error) {
134+
return nil, status.Errorf(codes.Unimplemented, "method ExecuteStage not implemented")
135+
}
136+
137+
// PipelineSyncPluginServiceServer is the gRPC server that handles requests from the piped.
138+
type PipelineSyncPluginServiceServer[Config any] struct {
139+
deployment.UnimplementedDeploymentServiceServer
140+
commonFields
141+
142+
base PipelineSyncPlugin[Config]
143+
}
144+
145+
// Name returns the name of the plugin.
146+
func (s *PipelineSyncPluginServiceServer[Config]) Name() string {
147+
return s.base.Name()
148+
}
149+
150+
// Version returns the version of the plugin.
151+
func (s *PipelineSyncPluginServiceServer[Config]) Version() string {
152+
return s.base.Version()
153+
}
154+
155+
// Register registers the server to the given gRPC server.
156+
func (s *PipelineSyncPluginServiceServer[Config]) Register(server *grpc.Server) {
157+
deployment.RegisterDeploymentServiceServer(server, s)
158+
}
159+
160+
func (s *PipelineSyncPluginServiceServer[Config]) setCommonFields(fields commonFields) {
161+
s.commonFields = fields
162+
}
163+
164+
func (s *PipelineSyncPluginServiceServer[Config]) FetchDefinedStages(context.Context, *deployment.FetchDefinedStagesRequest) (*deployment.FetchDefinedStagesResponse, error) {
165+
return &deployment.FetchDefinedStagesResponse{Stages: s.base.FetchDefinedStages()}, nil
166+
}
167+
func (s *PipelineSyncPluginServiceServer[Config]) DetermineVersions(context.Context, *deployment.DetermineVersionsRequest) (*deployment.DetermineVersionsResponse, error) {
168+
return nil, status.Errorf(codes.Unimplemented, "method DetermineVersions not implemented")
169+
}
170+
func (s *PipelineSyncPluginServiceServer[Config]) DetermineStrategy(context.Context, *deployment.DetermineStrategyRequest) (*deployment.DetermineStrategyResponse, error) {
171+
return nil, status.Errorf(codes.Unimplemented, "method DetermineStrategy not implemented")
172+
}
173+
func (s *PipelineSyncPluginServiceServer[Config]) BuildPipelineSyncStages(context.Context, *deployment.BuildPipelineSyncStagesRequest) (*deployment.BuildPipelineSyncStagesResponse, error) {
174+
return nil, status.Errorf(codes.Unimplemented, "method BuildPipelineSyncStages not implemented")
175+
}
176+
func (s *PipelineSyncPluginServiceServer[Config]) BuildQuickSyncStages(context.Context, *deployment.BuildQuickSyncStagesRequest) (*deployment.BuildQuickSyncStagesResponse, error) {
177+
return nil, status.Errorf(codes.Unimplemented, "method BuildQuickSyncStages not implemented")
178+
}
179+
func (s *PipelineSyncPluginServiceServer[Config]) ExecuteStage(context.Context, *deployment.ExecuteStageRequest) (*deployment.ExecuteStageResponse, error) {
180+
return nil, status.Errorf(codes.Unimplemented, "method ExecuteStage not implemented")
181+
}

0 commit comments

Comments
 (0)