Skip to content

Commit

Permalink
Merge pull request #527 from jnummelin/external-api-address
Browse files Browse the repository at this point in the history
Config option for external api address
  • Loading branch information
jnummelin authored Dec 22, 2020
2 parents 67b36fd + 37afdc2 commit 5aa0390
Show file tree
Hide file tree
Showing 12 changed files with 703 additions and 7 deletions.
18 changes: 18 additions & 0 deletions cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/spf13/cobra"

"github.com/k0sproject/k0s/pkg/build"
"github.com/k0sproject/k0s/pkg/kubernetes"
"github.com/k0sproject/k0s/pkg/telemetry"

"github.com/avast/retry-go"
Expand Down Expand Up @@ -200,6 +201,23 @@ func startServer(token string) error {
})
}

// common factory to get the admin kube client that's needed in many components
// TODO: Refactor all needed components to use this factory
adminClientFactory := kubernetes.NewAdminClientFactory(k0sVars)

// One leader elector per controller
// TODO: Make all other needed components use this "global" leader elector
leaderElector := server.NewLeaderElector(clusterConfig, adminClientFactory)
componentManager.Add(leaderElector)

if clusterConfig.Spec.API.ExternalAddress != "" {
componentManager.Add(server.NewEndpointReconciler(
clusterConfig,
leaderElector,
adminClientFactory,
))
}

perfTimer.Checkpoint("starting-component-init")
// init components
if err := componentManager.Init(); err != nil {
Expand Down
3 changes: 2 additions & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ metadata:
name: k0s
spec:
api:
externalAddress: my-lb-address.example.com
address: 192.168.68.106
sans:
- 192.168.68.106
- 192.168.68.106
extraArgs: {}
controllerManager:
extraArgs: {}
Expand Down Expand Up @@ -143,6 +143,7 @@ extensions:

### `spec.api`

- `externalAddress`: If k0s controllers are running behind a loadbalancer provide the loadbalancer address here. This will configure all cluster components to connect to this address and also configures this address to be used when joining new nodes into the cluster.
- `address`: The local address to bind API on. Also used as one of the addresses pushed on the k0s create service certificate on the API. Defaults to first non-local address found on the node.
- `sans`: List of additional addresses to push to API servers serving certificate
- `extraArgs`: Map of key-values (strings) for any extra arguments you wish to pass down to Kubernetes api-server process
Expand Down
13 changes: 13 additions & 0 deletions internal/util/slice.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,16 @@ func IsStringArrayEqual(a1 []string, a2 []string) bool {
}
return false
}

// Unique returns only the unique items from given input slice
func Unique(input []string) []string {
m := make(map[string]bool)
result := make([]string, 0, len(input))
for _, s := range input {
if _, ok := m[s]; !ok {
m[s] = true
result = append(result, s)
}
}
return result
}
34 changes: 33 additions & 1 deletion internal/util/slice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ limitations under the License.
*/
package util

import "testing"
import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestStringSliceContains(t *testing.T) {
type args struct {
Expand Down Expand Up @@ -88,3 +92,31 @@ func TestArrayIsEqual(t *testing.T) {
})
}
}

func TestUnique(t *testing.T) {
tests := []struct {
name string
input []string
want []string
}{
{
"all unique",
[]string{"a", "b", "c"},
[]string{"a", "b", "c"},
},
{
"some non unique",
[]string{"c", "a", "b", "b", "c"},
[]string{"c", "a", "b"},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := Unique(tt.input)
assert.Equal(t, tt.want, got)

})
}

}
25 changes: 22 additions & 3 deletions pkg/apis/v1beta1/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,10 @@ type ClusterSpec struct {

// APISpec ...
type APISpec struct {
Address string `yaml:"address"`
SANs []string `yaml:"sans"`
ExtraArgs map[string]string `yaml:"extraArgs"`
Address string `yaml:"address"`
ExternalAddress string `yaml:"externalAddress"`
SANs []string `yaml:"sans"`
ExtraArgs map[string]string `yaml:"extraArgs"`
}

// ControllerManagerSpec ...
Expand Down Expand Up @@ -88,14 +89,32 @@ func (c *ClusterConfig) Validate() []error {

// APIAddress ...
func (a *APISpec) APIAddress() string {
if a.ExternalAddress != "" {
return fmt.Sprintf("https://%s:6443", a.ExternalAddress)
}
return fmt.Sprintf("https://%s:6443", a.Address)
}

// K0sControlPlaneAPIAddress returns the controller join APIs address
func (a *APISpec) K0sControlPlaneAPIAddress() string {
if a.ExternalAddress != "" {
return fmt.Sprintf("https://%s:9443", a.ExternalAddress)
}
return fmt.Sprintf("https://%s:9443", a.Address)
}

// Sans return the given SANS plus all local adresses and externalAddress if given
func (a *APISpec) Sans() []string {
sans, _ := util.AllAddresses()
sans = append(sans, a.Address)
sans = append(sans, a.SANs...)
if a.ExternalAddress != "" {
sans = append(sans, a.ExternalAddress)
}

return util.Unique(sans)
}

// FromYaml ...
func FromYaml(filename string) (*ClusterConfig, error) {
buf, err := ioutil.ReadFile(filename)
Expand Down
35 changes: 35 additions & 0 deletions pkg/apis/v1beta1/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,38 @@ spec:
assert.Equal(t, 1, len(errors))
assert.Equal(t, "unsupported network provider: invalidProvider", errors[0].Error())
}

func TestApiExternalAddress(t *testing.T) {
yamlData := `
apiVersion: k0s.k0sproject.io/v1beta1
kind: Cluster
metadata:
name: foobar
spec:
api:
externalAddress: foo.bar.com
address: 1.2.3.4
`

c, err := fromYaml(t, yamlData)
assert.NoError(t, err)
assert.Equal(t, "https://foo.bar.com:6443", c.Spec.API.APIAddress())
assert.Equal(t, "https://foo.bar.com:9443", c.Spec.API.K0sControlPlaneAPIAddress())
}

func TestApiNoExternalAddress(t *testing.T) {
yamlData := `
apiVersion: k0s.k0sproject.io/v1beta1
kind: Cluster
metadata:
name: foobar
spec:
api:
address: 1.2.3.4
`

c, err := fromYaml(t, yamlData)
assert.NoError(t, err)
assert.Equal(t, "https://1.2.3.4:6443", c.Spec.API.APIAddress())
assert.Equal(t, "https://1.2.3.4:9443", c.Spec.API.K0sControlPlaneAPIAddress())
}
Loading

0 comments on commit 5aa0390

Please sign in to comment.