Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ Allow CAPBK to generate JoinConfiguration discovery kubeconfig #10799

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -492,10 +492,11 @@ generate-go-conversions-kubeadm-bootstrap: $(CONVERSION_GEN) ## Generate convers
--go-header-file=./hack/boilerplate/boilerplate.generatego.txt \
./internal/apis/bootstrap/kubeadm/v1alpha3 \
./internal/apis/bootstrap/kubeadm/v1alpha4
$(MAKE) clean-generated-conversions SRC_DIRS="./bootstrap/kubeadm/types/upstreamv1beta2,./bootstrap/kubeadm/types/upstreamv1beta3,./bootstrap/kubeadm/types/upstreamv1beta4"
$(MAKE) clean-generated-conversions SRC_DIRS="./bootstrap/kubeadm/types/upstreamv1beta1,./bootstrap/kubeadm/types/upstreamv1beta2,./bootstrap/kubeadm/types/upstreamv1beta3,./bootstrap/kubeadm/types/upstreamv1beta4"
$(CONVERSION_GEN) \
--output-file=zz_generated.conversion.go \
--go-header-file=./hack/boilerplate/boilerplate.generatego.txt \
./bootstrap/kubeadm/types/upstreamv1beta1 \
sbueringer marked this conversation as resolved.
Show resolved Hide resolved
./bootstrap/kubeadm/types/upstreamv1beta2 \
./bootstrap/kubeadm/types/upstreamv1beta3 \
./bootstrap/kubeadm/types/upstreamv1beta4
Expand Down
131 changes: 131 additions & 0 deletions bootstrap/kubeadm/api/v1beta1/kubeadm_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,137 @@ type BootstrapTokenDiscovery struct {
type FileDiscovery struct {
// KubeConfigPath is used to specify the actual file path or URL to the kubeconfig file from which to load cluster information
KubeConfigPath string `json:"kubeConfigPath"`

vincepri marked this conversation as resolved.
Show resolved Hide resolved
// KubeConfig is used (optionally) to generate a KubeConfig based on the KubeadmConfig's information.
// The file is generated at the path specified in KubeConfigPath.
//
// Host address (server field) information is automatically populated based on the Cluster's ControlPlaneEndpoint.
// Certificate Authority (certificate-authority-data field) is gathered from the cluster's CA secret.
//
// +optional
KubeConfig *FileDiscoveryKubeConfig `json:"kubeConfig,omitempty"`
sbueringer marked this conversation as resolved.
Show resolved Hide resolved
}

// FileDiscoveryKubeConfig contains elements describing how to generate the kubeconfig for bootstrapping.
type FileDiscoveryKubeConfig struct {
// Cluster contains information about how to communicate with the kubernetes cluster.
//
// By default the following fields are automatically populated:
// - Server with the Cluster's ControlPlaneEndpoint.
// - CertificateAuthorityData with the Cluster's CA certificate.
vincepri marked this conversation as resolved.
Show resolved Hide resolved
// +optional
Cluster *KubeConfigCluster `json:"cluster,omitempty"`

// User contains information that describes identity information.
// This is used to tell the kubernetes cluster who you are.
User KubeConfigUser `json:"user"`
}

// KubeConfigCluster contains information about how to communicate with a kubernetes cluster.
//
// Adapted from clientcmdv1.Cluster.
type KubeConfigCluster struct {
// Server is the address of the kubernetes cluster (https://hostname:port).
//
// Defaults to https:// + Cluster.Spec.ControlPlaneEndpoint.
//
// +optional
Server string `json:"server,omitempty"`

// TLSServerName is used to check server certificate. If TLSServerName is empty, the hostname used to contact the server is used.
// +optional
TLSServerName string `json:"tlsServerName,omitempty"`

// InsecureSkipTLSVerify skips the validity check for the server's certificate. This will make your HTTPS connections insecure.
// +optional
InsecureSkipTLSVerify bool `json:"insecureSkipTLSVerify,omitempty"`

// CertificateAuthorityData contains PEM-encoded certificate authority certificates.
//
// Defaults to the Cluster's CA certificate if empty.
//
// +optional
CertificateAuthorityData []byte `json:"certificateAuthorityData,omitempty"`

// ProxyURL is the URL to the proxy to be used for all requests made by this
// client. URLs with "http", "https", and "socks5" schemes are supported. If
// this configuration is not provided or the empty string, the client
// attempts to construct a proxy configuration from http_proxy and
// https_proxy environment variables. If these environment variables are not
// set, the client does not attempt to proxy requests.
//
// socks5 proxying does not currently support spdy streaming endpoints (exec,
// attach, port forward).
//
// +optional
ProxyURL string `json:"proxyURL,omitempty"`
}

// KubeConfigUser contains information that describes identity information.
// This is used to tell the kubernetes cluster who you are.
//
// Either authProvider or exec must be filled.
//
// Adapted from clientcmdv1.AuthInfo.
type KubeConfigUser struct {
// AuthProvider specifies a custom authentication plugin for the kubernetes cluster.
vincepri marked this conversation as resolved.
Show resolved Hide resolved
// +optional
AuthProvider *KubeConfigAuthProvider `json:"authProvider,omitempty"`

// Exec specifies a custom exec-based authentication plugin for the kubernetes cluster.
// +optional
Exec *KubeConfigAuthExec `json:"exec,omitempty"`
}

// KubeConfigAuthProvider holds the configuration for a specified auth provider.
type KubeConfigAuthProvider struct {
// Name is the name of the authentication plugin.
Name string `json:"name"`

// Config holds the parameters for the authentication plugin.
vincepri marked this conversation as resolved.
Show resolved Hide resolved
// +optional
Config map[string]string `json:"config,omitempty"`
}

// KubeConfigAuthExec specifies a command to provide client credentials. The command is exec'd
// and outputs structured stdout holding credentials.
//
// See the client.authentication.k8s.io API group for specifications of the exact input
// and output format.
type KubeConfigAuthExec struct {
// Command to execute.
Command string `json:"command"`

// Arguments to pass to the command when executing it.
// +optional
Args []string `json:"args,omitempty"`

// Env defines additional environment variables to expose to the process. These
// are unioned with the host's environment, as well as variables client-go uses
// to pass argument to the plugin.
// +optional
Env []KubeConfigAuthExecEnv `json:"env,omitempty"`

// Preferred input version of the ExecInfo. The returned ExecCredentials MUST use
// the same encoding version as the input.
// Defaults to client.authentication.k8s.io/v1 if not set.
// +optional
APIVersion string `json:"apiVersion,omitempty"`
sbueringer marked this conversation as resolved.
Show resolved Hide resolved

// ProvideClusterInfo determines whether or not to provide cluster information,
// which could potentially contain very large CA data, to this exec plugin as a
// part of the KUBERNETES_EXEC_INFO environment variable. By default, it is set
// to false. Package k8s.io/client-go/tools/auth/exec provides helper methods for
// reading this environment variable.
// +optional
vincepri marked this conversation as resolved.
Show resolved Hide resolved
ProvideClusterInfo bool `json:"provideClusterInfo,omitempty"`
}

// KubeConfigAuthExecEnv is used for setting environment variables when executing an exec-based
// credential plugin.
type KubeConfigAuthExecEnv struct {
Name string `json:"name"`
Value string `json:"value"`
}

// HostPathMount contains elements describing volumes that are mounted from the
Expand Down
36 changes: 36 additions & 0 deletions bootstrap/kubeadm/api/v1beta1/kubeadmconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,15 @@ func (c *KubeadmConfigSpec) Default() {
if c.JoinConfiguration != nil && c.JoinConfiguration.NodeRegistration.ImagePullPolicy == "" {
c.JoinConfiguration.NodeRegistration.ImagePullPolicy = "IfNotPresent"
}
if c.JoinConfiguration != nil && c.JoinConfiguration.Discovery.File != nil {
if kfg := c.JoinConfiguration.Discovery.File.KubeConfig; kfg != nil {
if kfg.User.Exec != nil {
if kfg.User.Exec.APIVersion == "" {
kfg.User.Exec.APIVersion = "client.authentication.k8s.io/v1"
}
}
}
}
}

// Validate ensures the KubeadmConfigSpec is valid.
Expand All @@ -142,6 +151,33 @@ func (c *KubeadmConfigSpec) Validate(pathPrefix *field.Path) field.ErrorList {
allErrs = append(allErrs, c.validateUsers(pathPrefix)...)
allErrs = append(allErrs, c.validateIgnition(pathPrefix)...)

// Validate JoinConfiguration.
if c.JoinConfiguration != nil {
if c.JoinConfiguration.Discovery.File != nil {
if kfg := c.JoinConfiguration.Discovery.File.KubeConfig; kfg != nil {
userPath := pathPrefix.Child("joinConfiguration", "discovery", "file", "kubeconfig", "user")
if kfg.User.AuthProvider == nil && kfg.User.Exec == nil {
allErrs = append(allErrs,
field.Invalid(
userPath,
kfg.User,
"at least one of authProvider or exec must be defined",
),
)
}
if kfg.User.AuthProvider != nil && kfg.User.Exec != nil {
allErrs = append(allErrs,
field.Invalid(
userPath,
kfg.User,
"either authProvider or exec must be defined",
),
)
}
}
}
}

return allErrs
}

Expand Down
135 changes: 134 additions & 1 deletion bootstrap/kubeadm/api/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading