mirror of
https://github.com/vmware-tanzu/pinniped.git
synced 2026-01-07 05:57:02 +00:00
- Allow the port number to be configured to any value within the range 1024 to 65535 - This commit does not include adding new config knobs to the ytt values file, so while it is possible to change this port without needing to recompile, it is not convenient
175 lines
5.5 KiB
Go
175 lines
5.5 KiB
Go
// Copyright 2020-2021 the Pinniped contributors. All Rights Reserved.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
// Package concierge contains functionality to load/store Config's from/to
|
|
// some source.
|
|
package concierge
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"strings"
|
|
|
|
"k8s.io/utils/pointer"
|
|
"sigs.k8s.io/yaml"
|
|
|
|
"go.pinniped.dev/internal/constable"
|
|
"go.pinniped.dev/internal/groupsuffix"
|
|
"go.pinniped.dev/internal/plog"
|
|
)
|
|
|
|
const (
|
|
aboutAYear = 60 * 60 * 24 * 365
|
|
about9Months = 60 * 60 * 24 * 30 * 9
|
|
|
|
// Use 10250 because it happens to be the same port on which the Kubelet listens, so some cluster types
|
|
// are more permissive with servers that run on this port. For example, GKE private clusters do not
|
|
// allow traffic from the control plane to most ports, but do allow traffic to port 10250. This allows
|
|
// the Concierge to work without additional configuration on these types of clusters.
|
|
aggregatedAPIServerPortDefault = 10250
|
|
)
|
|
|
|
// FromPath loads an Config from a provided local file path, inserts any
|
|
// defaults (from the Config documentation), and verifies that the config is
|
|
// valid (per the Config documentation).
|
|
//
|
|
// Note! The Config file should contain base64-encoded WebhookCABundle data.
|
|
// This function will decode that base64-encoded data to PEM bytes to be stored
|
|
// in the Config.
|
|
func FromPath(path string) (*Config, error) {
|
|
data, err := ioutil.ReadFile(path)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("read file: %w", err)
|
|
}
|
|
|
|
var config Config
|
|
if err := yaml.Unmarshal(data, &config); err != nil {
|
|
return nil, fmt.Errorf("decode yaml: %w", err)
|
|
}
|
|
|
|
maybeSetAPIDefaults(&config.APIConfig)
|
|
maybeSetAggregatedAPIServerPortDefaults(&config.AggregatedAPIServerPort)
|
|
maybeSetAPIGroupSuffixDefault(&config.APIGroupSuffix)
|
|
maybeSetKubeCertAgentDefaults(&config.KubeCertAgentConfig)
|
|
|
|
if err := validateAPI(&config.APIConfig); err != nil {
|
|
return nil, fmt.Errorf("validate api: %w", err)
|
|
}
|
|
|
|
if err := validateAPIGroupSuffix(*config.APIGroupSuffix); err != nil {
|
|
return nil, fmt.Errorf("validate apiGroupSuffix: %w", err)
|
|
}
|
|
|
|
if err := validateAggregatedAPIServerPort(config.AggregatedAPIServerPort); err != nil {
|
|
return nil, fmt.Errorf("validate aggregatedAPIServerPort: %w", err)
|
|
}
|
|
|
|
if err := validateNames(&config.NamesConfig); err != nil {
|
|
return nil, fmt.Errorf("validate names: %w", err)
|
|
}
|
|
|
|
if err := plog.ValidateAndSetLogLevelGlobally(config.LogLevel); err != nil {
|
|
return nil, fmt.Errorf("validate log level: %w", err)
|
|
}
|
|
|
|
if config.Labels == nil {
|
|
config.Labels = make(map[string]string)
|
|
}
|
|
|
|
return &config, nil
|
|
}
|
|
|
|
func maybeSetAPIDefaults(apiConfig *APIConfigSpec) {
|
|
if apiConfig.ServingCertificateConfig.DurationSeconds == nil {
|
|
apiConfig.ServingCertificateConfig.DurationSeconds = pointer.Int64Ptr(aboutAYear)
|
|
}
|
|
|
|
if apiConfig.ServingCertificateConfig.RenewBeforeSeconds == nil {
|
|
apiConfig.ServingCertificateConfig.RenewBeforeSeconds = pointer.Int64Ptr(about9Months)
|
|
}
|
|
}
|
|
|
|
func maybeSetAPIGroupSuffixDefault(apiGroupSuffix **string) {
|
|
if *apiGroupSuffix == nil {
|
|
*apiGroupSuffix = pointer.StringPtr(groupsuffix.PinnipedDefaultSuffix)
|
|
}
|
|
}
|
|
|
|
func maybeSetAggregatedAPIServerPortDefaults(aggregatedAPIServerPort **int64) {
|
|
if *aggregatedAPIServerPort == nil {
|
|
*aggregatedAPIServerPort = pointer.Int64Ptr(aggregatedAPIServerPortDefault)
|
|
}
|
|
}
|
|
|
|
func maybeSetKubeCertAgentDefaults(cfg *KubeCertAgentSpec) {
|
|
if cfg.NamePrefix == nil {
|
|
cfg.NamePrefix = pointer.StringPtr("pinniped-kube-cert-agent-")
|
|
}
|
|
|
|
if cfg.Image == nil {
|
|
cfg.Image = pointer.StringPtr("debian:latest")
|
|
}
|
|
}
|
|
|
|
func validateNames(names *NamesConfigSpec) error {
|
|
missingNames := []string{}
|
|
if names == nil {
|
|
names = &NamesConfigSpec{}
|
|
}
|
|
if names.ServingCertificateSecret == "" {
|
|
missingNames = append(missingNames, "servingCertificateSecret")
|
|
}
|
|
if names.CredentialIssuer == "" {
|
|
missingNames = append(missingNames, "credentialIssuer")
|
|
}
|
|
if names.APIService == "" {
|
|
missingNames = append(missingNames, "apiService")
|
|
}
|
|
if names.ImpersonationLoadBalancerService == "" {
|
|
missingNames = append(missingNames, "impersonationLoadBalancerService")
|
|
}
|
|
if names.ImpersonationClusterIPService == "" {
|
|
missingNames = append(missingNames, "impersonationClusterIPService")
|
|
}
|
|
if names.ImpersonationTLSCertificateSecret == "" {
|
|
missingNames = append(missingNames, "impersonationTLSCertificateSecret")
|
|
}
|
|
if names.ImpersonationCACertificateSecret == "" {
|
|
missingNames = append(missingNames, "impersonationCACertificateSecret")
|
|
}
|
|
if names.ImpersonationSignerSecret == "" {
|
|
missingNames = append(missingNames, "impersonationSignerSecret")
|
|
}
|
|
if names.AgentServiceAccount == "" {
|
|
missingNames = append(missingNames, "agentServiceAccount")
|
|
}
|
|
if len(missingNames) > 0 {
|
|
return constable.Error("missing required names: " + strings.Join(missingNames, ", "))
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func validateAPI(apiConfig *APIConfigSpec) error {
|
|
if *apiConfig.ServingCertificateConfig.DurationSeconds < *apiConfig.ServingCertificateConfig.RenewBeforeSeconds {
|
|
return constable.Error("durationSeconds cannot be smaller than renewBeforeSeconds")
|
|
}
|
|
|
|
if *apiConfig.ServingCertificateConfig.RenewBeforeSeconds <= 0 {
|
|
return constable.Error("renewBefore must be positive")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func validateAPIGroupSuffix(apiGroupSuffix string) error {
|
|
return groupsuffix.Validate(apiGroupSuffix)
|
|
}
|
|
|
|
func validateAggregatedAPIServerPort(aggregatedAPIServerPort *int64) error {
|
|
// It cannot be below 1024 because the container is not running as root.
|
|
if *aggregatedAPIServerPort < 1024 || *aggregatedAPIServerPort > 65535 {
|
|
return constable.Error("must be within range 1024 to 65535")
|
|
}
|
|
return nil
|
|
}
|