api.go 2.48 KiB
package autoradio
import (
"crypto/rand"
"encoding/base32"
"fmt"
"hash/crc32"
"strings"
)
const (
// All our keys are stored in etcd below this prefix. The
// slash is used as hierarchy separator for our keyspace.
EtcdPrefix = "autoradio/"
// MountPrefix stores the path to the mount configuration in
// etcd. This should never change between releases, upgrades
// to the configuration format should be backwards-compatible.
MountPrefix = EtcdPrefix + "icecast/mounts/"
// Paths for the cluster runtime data. Whenever the format of
// this data changes, the ABIVersion should be increased. A
// rolling restart of the cluster will then seamlessly cause a
// transition to the new consensus (the cluster will be
// partitioned in the meantime).
ABIVersion = "4"
// Prefixes for the etcd-based leader elections.
ElectionPrefix = EtcdPrefix + "election/" + ABIVersion + "/"
IcecastElectionPrefix = ElectionPrefix + "icecast/"
TranscoderElectionPrefix = ElectionPrefix + "transcode/"
// Prefix for the streams served directly by Icecast.
IcecastMountPrefix = "/_stream"
// Prefixes for etcd-based service discovery.
EndpointPrefix = EtcdPrefix + "endpoints/" + ABIVersion + "/"
PublicEndpointPrefix = EndpointPrefix + "frontend/public/"
StatusEndpointPrefix = EndpointPrefix + "frontend/status/"
)
// IcecastPort is the port that the Icecast server will listen
// on. Since we fully manage the system-wide Icecast instance,
// there's not much point in making this configurable.
var IcecastPort = 8000
// MountPathToIcecastPath returns the Icecast mount path for the given
// public mount name.
func MountPathToIcecastPath(mountPath string) string {
return IcecastMountPrefix + mountPath
}
// IcecastPathToMountPath returns the public mount name from an
// Icecast mount path. If 'path' does not start with
// IcecastMountPrefix, it is returned unchanged (though arguably this
// should be an error).
func IcecastPathToMountPath(path string) string {
return strings.TrimPrefix(path, IcecastMountPrefix)
}
// GeneratePassword returns a new random password.
func GeneratePassword() string {
b := make([]byte, 20)
if _, err := rand.Read(b); err != nil {
panic(err)
}
return strings.ToLower(base32.StdEncoding.EncodeToString(b))
}
// GenerateUsername returns a username somehow related to the name of
// the mount, possibly unique (but not actually guaranteed to be so).
func GenerateUsername(path string) string {
return fmt.Sprintf("source%d", crc32.ChecksumIEEE([]byte(path)))
}