Skip to content

Commit

Permalink
parse api server address
Browse files Browse the repository at this point in the history
  • Loading branch information
aleoli committed Aug 5, 2021
1 parent 054d60b commit 5ae11c1
Show file tree
Hide file tree
Showing 11 changed files with 193 additions and 55 deletions.
1 change: 0 additions & 1 deletion apis/config/v1alpha1/clusterconfig_types.go
Expand Up @@ -115,7 +115,6 @@ type LabelPolicy struct {
// APIServerConfig defines the configuration of the cluster APIServer.
type APIServerConfig struct {
Address string `json:"address,omitempty"`
Port string `json:"port,omitempty"`
TrustedCA bool `json:"trustedCA,omitempty"`
}

Expand Down
1 change: 0 additions & 1 deletion deployments/liqo/README.md
Expand Up @@ -3,7 +3,6 @@
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| apiServer.address | string | `""` | The address that must be used to contact your API server, it needs to be reachable from the clusters that you will peer with (defaults to your master IP) |
| apiServer.port | string | `"6443"` | The port that must be used to contact your API server |
| apiServer.trustedCA | bool | `false` | Indicates that the API Server is exposing a certificate issued by a trusted Certification Authority |
| auth.config.allowEmptyToken | bool | `false` | Set to true to disable the authentication of discovered clusters. NB: use it only for testing installations |
| auth.imageName | string | `"liqo/auth-service"` | auth image repository |
Expand Down
2 changes: 0 additions & 2 deletions deployments/liqo/crds/config.liqo.io_clusterconfigs.yaml
Expand Up @@ -42,8 +42,6 @@ spec:
properties:
address:
type: string
port:
type: string
trustedCA:
type: boolean
type: object
Expand Down
2 changes: 0 additions & 2 deletions deployments/liqo/values.yaml
Expand Up @@ -9,8 +9,6 @@ pullPolicy: "IfNotPresent"
apiServer:
# -- The address that must be used to contact your API server, it needs to be reachable from the clusters that you will peer with (defaults to your master IP)
address: ""
# -- The port that must be used to contact your API server
port: "6443"
# -- Indicates that the API Server is exposing a certificate issued by a trusted Certification Authority
trustedCA: false

Expand Down
1 change: 0 additions & 1 deletion install.sh
Expand Up @@ -461,7 +461,6 @@ function install_liqo() {
--set auth.ingress.host="${LIQO_AUTHSERVER_ADDR:-}" \
--set auth.ingress.class="${LIQO_INGRESS_CLASS:-}" \
--set apiServer.address="${LIQO_APISERVER_ADDR:-}" \
--set apiServer.port="${LIQO_APISERVER_PORT:-}" \
--set auth.ingress.host="${LIQO_AUTHSERVER_ADDR:-}" \
--set auth.portOverride="${LIQO_AUTHSERVER_PORT:-}" >/dev/null ||
fatal "[INSTALL]" "Something went wrong while installing Liqo"
Expand Down
14 changes: 1 addition & 13 deletions internal/auth-service/auth_test.go
Expand Up @@ -11,7 +11,6 @@ import (
"encoding/pem"
"os"
"path/filepath"
"strings"
"testing"
"time"

Expand Down Expand Up @@ -53,16 +52,6 @@ func (man *tokenManagerMock) createToken() error {
return nil
}

// getHost get the address given the address:port string
func getHost(address string) string {
return strings.Split(address, ":")[0]
}

// getPort get the port given the address:port string
func getPort(address string) string {
return strings.Split(address, ":")[1]
}

// getCSR get a CertificateSigningRequest for testing purposes
func getCSR(localClusterID string) (csrBytes []byte, err error) {
key, err := rsa.GenerateKey(rand.Reader, 2048)
Expand Down Expand Up @@ -159,8 +148,7 @@ var _ = Describe("Auth", func() {
useTLS: false,
credentialsValidator: &tokenValidator{},
apiServerConfig: &v1alpha1.APIServerConfig{
Address: getHost(cluster.GetCfg().Host),
Port: getPort(cluster.GetCfg().Host),
Address: cluster.GetCfg().Host,
TrustedCA: false,
},
}
Expand Down
Expand Up @@ -49,7 +49,6 @@ func (c *configMock) GetConfig() *v1alpha1.DiscoveryConfig {
func (c *configMock) GetAPIServerConfig() *v1alpha1.APIServerConfig {
return &v1alpha1.APIServerConfig{
Address: os.Getenv("APISERVER"),
Port: os.Getenv("APISERVER_PORT"),
TrustedCA: false,
}
}
Expand Down
12 changes: 4 additions & 8 deletions pkg/identityManager/identityManager_test.go
Expand Up @@ -36,22 +36,19 @@ import (

type mockApiServerConfigProvider struct {
address string
port string
trustedCA bool
}

func newMockApiServerConfigProvider(address, port string, trustedCA bool) utils.ApiServerConfigProvider {
func newMockAPIServerConfigProvider(address string, trustedCA bool) utils.ApiServerConfigProvider {
return &mockApiServerConfigProvider{
address: address,
port: port,
trustedCA: trustedCA,
}
}

func (mock *mockApiServerConfigProvider) GetAPIServerConfig() *configv1alpha1.APIServerConfig {
return &configv1alpha1.APIServerConfig{
Address: mock.address,
Port: mock.port,
TrustedCA: mock.trustedCA,
}
}
Expand Down Expand Up @@ -220,7 +217,7 @@ var _ = Describe("IdentityManager", func() {
Context("Storage", func() {

It("StoreCertificate", func() {
apiServerConfig := newMockApiServerConfigProvider("127.0.0.1", "6443", false)
apiServerConfig := newMockAPIServerConfigProvider("127.0.0.1", false)

signingIdentityResponse := responsetypes.SigningRequestResponse{
ResponseType: responsetypes.SigningRequestResponseCertificate,
Expand All @@ -241,8 +238,7 @@ var _ = Describe("IdentityManager", func() {
Expect(cnf).NotTo(BeNil())
Expect(cnf.Host).To(Equal(
fmt.Sprintf(
"https://%v:%v", apiServerConfig.GetAPIServerConfig().Address,
apiServerConfig.GetAPIServerConfig().Port)))
"https://%v", apiServerConfig.GetAPIServerConfig().Address)))

// retrieve the remote tenant namespace
remoteNamespace, err := identityMan.GetRemoteTenantNamespace(remoteClusterID, "")
Expand All @@ -251,7 +247,7 @@ var _ = Describe("IdentityManager", func() {
})

It("StoreCertificate IAM", func() {
apiServerConfig := newMockApiServerConfigProvider("127.0.0.1", "6443", false)
apiServerConfig := newMockAPIServerConfigProvider("127.0.0.1", false)

signingIAMResponse := responsetypes.SigningRequestResponse{
ResponseType: responsetypes.SigningRequestResponseIAM,
Expand Down
35 changes: 9 additions & 26 deletions pkg/kubeconfig/create.go
Expand Up @@ -2,8 +2,8 @@ package kubeconfig

import (
"context"
"errors"
"fmt"
"strings"

corev1 "k8s.io/api/core/v1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -13,7 +13,6 @@ import (
"k8s.io/klog"
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"

"github.com/liqotech/liqo/pkg/discovery"
"github.com/liqotech/liqo/pkg/utils"
)

Expand Down Expand Up @@ -56,33 +55,17 @@ func CreateKubeConfigFromServiceAccount(apiServerConfigProvider utils.ApiServerC
// 1. from the ClusterConfig
// 2. defaults to 6443.
func GetApiServerURL(apiServerConfigProvider utils.ApiServerConfigProvider, clientset kubernetes.Interface) (string, error) {
address := apiServerConfigProvider.GetAPIServerConfig().Address
if address == "" {
nodes, err := clientset.CoreV1().Nodes().List(context.TODO(), v1.ListOptions{
LabelSelector: "node-role.kubernetes.io/master",
})
if err != nil {
klog.Error(err)
return "", err
}
if len(nodes.Items) == 0 {
err = errors.New("no APISERVER env variable found and no master node found, one of the two values must be present")
klog.Error(err)
return "", err
}
address, err = discovery.GetAddressFromNodeList(nodes.Items)
if err != nil {
klog.Error(err)
return "", err
}
}
config := apiServerConfigProvider.GetAPIServerConfig()

port := apiServerConfigProvider.GetAPIServerConfig().Port
if port == "" {
port = "6443"
address := config.Address
if address != "" {
if !strings.HasPrefix(address, "https://") {
address = fmt.Sprintf("https://%v", address)
}
return address, nil
}

return fmt.Sprintf("https://%v:%v", address, port), nil
return utils.GetAPIServerAddressFromMasterNode(context.TODO(), clientset)
}

// this function creates a kube-config file for a specified ServiceAccount.
Expand Down
59 changes: 59 additions & 0 deletions pkg/utils/address.go
@@ -0,0 +1,59 @@
package utils

import (
"context"
"fmt"

v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"

"github.com/liqotech/liqo/pkg/discovery"
)

// GetAPIServerAddressFromMasterNode returns the API Server address using the IP of the
// master node of this cluster. The port is always defaulted to 6443.
func GetAPIServerAddressFromMasterNode(ctx context.Context,
clientset kubernetes.Interface) (address string, err error) {
nodes, err := getMasterNodes(ctx, clientset)
if err != nil {
klog.Error(err)
return "", err
}
host, err := discovery.GetAddressFromNodeList(nodes.Items)
if err != nil {
klog.Error(err)
return "", err
}
return fmt.Sprintf("https://%v:6443", host), nil
}

func getMasterNodes(ctx context.Context, clientset kubernetes.Interface) (*v1.NodeList, error) {
labelSelectors := []string{
"node-role.kubernetes.io/control-plane",
"node-role.kubernetes.io/master",
}

nodes := &v1.NodeList{}
var err error
for _, selector := range labelSelectors {
nodes, err = clientset.CoreV1().Nodes().List(ctx, metav1.ListOptions{
LabelSelector: selector,
})
if err != nil {
klog.Error(err)
return nodes, err
}
if len(nodes.Items) != 0 {
break
}
}

if len(nodes.Items) == 0 {
err = fmt.Errorf("no ApiServer.Address variable provided and no master node found, one of the two values must be present")
klog.Error(err)
return nodes, err
}
return nodes, nil
}
120 changes: 120 additions & 0 deletions pkg/utils/address_test.go
@@ -0,0 +1,120 @@
package utils

import (
"context"
"os"
"path/filepath"
"testing"

. "github.com/onsi/ginkgo"
. "github.com/onsi/ginkgo/extensions/table"
. "github.com/onsi/gomega"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"

"github.com/liqotech/liqo/pkg/utils/testutil"
)

func TestAddress(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Address Suite")
}

var _ = Describe("Address", func() {

var (
cluster testutil.Cluster
ctx context.Context
cancel context.CancelFunc
)

BeforeSuite(func() {
ctx, cancel = context.WithCancel(context.Background())

var err error
cluster, _, err = testutil.NewTestCluster([]string{filepath.Join("..", "..", "..", "deployments", "liqo", "crds")})
if err != nil {
By(err.Error())
os.Exit(1)
}
})

AfterSuite(func() {
cancel()

err := cluster.GetEnv().Stop()
if err != nil {
By(err.Error())
os.Exit(1)
}
})

type addressTestcase struct {
node *v1.Node
expectedAddress string
}

DescribeTable("Address table",

func(c addressTestcase) {
client := kubernetes.NewForConfigOrDie(cluster.GetCfg())

node, err := client.CoreV1().Nodes().Create(ctx, c.node, metav1.CreateOptions{})
Expect(err).To(Succeed())
node.Status = *c.node.Status.DeepCopy()
node, err = client.CoreV1().Nodes().Update(ctx, node, metav1.UpdateOptions{})
Expect(err).To(Succeed())

address, err := GetAPIServerAddressFromMasterNode(ctx, client)
Expect(err).To(Succeed())

Expect(address).To(Equal(c.expectedAddress))

Expect(client.CoreV1().Nodes().Delete(ctx, node.Name, metav1.DeleteOptions{})).To(Succeed())
},

Entry("master node", addressTestcase{
node: &v1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: "master-1",
Labels: map[string]string{
"node-role.kubernetes.io/master": "",
},
},
Spec: v1.NodeSpec{},
Status: v1.NodeStatus{
Addresses: []v1.NodeAddress{
{
Type: v1.NodeExternalIP,
Address: "1.2.3.4",
},
},
},
},
expectedAddress: "https://1.2.3.4:6443",
}),

Entry("control plane node", addressTestcase{
node: &v1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: "master-1",
Labels: map[string]string{
"node-role.kubernetes.io/control-plane": "",
},
},
Spec: v1.NodeSpec{},
Status: v1.NodeStatus{
Addresses: []v1.NodeAddress{
{
Type: v1.NodeExternalIP,
Address: "1.2.3.4",
},
},
},
},
expectedAddress: "https://1.2.3.4:6443",
}),
)

})

0 comments on commit 5ae11c1

Please sign in to comment.