smsgw: productionize, implement kube/mirko
This productionizes smsgw.
We also add some jsonnet machinery to provide a unified service for Go
micro/mirkoservices.
This machinery provides all the nice stuff:
- a deployment
- a service for all your types of pots
- TLS certificates for HSPKI
We also update and test hspki for a new name scheme.
Change-Id: I292d00f858144903cbc8fe0c1c26eb1180d636bc
diff --git a/go/pki/grpc.go b/go/pki/grpc.go
index 6d8f173..1720ad8 100644
--- a/go/pki/grpc.go
+++ b/go/pki/grpc.go
@@ -36,6 +36,7 @@
flagCAPath string
flagCertificatePath string
flagKeyPath string
+ flagPKICluster string
flagPKIRealm string
flagPKIDisable bool
@@ -53,7 +54,8 @@
flag.StringVar(&flagCAPath, "hspki_tls_ca_path", "pki/ca.pem", "Path to PKI CA certificate")
flag.StringVar(&flagCertificatePath, "hspki_tls_certificate_path", "pki/service.pem", "Path to PKI service certificate")
flag.StringVar(&flagKeyPath, "hspki_tls_key_path", "pki/service-key.pem", "Path to PKI service private key")
- flag.StringVar(&flagPKIRealm, "hspki_realm", "svc.cluster.local", "PKI realm")
+ flag.StringVar(&flagPKICluster, "hspki_cluster", "local.hswaw.net", "FQDN of cluster on which this service runs")
+ flag.StringVar(&flagPKIRealm, "hspki_realm", "hswaw.net", "Cluster realm (top level from which we accept foreign cluster certs)")
flag.BoolVar(&flagPKIDisable, "hspki_disable", false, "Disable PKI entirely (insecure!)")
}
@@ -81,14 +83,39 @@
if !strings.HasSuffix(name, "."+flagPKIRealm) {
return nil, fmt.Errorf("invalid realm")
}
- service := strings.TrimSuffix(name, "."+flagPKIRealm)
- parts := strings.Split(service, ".")
- if len(parts) != 2 {
- return nil, fmt.Errorf("invalid job/principal format")
+
+ inRealm := strings.TrimSuffix(name, "."+flagPKIRealm)
+
+ special := []string{"person", "external"}
+
+ for _, s := range special {
+ // Special case for people running jobs from workstations, or for non-cluster services.
+ if strings.HasSuffix(inRealm, "."+s) {
+ asPerson := strings.TrimSuffix(inRealm, "."+s)
+ parts := strings.Split(asPerson, ".")
+ if len(parts) != 1 {
+ return nil, fmt.Errorf("invalid person fqdn")
+ }
+ return &ClientInfo{
+ Cluster: fmt.Sprintf("%s.%s", s, flagPKIRealm),
+ Principal: parts[0],
+ Job: "",
+ }, nil
+ }
}
+
+ parts := strings.Split(inRealm, ".")
+ if len(parts) != 4 {
+ return nil, fmt.Errorf("invalid job/principal format for in-cluster")
+ }
+ if parts[2] != "svc" {
+ return nil, fmt.Errorf("can only refer to services within cluster")
+ }
+ clusterShort := parts[3]
+
return &ClientInfo{
- Realm: flagPKIRealm,
- Principal: parts[1],
+ Cluster: fmt.Sprintf("%s.%s", clusterShort, flagPKIRealm),
+ Principal: fmt.Sprintf("%s.svc", parts[1]),
Job: parts[0],
}, nil
}
@@ -137,15 +164,24 @@
// ClientInfo contains information about the HSPKI authentication data of the
// gRPC client that has made the request.
type ClientInfo struct {
- Realm string
+ Cluster string
Principal string
Job string
}
// String returns a human-readable representation of the ClientInfo in the
-// form "job=foo, principal=bar, realm=baz".
+// form "job=foo, principal=bar.svc, cluster=baz.hswaw.net".
func (c *ClientInfo) String() string {
- return fmt.Sprintf("job=%q, principal=%q, realm=%q", c.Job, c.Principal, c.Realm)
+ return fmt.Sprintf("job=%q, principal=%q, cluster=%q", c.Job, c.Principal, c.Cluster)
+}
+
+// Person returns a reference to a person's ID if the ClientInfo describes a person.
+// Otherwise, it returns an empty string.
+func (c *ClientInfo) Person() string {
+ if c.Cluster != fmt.Sprintf("person.%s", flagPKIRealm) {
+ return ""
+ }
+ return c.Principal
}
// ClientInfoFromContext returns ClientInfo from a gRPC service context.