Skip to content

Commit ea6ee30

Browse files
authored
feat: sidecar injection and loading (#22)
Signed-off-by: Leonardo Cecchi <[email protected]>
1 parent dd6548c commit ea6ee30

File tree

16 files changed

+192
-134
lines changed

16 files changed

+192
-134
lines changed

.golangci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,4 +131,4 @@ issues:
131131
- test
132132
exclude-files:
133133
- zz_generated.*
134-
- internal/controller/suite_test.go
134+
- internal/operator/controller/suite_test.go

cmd/instance/main.go

Lines changed: 40 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,58 @@
1-
// Package main is the implementation of the CNPG-i PostgreSQL sidecar
1+
// Package main is the entrypoint of operator plugin
22
package main
33

44
import (
5-
"errors"
5+
"fmt"
66
"os"
77

8-
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
9-
"k8s.io/apimachinery/pkg/fields"
10-
"k8s.io/apimachinery/pkg/runtime"
11-
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
12-
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
13-
ctrl "sigs.k8s.io/controller-runtime"
14-
"sigs.k8s.io/controller-runtime/pkg/cache"
15-
"sigs.k8s.io/controller-runtime/pkg/client"
8+
"github.com/cloudnative-pg/machinery/pkg/log"
9+
"github.com/spf13/cobra"
10+
"github.com/spf13/viper"
1611

17-
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
1812
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/instance"
1913
)
2014

21-
var (
22-
scheme = runtime.NewScheme()
23-
setupLog = ctrl.Log.WithName("setup")
24-
)
25-
26-
func init() {
27-
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
28-
29-
utilruntime.Must(barmancloudv1.AddToScheme(scheme))
30-
// +kubebuilder:scaffold:scheme
31-
}
32-
3315
func main() {
34-
setupLog.Info("Starting barman cloud instance plugin")
35-
namespace := mustGetEnv("NAMESPACE")
36-
boName := mustGetEnv("BARMAN_OBJECT_NAME")
37-
clusterName := mustGetEnv("CLUSTER_NAME")
38-
instanceName := mustGetEnv("INSTANCE_NAME")
39-
40-
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
41-
Scheme: scheme,
42-
Cache: cache.Options{
43-
ByObject: map[client.Object]cache.ByObject{
44-
&barmancloudv1.ObjectStore{}: {
45-
Field: fields.OneTermEqualSelector("metadata.name", boName),
46-
Namespaces: map[string]cache.Config{
47-
namespace: {},
48-
},
49-
},
50-
&cnpgv1.Cluster{}: {
51-
Field: fields.OneTermEqualSelector("metadata.name", clusterName),
52-
Namespaces: map[string]cache.Config{
53-
namespace: {},
54-
},
55-
},
56-
},
16+
cobra.EnableTraverseRunHooks = true
17+
18+
logFlags := &log.Flags{}
19+
rootCmd := &cobra.Command{
20+
Use: "instance",
21+
Short: "Starts the Barman Cloud CNPG-i sidecar plugin",
22+
PersistentPreRunE: func(_ *cobra.Command, _ []string) error {
23+
logFlags.ConfigureLogging()
24+
return nil
5725
},
58-
})
59-
if err != nil {
60-
setupLog.Error(err, "unable to start manager")
61-
os.Exit(1)
62-
}
63-
64-
if err := mgr.Add(&instance.CNPGI{
65-
Client: mgr.GetClient(),
66-
ClusterObjectKey: client.ObjectKey{
67-
Namespace: namespace,
68-
Name: clusterName,
69-
},
70-
BarmanObjectKey: client.ObjectKey{
71-
Namespace: namespace,
72-
Name: boName,
26+
RunE: func(cmd *cobra.Command, _ []string) error {
27+
requiredSettings := []string{
28+
"namespace",
29+
"barman-object-name",
30+
"cluster-name",
31+
"pod-name",
32+
"spool-directory",
33+
}
34+
35+
for _, k := range requiredSettings {
36+
if len(viper.GetString(k)) == 0 {
37+
return fmt.Errorf("missing required %s setting", k)
38+
}
39+
}
40+
41+
return instance.Start(cmd.Context())
7342
},
74-
InstanceName: instanceName,
75-
// TODO: improve
76-
PGDataPath: mustGetEnv("PGDATA"),
77-
PGWALPath: mustGetEnv("PGWAL"),
78-
SpoolDirectory: mustGetEnv("SPOOL_DIRECTORY"),
79-
ServerCertPath: mustGetEnv("SERVER_CERT"),
80-
ServerKeyPath: mustGetEnv("SERVER_KEY"),
81-
ClientCertPath: mustGetEnv("CLIENT_CERT"),
82-
ServerAddress: mustGetEnv("SERVER_ADDRESS"),
83-
PluginPath: mustGetEnv("PLUGIN_PATH"),
84-
}); err != nil {
85-
setupLog.Error(err, "unable to create CNPGI runnable")
86-
os.Exit(1)
8743
}
8844

89-
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
90-
setupLog.Error(err, "problem running manager")
91-
os.Exit(1)
92-
}
93-
}
45+
logFlags.AddFlags(rootCmd.PersistentFlags())
46+
47+
_ = viper.BindEnv("namespace", "NAMESPACE")
48+
_ = viper.BindEnv("barman-object-name", "BARMAN_OBJECT_NAME")
49+
_ = viper.BindEnv("cluster-name", "CLUSTER_NAME")
50+
_ = viper.BindEnv("pod-name", "POD_NAME")
51+
_ = viper.BindEnv("pgdata", "PGDATA")
52+
_ = viper.BindEnv("spool-directory", "SPOOL_DIRECTORY")
9453

95-
func mustGetEnv(envName string) string {
96-
value := os.Getenv(envName)
97-
if value == "" {
98-
setupLog.Error(
99-
errors.New("missing required env variable"),
100-
"while fetching env variables",
101-
"name",
102-
envName,
103-
)
54+
if err := rootCmd.Execute(); err != nil {
55+
fmt.Println(err)
10456
os.Exit(1)
10557
}
106-
return value
10758
}

cmd/operator/main.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@ import (
1010
"github.com/sourcegraph/conc/pool"
1111
"github.com/spf13/cobra"
1212
"github.com/spf13/viper"
13-
ctrl "sigs.k8s.io/controller-runtime"
1413

1514
"github.com/cloudnative-pg/plugin-barman-cloud/internal/cnpgi/operator"
16-
"github.com/cloudnative-pg/plugin-barman-cloud/internal/manager"
15+
"github.com/cloudnative-pg/plugin-barman-cloud/internal/operator/manager"
1716
)
1817

1918
func main() {
@@ -44,7 +43,6 @@ func newOperatorCommand() *cobra.Command {
4443
grpcServer := cmd.RunE
4544

4645
cmd.RunE = func(cmd *cobra.Command, args []string) error {
47-
ctrl.SetupSignalHandler()
4846
operatorPool := pool.
4947
New().
5048
WithContext(cmd.Context()).

docs/examples/cluster-example.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ spec:
77

88
plugins:
99
- name: barman-cloud.cloudnative-pg.io
10+
parameters:
11+
barmanObjectStore: minio-store
1012

1113
storage:
1214
size: 1Gi

go.mod

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ go 1.22.0
44

55
require (
66
github.com/cloudnative-pg/barman-cloud v0.0.0-20240924124724-92831d48562a
7-
github.com/cloudnative-pg/cloudnative-pg v1.24.0
7+
github.com/cloudnative-pg/cloudnative-pg v1.24.1-0.20241001084914-829808376542
88
github.com/cloudnative-pg/cnpg-i v0.0.0-20240924030516-c5636170f248
9-
github.com/cloudnative-pg/cnpg-i-machinery v0.0.0-20240926153929-09e2c6f6689b
9+
github.com/cloudnative-pg/cnpg-i-machinery v0.0.0-20241002070940-e5495e9c5ed6
1010
github.com/cloudnative-pg/machinery v0.0.0-20241001075747-34c8797af80f
1111
github.com/onsi/ginkgo/v2 v2.20.2
1212
github.com/onsi/gomega v1.34.2
@@ -114,12 +114,12 @@ require (
114114
gopkg.in/ini.v1 v1.67.0 // indirect
115115
gopkg.in/yaml.v2 v2.4.0 // indirect
116116
gopkg.in/yaml.v3 v3.0.1 // indirect
117-
k8s.io/apiextensions-apiserver v0.31.0 // indirect
118-
k8s.io/apiserver v0.31.0 // indirect
119-
k8s.io/component-base v0.31.0 // indirect
117+
k8s.io/apiextensions-apiserver v0.31.1 // indirect
118+
k8s.io/apiserver v0.31.1 // indirect
119+
k8s.io/component-base v0.31.1 // indirect
120120
k8s.io/klog/v2 v2.130.1 // indirect
121121
k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38 // indirect
122-
k8s.io/utils v0.0.0-20240902221715-702e33fdd3c3 // indirect
122+
k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 // indirect
123123
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 // indirect
124124
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
125125
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect

go.sum

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF
1616
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
1717
github.com/cloudnative-pg/barman-cloud v0.0.0-20240924124724-92831d48562a h1:0v1ML9Eibfq3helbT9GtU0EstqFtG91k/MPO9azY5ME=
1818
github.com/cloudnative-pg/barman-cloud v0.0.0-20240924124724-92831d48562a/go.mod h1:Jm0tOp5oB7utpt8wz6RfSv31h1mThOtffjfyxVupriE=
19-
github.com/cloudnative-pg/cloudnative-pg v1.24.0 h1:lY9IP/Gnh5ogNcFGoPnbD2eOiHdSdbdEp0PaUdOAMDQ=
20-
github.com/cloudnative-pg/cloudnative-pg v1.24.0/go.mod h1:n7Qqax6os+x3+7Qu/GojUUeKlL1ELGV63dcO/tzIfB4=
19+
github.com/cloudnative-pg/cloudnative-pg v1.24.1-0.20241001084914-829808376542 h1:IXf5lj+m4CBqzckQ9L/9hJ01JUoVw5N0FuPex0sVdVo=
20+
github.com/cloudnative-pg/cloudnative-pg v1.24.1-0.20241001084914-829808376542/go.mod h1:L8M+kTGpz/eaLZj46+4sARvO/vDYlo/m1xOigI/ghBA=
2121
github.com/cloudnative-pg/cnpg-i v0.0.0-20240924030516-c5636170f248 h1:eUGzb7YNjVLilwhgZoe4hDOO70fci3oqb/ZzQFbN3xg=
2222
github.com/cloudnative-pg/cnpg-i v0.0.0-20240924030516-c5636170f248/go.mod h1:K9/4eAT3rh2bKIWyujoN8BIPRXa4d1Ls+eBY8PE8y6w=
23-
github.com/cloudnative-pg/cnpg-i-machinery v0.0.0-20240926153929-09e2c6f6689b h1:T9G61tzOBoB5yvlDPULUoiUl6QxPmti3pkNFhQYGGQY=
24-
github.com/cloudnative-pg/cnpg-i-machinery v0.0.0-20240926153929-09e2c6f6689b/go.mod h1:dV1+nE7jWENm/fcnKBeKsaScMz685rQPbPCCDydJgsY=
23+
github.com/cloudnative-pg/cnpg-i-machinery v0.0.0-20241002070940-e5495e9c5ed6 h1:C4CU5fBTYTiJBPDqcgHpXSc5IvRTy+5KTaFZzdKHfAQ=
24+
github.com/cloudnative-pg/cnpg-i-machinery v0.0.0-20241002070940-e5495e9c5ed6/go.mod h1:mHEVy/Guae+rij1qlgwHg+lyFKDX48qjTL4lAqE7OJs=
2525
github.com/cloudnative-pg/machinery v0.0.0-20241001075747-34c8797af80f h1:RgPmQJkuSu3eTdfd4T2K95RYQi57LHB2+Jfsu/faKOM=
2626
github.com/cloudnative-pg/machinery v0.0.0-20241001075747-34c8797af80f/go.mod h1:bWp1Es5zlxElg4Z/c5f0RKOkDcyNvDHdYIvNcPQU4WM=
2727
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
@@ -286,22 +286,22 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
286286
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
287287
k8s.io/api v0.31.1 h1:Xe1hX/fPW3PXYYv8BlozYqw63ytA92snr96zMW9gWTU=
288288
k8s.io/api v0.31.1/go.mod h1:sbN1g6eY6XVLeqNsZGLnI5FwVseTrZX7Fv3O26rhAaI=
289-
k8s.io/apiextensions-apiserver v0.31.0 h1:fZgCVhGwsclj3qCw1buVXCV6khjRzKC5eCFt24kyLSk=
290-
k8s.io/apiextensions-apiserver v0.31.0/go.mod h1:b9aMDEYaEe5sdK+1T0KU78ApR/5ZVp4i56VacZYEHxk=
289+
k8s.io/apiextensions-apiserver v0.31.1 h1:L+hwULvXx+nvTYX/MKM3kKMZyei+UiSXQWciX/N6E40=
290+
k8s.io/apiextensions-apiserver v0.31.1/go.mod h1:tWMPR3sgW+jsl2xm9v7lAyRF1rYEK71i9G5dRtkknoQ=
291291
k8s.io/apimachinery v0.31.1 h1:mhcUBbj7KUjaVhyXILglcVjuS4nYXiwC+KKFBgIVy7U=
292292
k8s.io/apimachinery v0.31.1/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo=
293-
k8s.io/apiserver v0.31.0 h1:p+2dgJjy+bk+B1Csz+mc2wl5gHwvNkC9QJV+w55LVrY=
294-
k8s.io/apiserver v0.31.0/go.mod h1:KI9ox5Yu902iBnnyMmy7ajonhKnkeZYJhTZ/YI+WEMk=
293+
k8s.io/apiserver v0.31.1 h1:Sars5ejQDCRBY5f7R3QFHdqN3s61nhkpaX8/k1iEw1c=
294+
k8s.io/apiserver v0.31.1/go.mod h1:lzDhpeToamVZJmmFlaLwdYZwd7zB+WYRYIboqA1kGxM=
295295
k8s.io/client-go v0.31.1 h1:f0ugtWSbWpxHR7sjVpQwuvw9a3ZKLXX0u0itkFXufb0=
296296
k8s.io/client-go v0.31.1/go.mod h1:sKI8871MJN2OyeqRlmA4W4KM9KBdBUpDLu/43eGemCg=
297-
k8s.io/component-base v0.31.0 h1:/KIzGM5EvPNQcYgwq5NwoQBaOlVFrghoVGr8lG6vNRs=
298-
k8s.io/component-base v0.31.0/go.mod h1:TYVuzI1QmN4L5ItVdMSXKvH7/DtvIuas5/mm8YT3rTo=
297+
k8s.io/component-base v0.31.1 h1:UpOepcrX3rQ3ab5NB6g5iP0tvsgJWzxTyAo20sgYSy8=
298+
k8s.io/component-base v0.31.1/go.mod h1:WGeaw7t/kTsqpVTaCoVEtillbqAhF2/JgvO0LDOMa0w=
299299
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
300300
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
301301
k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38 h1:1dWzkmJrrprYvjGwh9kEUxmcUV/CtNU8QM7h1FLWQOo=
302302
k8s.io/kube-openapi v0.0.0-20240903163716-9e1beecbcb38/go.mod h1:coRQXBK9NxO98XUv3ZD6AK3xzHCxV6+b7lrquKwaKzA=
303-
k8s.io/utils v0.0.0-20240902221715-702e33fdd3c3 h1:b2FmK8YH+QEwq/Sy2uAEhmqL5nPfGYbJOcaqjeYYZoA=
304-
k8s.io/utils v0.0.0-20240902221715-702e33fdd3c3/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
303+
k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 h1:MDF6h2H/h4tbzmtIKTuctcwZmY0tY9mD9fNT47QO6HI=
304+
k8s.io/utils v0.0.0-20240921022957-49e7df575cb6/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
305305
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3 h1:2770sDpzrjjsAtVhSeUFseziht227YAWYHLGNM8QPwY=
306306
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.30.3/go.mod h1:Ve9uj1L+deCXFrPOk1LpFXqTg7LCFzFso6PA48q/XZw=
307307
sigs.k8s.io/controller-runtime v0.19.0 h1:nWVM7aq+Il2ABxwiCizrVDSlmDcshi9llbaFbC0ji/Q=

internal/cnpgi/instance/manager.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package instance
2+
3+
import (
4+
"context"
5+
"os"
6+
"path"
7+
8+
cnpgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
9+
"github.com/spf13/viper"
10+
"k8s.io/apimachinery/pkg/fields"
11+
"k8s.io/apimachinery/pkg/runtime"
12+
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
13+
ctrl "sigs.k8s.io/controller-runtime"
14+
"sigs.k8s.io/controller-runtime/pkg/cache"
15+
"sigs.k8s.io/controller-runtime/pkg/client"
16+
"sigs.k8s.io/controller-runtime/pkg/log"
17+
18+
barmancloudv1 "github.com/cloudnative-pg/plugin-barman-cloud/api/v1"
19+
)
20+
21+
var scheme = runtime.NewScheme()
22+
23+
func init() {
24+
utilruntime.Must(barmancloudv1.AddToScheme(scheme))
25+
utilruntime.Must(cnpgv1.AddToScheme(scheme))
26+
}
27+
28+
// Start starts the sidecar informers and CNPG-i server
29+
func Start(ctx context.Context) error {
30+
setupLog := log.FromContext(ctx)
31+
setupLog.Info("Starting barman cloud instance plugin")
32+
namespace := viper.GetString("namespace")
33+
boName := viper.GetString("barman-object-name")
34+
clusterName := viper.GetString("cluster-name")
35+
podName := viper.GetString("pod-name")
36+
37+
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
38+
Scheme: scheme,
39+
Cache: cache.Options{
40+
ByObject: map[client.Object]cache.ByObject{
41+
&barmancloudv1.ObjectStore{}: {
42+
Field: fields.OneTermEqualSelector("metadata.name", boName),
43+
Namespaces: map[string]cache.Config{
44+
namespace: {},
45+
},
46+
},
47+
&cnpgv1.Cluster{}: {
48+
Field: fields.OneTermEqualSelector("metadata.name", clusterName),
49+
Namespaces: map[string]cache.Config{
50+
namespace: {},
51+
},
52+
},
53+
},
54+
},
55+
})
56+
if err != nil {
57+
setupLog.Error(err, "unable to start manager")
58+
os.Exit(1)
59+
}
60+
61+
if err := mgr.Add(&CNPGI{
62+
Client: mgr.GetClient(),
63+
ClusterObjectKey: client.ObjectKey{
64+
Namespace: namespace,
65+
Name: clusterName,
66+
},
67+
BarmanObjectKey: client.ObjectKey{
68+
Namespace: namespace,
69+
Name: boName,
70+
},
71+
InstanceName: podName,
72+
// TODO: improve
73+
PGDataPath: viper.GetString("pgdata"),
74+
PGWALPath: path.Join(viper.GetString("pgdata"), "pg_wal"),
75+
SpoolDirectory: viper.GetString("spool-directory"),
76+
PluginPath: viper.GetString("plugin-path"),
77+
}); err != nil {
78+
setupLog.Error(err, "unable to create CNPGI runnable")
79+
return err
80+
}
81+
82+
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
83+
setupLog.Error(err, "problem running manager")
84+
return err
85+
}
86+
87+
return nil
88+
}

internal/cnpgi/instance/start.go

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,6 @@ type CNPGI struct {
1818
PGDataPath string
1919
PGWALPath string
2020
SpoolDirectory string
21-
ServerCertPath string
22-
ServerKeyPath string
23-
ClientCertPath string
24-
// mutually exclusive with pluginPath
25-
ServerAddress string
2621
// mutually exclusive with serverAddress
2722
PluginPath string
2823
InstanceName string
@@ -49,12 +44,8 @@ func (c *CNPGI) Start(ctx context.Context) error {
4944
Client: c.Client,
5045
BarmanObjectKey: c.BarmanObjectKey,
5146
},
52-
Enrichers: []http.ServerEnricher{enrich},
53-
ServerCertPath: c.ServerCertPath,
54-
ServerKeyPath: c.ServerKeyPath,
55-
ClientCertPath: c.ClientCertPath,
56-
ServerAddress: c.ServerAddress,
57-
PluginPath: c.PluginPath,
47+
Enrichers: []http.ServerEnricher{enrich},
48+
PluginPath: c.PluginPath,
5849
}
5950

6051
return srv.Start(ctx)

internal/cnpgi/metadata/constants.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import "github.com/cloudnative-pg/cnpg-i/pkg/identity"
44

55
// PluginName is the name of the plugin from the instance manager
66
// Point-of-view
7-
const PluginName = "instance.barman-cloud.cloudnative-pg.io"
7+
const PluginName = "barman-cloud.cloudnative-pg.io"
88

99
// Data is the metadata of this plugin.
1010
var Data = identity.GetPluginMetadataResponse{

0 commit comments

Comments
 (0)