blob: 47e3ac30e57dee48c75bff80e2f511992dd24044 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cmd
import (
"os"
"path/filepath"
"runtime"
"strings"
)
import (
"github.com/asaskevich/govalidator"
"github.com/golang-jwt/jwt/v4"
"github.com/pkg/errors"
)
import (
"github.com/apache/dubbo-kubernetes/app/dubboctl/internal/envoy"
"github.com/apache/dubbo-kubernetes/pkg/config/app/dubboctl"
"github.com/apache/dubbo-kubernetes/pkg/core/runtime/component"
core_xds "github.com/apache/dubbo-kubernetes/pkg/core/xds"
"github.com/apache/dubbo-kubernetes/pkg/log"
leader_memory "github.com/apache/dubbo-kubernetes/pkg/plugins/leader/memory"
util_files "github.com/apache/dubbo-kubernetes/pkg/util/files"
)
type ProxyConfig struct {
ComponentManager component.Manager
BootstrapDynamicMetadata map[string]string
Config *dubboctl.Config
BootstrapGenerator envoy.BootstrapConfigFactoryFunc
DataplaneTokenGenerator func(cfg *dubboctl.Config) (component.Component, error)
LogLevel log.LogLevel
}
var features = []string{core_xds.FeatureTCPAccessLogViaNamedPipe}
func defaultDataplaneTokenGenerator(cfg *dubboctl.Config) (component.Component, error) {
if cfg.DataplaneRuntime.Token != "" {
path := filepath.Join(cfg.DataplaneRuntime.ConfigDir, cfg.Dataplane.Name)
if err := writeFile(path, []byte(cfg.DataplaneRuntime.Token), 0o600); err != nil {
runLog.Error(err, "unable to create file with dataplane token")
return nil, err
}
cfg.DataplaneRuntime.TokenPath = path
}
if cfg.DataplaneRuntime.TokenPath != "" {
if err := ValidateTokenPath(cfg.DataplaneRuntime.TokenPath); err != nil {
return nil, errors.Wrapf(err, "dataplane token is invalid, in Kubernetes you must mount a serviceAccount token, in universal you must start your proxy with a generated token.")
}
}
return component.ComponentFunc(func(<-chan struct{}) error {
return nil
}), nil
}
func DefaultProxyConfig() *ProxyConfig {
config := dubboctl.DefaultConfig()
return &ProxyConfig{
ComponentManager: component.NewManager(leader_memory.NewNeverLeaderElector()),
BootstrapGenerator: envoy.NewRemoteBootstrapGenerator(runtime.GOOS, features),
Config: &config,
BootstrapDynamicMetadata: map[string]string{},
DataplaneTokenGenerator: defaultDataplaneTokenGenerator,
}
}
func ValidateTokenPath(path string) error {
if path == "" {
return nil
}
empty, err := util_files.FileEmpty(path)
if err != nil {
return errors.Wrapf(err, "could not read file %s", path)
}
if empty {
return errors.Errorf("token under file %s is empty", path)
}
rawToken, err := os.ReadFile(path)
if err != nil {
return errors.Wrapf(err, "could not read the token in the file %s", path)
}
strToken := strings.TrimSpace(string(rawToken))
if !govalidator.Matches(strToken, "^[^\\x00\\n\\r]*$") {
return errors.New("Token shouldn't contain line breaks within the token, only at the start or end")
}
token, _, err := new(jwt.Parser).ParseUnverified(strToken, &jwt.MapClaims{})
if err != nil {
return errors.Wrap(err, "not valid JWT token. Can't parse it.")
}
if token.Method.Alg() == "" {
return errors.New("not valid JWT token. No Alg.")
}
if token.Header == nil {
return errors.New("not valid JWT token. No Header.")
}
return nil
}