Skip to content

Commit

Permalink
Provide cluster name and cluster base domain to baremetal runtimecfg
Browse files Browse the repository at this point in the history
Signed-off-by: Christoph Stäbler <cstabler@redhat.com>
  • Loading branch information
creydr committed Jan 20, 2022
1 parent 45d7287 commit 3610dbc
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 2 deletions.
64 changes: 64 additions & 0 deletions pkg/controller/template/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,8 @@ func renderTemplate(config RenderConfig, path string, b []byte) ([]byte, error)
funcs["onPremPlatformKeepalivedEnableUnicast"] = onPremPlatformKeepalivedEnableUnicast
funcs["urlHost"] = urlHost
funcs["urlPort"] = urlPort
funcs["clusterName"] = clusterName
funcs["clusterBaseDomain"] = clusterBaseDomain
tmpl, err := template.New(path).Funcs(funcs).Parse(string(b))
if err != nil {
return nil, fmt.Errorf("failed to parse template %s: %v", path, err)
Expand Down Expand Up @@ -547,3 +549,65 @@ func urlPort(u string) (interface{}, error) {
return "", fmt.Errorf("unknown scheme in %s", u)
}
}

func clusterName(cfg RenderConfig) (interface{}, error) {
serverURL, err := url.Parse(cfg.Infra.Status.APIServerURL)
if err != nil {
return nil, err
}

return clusterNameFromInfrastructureNameAndApiHostname(cfg.Infra.Status.InfrastructureName, serverURL.Hostname())
}

func clusterBaseDomain(cfg RenderConfig) (interface{}, error) {
return cfg.DNS.Spec.BaseDomain, nil
}

// clusterNameFromInfrastructureNameAndApiHostname returns the most plausible
// cluster name based on the information of the infrastructureName and
// apiHostname. It checks it by cutting off parts at the end of the
// infrastructureName and checking if it is contained in the api servers host
// name.
//
// e.g. infrastructureName: "sub-my-cluster-nzml9" and api server host
// name: "api.sub.my-cluster.ocp.redhat.com" --> removes the "-nzml9" from
// the end of the instrastructure name.
func clusterNameFromInfrastructureNameAndApiHostname(infrastructureName, apiHostname string) (string, error) {
parts := strings.Split(infrastructureName, "-")
for i := len(parts) - 1; i > 0; i-- {
infraNameShortend := strings.Join(parts[:i], "-")

possibleClusternames := clusterNameCombinations(infraNameShortend)
for _, possibleClustername := range possibleClusternames {
if !strings.HasSuffix(possibleClustername, ".") && strings.Contains(apiHostname, possibleClustername) {
return possibleClustername, nil
}
}
}

return "", fmt.Errorf("could find a matching of %s in %s", infrastructureName, apiHostname)
}

// clusterNameCombinations returns a list of strings with all combinations with
// a dash replaced by a dot in the given string.
//
// given nameRaw with "a-b-c" it will return a slice containing a-b-c, a.b-c,
// a-b.c and a.b.c
func clusterNameCombinations(nameRaw string) []string {
parts := strings.SplitN(nameRaw, "-", 2)
if len(parts) == 2 {
suffixes := clusterNameCombinations(strings.Join(parts[1:], "-"))

var possibleNames []string
for _, suffix := range suffixes {
possibleNames = append(possibleNames, fmt.Sprintf("%s.%s", parts[0], suffix))
possibleNames = append(possibleNames, fmt.Sprintf("%s-%s", parts[0], suffix))
}

return possibleNames
} else if len(parts) == 1 {
return parts
}

return nil
}
103 changes: 101 additions & 2 deletions pkg/controller/template/render_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,9 @@ import (
ign3types "github.com/coreos/ignition/v2/config/v3_2/types"
configv1 "github.com/openshift/api/config/v1"
"github.com/openshift/library-go/pkg/cloudprovider"
"k8s.io/client-go/kubernetes/scheme"

mcfgv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"
ctrlcommon "github.com/openshift/machine-config-operator/pkg/controller/common"
"k8s.io/client-go/kubernetes/scheme"
)

