api.go 2.48 KB
Newer Older
ale's avatar
ale committed
1
package autoradio
2 3

import (
4
	"crypto/rand"
5
	"encoding/base32"
ale's avatar
ale committed
6
	"fmt"
ale's avatar
ale committed
7
	"hash/crc32"
8
	"strings"
ale's avatar
ale committed
9 10
)

11
const (
ale's avatar
ale committed
12 13 14 15
	// All our keys are stored in etcd below this prefix. The
	// slash is used as hierarchy separator for our keyspace.
	EtcdPrefix = "autoradio/"

ale's avatar
ale committed
16 17 18
	// 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.
ale's avatar
ale committed
19
	MountPrefix = EtcdPrefix + "icecast/mounts/"
20

ale's avatar
ale committed
21
	// Paths for the cluster runtime data. Whenever the format of
22 23 24 25
	// 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).
ale's avatar
ale committed
26 27
	ABIVersion = "4"

28
	// Prefixes for the etcd-based leader elections.
ale's avatar
ale committed
29 30 31
	ElectionPrefix           = EtcdPrefix + "election/" + ABIVersion + "/"
	IcecastElectionPrefix    = ElectionPrefix + "icecast/"
	TranscoderElectionPrefix = ElectionPrefix + "transcode/"
ale's avatar
ale committed
32

33
	// Prefix for the streams served directly by Icecast.
34
	IcecastMountPrefix = "/_stream"
ale's avatar
ale committed
35 36

	// Prefixes for etcd-based service discovery.
37 38 39
	EndpointPrefix       = EtcdPrefix + "endpoints/" + ABIVersion + "/"
	PublicEndpointPrefix = EndpointPrefix + "frontend/public/"
	StatusEndpointPrefix = EndpointPrefix + "frontend/status/"
40
)
ale's avatar
ale committed
41

42 43 44 45
// 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
46

ale's avatar
ale committed
47
// MountPathToIcecastPath returns the Icecast mount path for the given
ale's avatar
ale committed
48
// public mount name.
ale's avatar
ale committed
49 50
func MountPathToIcecastPath(mountPath string) string {
	return IcecastMountPrefix + mountPath
51 52
}

ale's avatar
ale committed
53
// IcecastPathToMountPath returns the public mount name from an
ale's avatar
ale committed
54 55 56
// Icecast mount path. If 'path' does not start with
// IcecastMountPrefix, it is returned unchanged (though arguably this
// should be an error).
ale's avatar
ale committed
57
func IcecastPathToMountPath(path string) string {
58 59 60
	return strings.TrimPrefix(path, IcecastMountPrefix)
}

61 62
// GeneratePassword returns a new random password.
func GeneratePassword() string {
63
	b := make([]byte, 20)
ale's avatar
ale committed
64 65 66
	if _, err := rand.Read(b); err != nil {
		panic(err)
	}
67
	return strings.ToLower(base32.StdEncoding.EncodeToString(b))
68
}
ale's avatar
ale committed
69 70 71 72 73 74

// 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)))
}