Skip to content

Commit

Permalink
feat(installer): support certificate chain (#975)
Browse files Browse the repository at this point in the history
  • Loading branch information
Leo Ryu committed Dec 6, 2020
1 parent afeb2da commit 22b87fe
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 33 deletions.
36 changes: 9 additions & 27 deletions cmd/tke-installer/app/installer/installer.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ import (
"strings"
"time"

"tkestack.io/tke/pkg/util/validation"

"github.com/emicklei/go-restful"
"github.com/pkg/errors"
"github.com/segmentio/ksuid"
Expand Down Expand Up @@ -733,16 +731,9 @@ func (t *TKE) validateConfig(config types.Config) *apierrors.StatusError {
}
}

var dnsNames []string
if config.Gateway != nil && config.Gateway.Domain != "" {
dnsNames = append(dnsNames, config.Gateway.Domain)
}
if config.Registry.TKERegistry != nil {
dnsNames = append(dnsNames, config.Registry.TKERegistry.Domain, "*."+config.Registry.TKERegistry.Domain)
}
if config.Gateway != nil && config.Gateway.Cert.ThirdPartyCert != nil {
statusError := t.validateCertAndKey(config.Gateway.Cert.ThirdPartyCert.Certificate,
config.Gateway.Cert.ThirdPartyCert.PrivateKey, dnsNames)
config.Gateway.Cert.ThirdPartyCert.PrivateKey, config.Gateway.Domain)
if statusError != nil {
return statusError
}
Expand All @@ -751,38 +742,29 @@ func (t *TKE) validateConfig(config types.Config) *apierrors.StatusError {
return nil
}

func (t *TKE) validateCertAndKey(certificate []byte, privateKey []byte, dnsNames []string) *apierrors.StatusError {
func (t *TKE) validateCertAndKey(certificate []byte, privateKey []byte, dnsName string) *apierrors.StatusError {
if (certificate != nil && privateKey == nil) || (certificate == nil && privateKey != nil) {
return apierrors.NewBadRequest("certificate and privateKey must offer together")
}

if certificate != nil {
cert, err := tls.X509KeyPair(certificate, privateKey)
_, err := tls.X509KeyPair(certificate, privateKey)
if err != nil {
return apierrors.NewBadRequest(err.Error())
}
if len(cert.Certificate) != 1 {
return apierrors.NewBadRequest("certificate must only has one cert")
}

certs1, err := certutil.ParseCertsPEM(certificate)
if err != nil {
return apierrors.NewBadRequest(err.Error())
}
for _, one := range dnsNames {
if !matchDNSName(certs1[0].DNSNames, one) {
return apierrors.NewBadRequest(fmt.Sprintf("certificate DNSNames must contains %v", one))
}
err = certs1[0].VerifyHostname(dnsName)
if err != nil {
return apierrors.NewBadRequest(err.Error())
}
}

return nil
}

func matchDNSName(certDNSNames []string, dnsName string) bool {
dotIdx := strings.Index(dnsName, ".")
return funk.Contains(certDNSNames, dnsName) || validation.IsValidDNSName(dnsName) && dotIdx > -1 && funk.Contains(certDNSNames, "*"+dnsName[dotIdx:])
}

// validateResource validate the cpu and memory of cluster machines whether meets the requirements.
func (t *TKE) validateResource(cluster *platformv1.Cluster) *apierrors.StatusError {
var (
Expand Down Expand Up @@ -1521,8 +1503,8 @@ func (t *TKE) installTKEGateway(ctx context.Context) error {
option["TenantID"] = t.Para.Config.Auth.TKEAuth.TenantID
}
if t.Para.Config.Gateway.Cert.ThirdPartyCert != nil {
option["ServerCrt"] = t.Para.Config.Gateway.Cert.ThirdPartyCert.Certificate
option["ServerKey"] = t.Para.Config.Gateway.Cert.ThirdPartyCert.PrivateKey
option["ServerCrt"] = string(t.Para.Config.Gateway.Cert.ThirdPartyCert.Certificate)
option["ServerKey"] = string(t.Para.Config.Gateway.Cert.ThirdPartyCert.PrivateKey)
}
err := apiclient.CreateResourceWithDir(ctx, t.globalClient, "manifests/tke-gateway/*.yaml", option)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion cmd/tke-installer/app/installer/installer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func TestTKE_validateCertAndKey(t *testing.T) {
err := tke.validateCertAndKey(
pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: cert.Raw}),
pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)}),
[]string{"console.tke.com", "registry.tke.com", "*.registry.tke.com"},
"console.tke.com",
)
assert.True(t, err == nil)
}
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,9 @@ data:
passthrough:
caFile: /app/certs/ca.crt
{{- end }}


{{- if not .SelfSigned }}
server.crt: |
{{ .ServerCrt }}
{{ .ServerCrt | spaces 4 }}
server.key: |
{{ .ServerKey }}
{{ .ServerKey | spaces 4 }}
{{- end }}
8 changes: 7 additions & 1 deletion pkg/util/template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ package template
import (
"bytes"
"io/ioutil"
"strings"
"text/template"

"github.com/pkg/errors"
Expand All @@ -39,7 +40,7 @@ func ParseFile(filename string, obj interface{}) ([]byte, error) {
// ParseString validates and parses passed as argument template
func ParseString(strtmpl string, obj interface{}) ([]byte, error) {
var buf bytes.Buffer
tmpl, err := template.New("template").Parse(strtmpl)
tmpl, err := template.New("template").Funcs(template.FuncMap{"spaces": spaces}).Parse(strtmpl)
if err != nil {
return nil, errors.Wrap(err, "error when parsing template")
}
Expand All @@ -49,3 +50,8 @@ func ParseString(strtmpl string, obj interface{}) ([]byte, error) {
}
return buf.Bytes(), nil
}

func spaces(n int, v string) string {
pad := strings.Repeat(" ", n)
return pad + strings.Replace(v, "\n", "\n"+pad, -1)
}

0 comments on commit 22b87fe

Please sign in to comment.