func TestMain(m *testing.M) {
Expand Down Expand Up @@ -498,3 +497,103 @@ func verifyIgn(actual [][]byte, dir string, t *testing.T) {
t.Errorf("can't find expected file:\n%v", key)
}
}

func Test_clusterNameFromInfrastructureName(t *testing.T) {
tests := []struct {
name string
infrastructureName string
apiHostname string
want string
wantErr bool
}{
{
name: "Should return cluster name",
infrastructureName: "my-cluster-nzml9",
apiHostname: "api.my-cluster.ocp.redhat.com",
want: "my-cluster",
wantErr: false,
},
{
name: "Should be able to handle dots ('.') in cluster name",
infrastructureName: "sub-sub-my-clustername-foobar",
apiHostname: "api-int.sub.sub.my-clustername.ocp.redhat.com",
want: "sub.sub.my-clustername",
wantErr: false,
},
{
name: "Should be able to handle a mix of dots ('.') and dashes ('-') in cluster name",
infrastructureName: "sub-sub-sub-my-clustername-foobar",
apiHostname: "api-int.sub-sub.sub.my-clustername.ocp.redhat.com",
want: "sub-sub.sub.my-clustername",
wantErr: false,
},
{
name: "Should return error if clustername could not be found",
infrastructureName: "foo-bar",
apiHostname: "api-int.ocp.redhat.com",
want: "",
wantErr: true,
},
{
name: "Should return error if infrastructureName is empty",
infrastructureName: "",
apiHostname: "api-int.ocp.redhat.com",
want: "",
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := clusterNameFromInfrastructureNameAndApiHostname(tt.infrastructureName, tt.apiHostname)
if (err != nil) != tt.wantErr {
t.Errorf("clusterNameFromInfrastructureName(%s, %s) = \"%s\" error = \"%v\", wantErr \"%v\"", tt.infrastructureName, tt.apiHostname, got, err, tt.wantErr)
return
}
if got != tt.want {
t.Errorf("clusterNameFromInfrastructureName(%s, %s) = \"%v\", want \"%v\"", tt.infrastructureName, tt.apiHostname, got, tt.want)
}
})
}
}

func Test_clusterNameCombinations(t *testing.T) {
tests := []struct {
name string
clusterNameRaw string
want []string
}{
{
name: "a",
clusterNameRaw: "a-b-c-d",
want: []string{
"a-b-c-d",
"a.b-c-d",
"a-b.c-d",
"a.b.c-d",
"a-b-c.d",
"a.b-c.d",
"a-b.c.d",
"a.b.c.d",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := clusterNameCombinations(tt.clusterNameRaw)
if len(got) != len(tt.want) {
t.Errorf("len of clusterNameCombinations(%s) = %d, want %d", tt.clusterNameRaw, len(got), len(tt.want))
}
for _, wantElement := range tt.want {
found := false
for _, gotElement := range got {
if gotElement == wantElement {
found = true
}
}
if !found {
t.Errorf("didn't find %s in clusterNameCombinations(%s) = %v", wantElement, tt.clusterNameRaw, got)
}
}
})
}
}
9 changes: 9 additions & 0 deletions templates/common/on-prem/files/keepalived.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ contents:
- "/config"
- "--out-dir"
- "/etc/keepalived"
env:
- name: CLUSTER_NAME
value: "{{ clusterName . }}"
- name: CLUSTER_BASE_DOMAIN
value: "{{ clusterBaseDomain . }}"
resources: {}
volumeMounts:
- name: kubeconfig
Expand Down Expand Up @@ -156,6 +161,10 @@ contents:
value: "{{ onPremPlatformKeepalivedEnableUnicast . }}"
- name: IS_BOOTSTRAP
value: "no"
- name: CLUSTER_NAME
value: "{{ clusterName . }}"
- name: CLUSTER_BASE_DOMAIN
value: "{{ clusterBaseDomain . }}"
command:
- dynkeepalived
- "/var/lib/kubelet/kubeconfig"
Expand Down

0 comments on commit 3610dbc

Please sign in to comment.