Add root cert expiry check command (#434)

* add root cert expiry check command

* fix helm repo url
This commit is contained in:
Yaron Schneider 2020-08-13 18:08:34 -07:00 committed by GitHub
parent ac1d1b7a94
commit 294fa19a20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 77 additions and 24 deletions

View File

@ -358,6 +358,12 @@ To specify a custom directory:
$ dapr mtls export -o certs
```
### Check root certificate expiry
```
$ dapr mtls expiry
```
This can be used when upgrading to a newer version of Dapr, as it's recommended to carry over the existing certs for a zero downtime upgrade.
### List Components

View File

@ -9,6 +9,7 @@ import (
"fmt"
"os"
"path/filepath"
"time"
"github.com/dapr/cli/pkg/kubernetes"
"github.com/dapr/cli/pkg/print"
@ -50,10 +51,26 @@ var ExportCMD = &cobra.Command{
},
}
var ExpiryCMD = &cobra.Command{
Use: "expiry",
Short: "Checks the expiry of the root certificate",
Run: func(cmd *cobra.Command, args []string) {
expiry, err := kubernetes.Expiry()
if err != nil {
print.FailureStatusEvent(os.Stdout, fmt.Sprintf("error getting root cert expiry: %s", err))
return
}
duration := int(expiry.Sub(time.Now().UTC()).Hours())
fmt.Println(fmt.Sprintf("Root certificate expires in %v hours. Expiry date: %s", duration, expiry.String()))
},
}
func init() {
MTLSCmd.Flags().BoolVarP(&kubernetesMode, "kubernetes", "k", false, "Check if mTLS is enabled in a Kubernetes cluster")
ExportCMD.Flags().StringVarP(&exportPath, "out", "o", ".", "Output directory path to save the certs")
MTLSCmd.MarkFlagRequired("kubernetes")
MTLSCmd.AddCommand(ExportCMD)
MTLSCmd.AddCommand(ExpiryCMD)
RootCmd.AddCommand(MTLSCmd)
}

View File

@ -28,7 +28,7 @@ import (
const (
daprReleaseName = "dapr"
daprHelmRepo = "https://dapr.github.io/dapr-helm-charts.io"
daprHelmRepo = "https://daprio.azurecr.io/helm/v1/repo"
daprLatestVersion = "latest"
)

View File

@ -1,12 +1,17 @@
package kubernetes
import (
"crypto/x509"
"encoding/pem"
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"time"
"github.com/dapr/dapr/pkg/apis/configuration/v1alpha1"
corev1 "k8s.io/api/core/v1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
@ -53,42 +58,67 @@ func ExportTrustChain(outputDir string) error {
}
}
_, client, err := GetKubeConfigClient()
secret, err := getTrustChainSecret()
if err != nil {
return err
}
ca := secret.Data["ca.crt"]
issuerCert := secret.Data["issuer.crt"]
issuerKey := secret.Data["issuer.key"]
err = ioutil.WriteFile(filepath.Join(outputDir, "ca.crt"), ca, 0600)
if err != nil {
return err
}
err = ioutil.WriteFile(filepath.Join(outputDir, "issuer.crt"), issuerCert, 0600)
if err != nil {
return err
}
err = ioutil.WriteFile(filepath.Join(outputDir, "issuer.key"), issuerKey, 0600)
if err != nil {
return err
}
return nil
}
func getTrustChainSecret() (*corev1.Secret, error) {
_, client, err := GetKubeConfigClient()
if err != nil {
return nil, err
}
c, err := getSystemConfig()
if err != nil {
return err
return nil, err
}
res, err := client.CoreV1().Secrets(c.GetNamespace()).List(meta_v1.ListOptions{})
if err != nil {
return err
return nil, err
}
for _, i := range res.Items {
if i.GetName() == trustBundleSecretName {
ca := i.Data["ca.crt"]
issuerCert := i.Data["issuer.crt"]
issuerKey := i.Data["issuer.key"]
err := ioutil.WriteFile(filepath.Join(outputDir, "ca.crt"), ca, 0600)
if err != nil {
return err
}
err = ioutil.WriteFile(filepath.Join(outputDir, "issuer.crt"), issuerCert, 0600)
if err != nil {
return err
}
err = ioutil.WriteFile(filepath.Join(outputDir, "issuer.key"), issuerKey, 0600)
if err != nil {
return err
}
break
return &i, nil
}
}
return nil
return nil, fmt.Errorf("could not find trust chain secret named %s in namespace %s", trustBundleSecretName, c.GetNamespace())
}
// Expiry returns the expiry time for the root cert
func Expiry() (*time.Time, error) {
secret, err := getTrustChainSecret()
if err != nil {
return nil, err
}
caCrt := secret.Data["ca.crt"]
block, _ := pem.Decode(caCrt)
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, err
}
return &cert.NotAfter, nil
}