Skip to content

Commit

Permalink
Fix kubeadm init regression
Browse files Browse the repository at this point in the history
Don't create admin rolebindings when --kubeconfig is set to a
non-default value.

Fixes: kubernetes/kubeadm#2992

Signed-off-by: Mario Valderrama <mario.valderrama@ionos.com>
  • Loading branch information
avorima committed Jan 15, 2024
1 parent 2991f6e commit f6cce58
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 3 deletions.
8 changes: 5 additions & 3 deletions cmd/kubeadm/app/cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -518,16 +518,18 @@ func (d *initData) Client() (clientset.Interface, error) {
return nil, err
}
} else { // Use a real client
if !d.adminKubeConfigBootstrapped {
isDefaultKubeConfigPath := d.KubeConfigPath() == kubeadmconstants.GetAdminKubeConfigPath()
// Only bootstrap the admin.conf if it's used by the user (i.e. --kubeconfig has its default value)
// and if the bootstrapping was not already done
if !d.adminKubeConfigBootstrapped && isDefaultKubeConfigPath {
// Call EnsureAdminClusterRoleBinding() to obtain a working client from admin.conf.
d.client, err = kubeconfigphase.EnsureAdminClusterRoleBinding(kubeadmconstants.KubernetesDir, nil)
if err != nil {
return nil, errors.Wrapf(err, "could not bootstrap the admin user in file %s", kubeadmconstants.AdminKubeConfigFileName)
}
d.adminKubeConfigBootstrapped = true
} else {
// In case adminKubeConfigBootstrapped is already set just return a client from the default
// kubeconfig location.
// Alternatively, just load the config pointed at the --kubeconfig path
d.client, err = kubeconfigutil.ClientSetFromFile(d.KubeConfigPath())
if err != nil {
return nil, err
Expand Down
52 changes: 52 additions & 0 deletions cmd/kubeadm/app/cmd/init_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ limitations under the License.
package cmd

import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"testing"
Expand Down Expand Up @@ -54,6 +57,20 @@ kind: ClusterConfiguration
controlPlaneEndpoint: "3.4.5.6"
`, kubeadmapiv1.SchemeGroupVersion.String(), expectedCRISocket)

const testKubeconfigDataFormat = `---
apiVersion: v1
clusters:
- name: foo-cluster
cluster:
server: %s
contexts:
- name: foo-context
context:
cluster: foo-cluster
current-context: foo-context
kind: Config
`

func TestNewInitData(t *testing.T) {
// create temp directory
tmpDir, err := os.MkdirTemp("", "kubeadm-init-test")
Expand Down Expand Up @@ -349,3 +366,38 @@ func expectedInitIgnorePreflightErrors(expectedItems ...string) func(t *testing.
}
}
}

func TestInitDataClientWithNonDefaultKubeconfig(t *testing.T) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodHead {
w.WriteHeader(http.StatusMethodNotAllowed)
}
}))
defer ts.Close()

kubeconfigPath := filepath.Join(t.TempDir(), "custom.conf")
if err := os.WriteFile(kubeconfigPath, []byte(fmt.Sprintf(testKubeconfigDataFormat, ts.URL)), 0o600); err != nil {
t.Fatalf("os.WriteFile returned unexpected error: %v", err)
}

// initialize an external init option and inject it to the init cmd
initOptions := newInitOptions()
initOptions.skipCRIDetect = true // avoid CRI detection in unit tests
initOptions.kubeconfigPath = kubeconfigPath
cmd := newCmdInit(nil, initOptions)

data, err := newInitData(cmd, nil, initOptions, nil)
if err != nil {
t.Fatalf("newInitData returned unexpected error: %v", err)
}

client, err := data.Client()
if err != nil {
t.Fatalf("data.Client returned unexpected error: %v", err)
}

result := client.Discovery().RESTClient().Verb("HEAD").Do(context.Background())
if err := result.Error(); err != nil {
t.Fatalf("REST client request returned unexpected error: %v", err)
}
}

0 comments on commit f6cce58

Please sign in to comment.