storage/kubernetes: allow arbitrary client IDs
Use a hash algorithm to match client IDs to Kubernetes object names. Because cryptographic hash algorithms produce sums larger than a Kubernetes name can fit, a non-cryptographic hash is used instead. Hash collisions are checked and result in errors.
This commit is contained in:
@@ -4,10 +4,13 @@ import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/base32"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"hash/fnv"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
@@ -31,6 +34,14 @@ type client struct {
|
||||
baseURL string
|
||||
namespace string
|
||||
|
||||
// Hash function to map IDs (which could span a large range) to Kubernetes names.
|
||||
// While this is not currently upgradable, it could be in the future.
|
||||
//
|
||||
// The default hash is a non-cryptographic hash, because cryptographic hashes
|
||||
// always produce sums too long to fit into a Kubernetes name. Because of this,
|
||||
// gets, updates, and deletes are _always_ checked for collisions.
|
||||
hash func() hash.Hash
|
||||
|
||||
// API version of the oidc resources. For example "oidc.coreos.com". This is
|
||||
// currently not configurable, but could be in the future.
|
||||
apiVersion string
|
||||
@@ -40,6 +51,18 @@ type client struct {
|
||||
cancel context.CancelFunc
|
||||
}
|
||||
|
||||
// idToName maps an arbitrary ID, such as an email or client ID to a Kubernetes object name.
|
||||
func (c *client) idToName(s string) string {
|
||||
return idToName(s, c.hash)
|
||||
}
|
||||
|
||||
// Kubernetes names must match the regexp '[a-z0-9]([-a-z0-9]*[a-z0-9])?'.
|
||||
var encoding = base32.NewEncoding("abcdefghijklmnopqrstuvwxyz234567")
|
||||
|
||||
func idToName(s string, h func() hash.Hash) string {
|
||||
return strings.TrimRight(encoding.EncodeToString(h().Sum([]byte(s))), "=")
|
||||
}
|
||||
|
||||
func (c *client) urlFor(apiVersion, namespace, resource, name string) string {
|
||||
basePath := "apis/"
|
||||
if apiVersion == "v1" {
|
||||
@@ -277,6 +300,7 @@ func newClient(cluster k8sapi.Cluster, user k8sapi.AuthInfo, namespace string) (
|
||||
return &client{
|
||||
client: &http.Client{Transport: t},
|
||||
baseURL: cluster.Server,
|
||||
hash: func() hash.Hash { return fnv.New64() },
|
||||
namespace: namespace,
|
||||
apiVersion: "oidc.coreos.com/v1",
|
||||
}, nil
|
||||
|
Reference in New Issue
Block a user