mirror of https://github.com/linkerd/linkerd2.git
128 lines
3.5 KiB
Go
128 lines
3.5 KiB
Go
package cmd
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/linkerd/linkerd2/multicluster/static"
|
|
mccharts "github.com/linkerd/linkerd2/multicluster/values"
|
|
"github.com/linkerd/linkerd2/pkg/charts"
|
|
"github.com/linkerd/linkerd2/pkg/k8s"
|
|
"github.com/linkerd/linkerd2/pkg/version"
|
|
"github.com/spf13/cobra"
|
|
chartloader "helm.sh/helm/v3/pkg/chart/loader"
|
|
"helm.sh/helm/v3/pkg/chartutil"
|
|
kerrors "k8s.io/apimachinery/pkg/api/errors"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
"sigs.k8s.io/yaml"
|
|
)
|
|
|
|
type (
|
|
allowOptions struct {
|
|
namespace string
|
|
serviceAccountName string
|
|
ignoreCluster bool
|
|
}
|
|
)
|
|
|
|
func newAllowCommand() *cobra.Command {
|
|
opts := allowOptions{
|
|
namespace: defaultMulticlusterNamespace,
|
|
ignoreCluster: false,
|
|
}
|
|
|
|
cmd := &cobra.Command{
|
|
Hidden: false,
|
|
Use: "allow",
|
|
Short: "Outputs credential resources that allow service-mirror controllers to connect to this cluster",
|
|
Args: cobra.NoArgs,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
|
|
values, err := buildMulticlusterAllowValues(cmd.Context(), &opts)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Render raw values and create chart config
|
|
rawValues, err := yaml.Marshal(values)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
files := []*chartloader.BufferedFile{
|
|
{Name: chartutil.ChartfileName},
|
|
{Name: "templates/namespace.yaml"},
|
|
{Name: "templates/remote-access-service-mirror-rbac.yaml"},
|
|
}
|
|
|
|
chart := &charts.Chart{
|
|
Name: helmMulticlusterDefaultChartName,
|
|
Dir: helmMulticlusterDefaultChartName,
|
|
Namespace: controlPlaneNamespace,
|
|
RawValues: rawValues,
|
|
Files: files,
|
|
Fs: static.Templates,
|
|
}
|
|
buf, err := chart.RenderNoPartials()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
stdout.Write(buf.Bytes())
|
|
stdout.Write([]byte("---\n"))
|
|
|
|
return nil
|
|
},
|
|
}
|
|
|
|
cmd.Flags().StringVar(&opts.namespace, "namespace", defaultMulticlusterNamespace, "The destination namespace for the service account.")
|
|
cmd.Flags().BoolVar(&opts.ignoreCluster, "ignore-cluster", false, "Ignore cluster configuration")
|
|
cmd.Flags().StringVar(&opts.serviceAccountName, "service-account-name", "", "The name of the multicluster access service account")
|
|
|
|
return cmd
|
|
}
|
|
|
|
func buildMulticlusterAllowValues(ctx context.Context, opts *allowOptions) (*mccharts.Values, error) {
|
|
|
|
kubeAPI, err := k8s.NewAPI(kubeconfigPath, kubeContext, impersonate, impersonateGroup, 0)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if opts.namespace == "" {
|
|
return nil, errors.New("you need to specify a namespace")
|
|
}
|
|
|
|
if opts.serviceAccountName == "" {
|
|
return nil, errors.New("you need to specify a service account name")
|
|
}
|
|
|
|
if opts.namespace == controlPlaneNamespace {
|
|
return nil, errors.New("you need to setup the multicluster addons in a namespace different than the Linkerd one")
|
|
}
|
|
|
|
defaults, err := mccharts.NewInstallValues()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
defaults.Namespace = opts.namespace
|
|
defaults.LinkerdVersion = version.Version
|
|
defaults.Gateway = false
|
|
defaults.ServiceMirror = false
|
|
defaults.RemoteMirrorServiceAccount = true
|
|
defaults.RemoteMirrorServiceAccountName = opts.serviceAccountName
|
|
|
|
if !opts.ignoreCluster {
|
|
acc, err := kubeAPI.CoreV1().ServiceAccounts(defaults.Namespace).Get(ctx, defaults.RemoteMirrorServiceAccountName, metav1.GetOptions{})
|
|
if err == nil && acc != nil {
|
|
return nil, fmt.Errorf("Service account with name %s already exists, use --ignore-cluster for force operation", defaults.RemoteMirrorServiceAccountName)
|
|
}
|
|
if !kerrors.IsNotFound(err) {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
return defaults, nil
|
|
}
|