mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-09 23:24:05 -08:00
marathon-sd - change port gathering strategy, support for container networking (#4499)
* marathon-sd - change port gathering strategy, add support for container networking - removed unnecessary error check on HTTPClientConfig.Validate() - renamed PortDefinitions and PortMappings to PortDefinition and PortMapping respectively - extended data model for extra parsed fields from Marathon json - support container networking on Marathon 1.5+ (target Task.IPAddresses.x.Address) - expanded test suite to cover all new cases - test: cancel context when reading from doneCh before returning from function - test: split test suite into Ports/PortMappings/PortDefinitions Signed-off-by: Timo Beckers <timo@incline.eu>
This commit is contained in:
parent
1a5a3d3be6
commit
1c9fbd65c4
|
@ -107,11 +107,7 @@ func (c *SDConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
|
|||
if (len(c.HTTPClientConfig.BearerToken) > 0 || len(c.HTTPClientConfig.BearerTokenFile) > 0) && (len(c.AuthToken) > 0 || len(c.AuthTokenFile) > 0) {
|
||||
return fmt.Errorf("marathon_sd: at most one of bearer_token, bearer_token_file, auth_token & auth_token_file must be configured")
|
||||
}
|
||||
if err := c.HTTPClientConfig.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return c.HTTPClientConfig.Validate()
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -278,31 +274,47 @@ func (d *Discovery) fetchTargetGroups() (map[string]*targetgroup.Group, error) {
|
|||
|
||||
// Task describes one instance of a service running on Marathon.
|
||||
type Task struct {
|
||||
ID string `json:"id"`
|
||||
Host string `json:"host"`
|
||||
Ports []uint32 `json:"ports"`
|
||||
ID string `json:"id"`
|
||||
Host string `json:"host"`
|
||||
Ports []uint32 `json:"ports"`
|
||||
IPAddresses []IPAddress `json:"ipAddresses"`
|
||||
}
|
||||
|
||||
// PortMappings describes in which port the process are binding inside the docker container.
|
||||
type PortMappings struct {
|
||||
Labels map[string]string `json:"labels"`
|
||||
// IPAddress describes the address and protocol the container's network interface is bound to.
|
||||
type IPAddress struct {
|
||||
Address string `json:"ipAddress"`
|
||||
Proto string `json:"protocol"`
|
||||
}
|
||||
|
||||
// PortMapping describes in which port the process are binding inside the docker container.
|
||||
type PortMapping struct {
|
||||
Labels map[string]string `json:"labels"`
|
||||
ContainerPort uint32 `json:"containerPort"`
|
||||
ServicePort uint32 `json:"servicePort"`
|
||||
}
|
||||
|
||||
// DockerContainer describes a container which uses the docker runtime.
|
||||
type DockerContainer struct {
|
||||
Image string `json:"image"`
|
||||
PortMappings []PortMappings `json:"portMappings"`
|
||||
Image string `json:"image"`
|
||||
PortMappings []PortMapping `json:"portMappings"`
|
||||
}
|
||||
|
||||
// Container describes the runtime an app in running in.
|
||||
type Container struct {
|
||||
Docker DockerContainer `json:"docker"`
|
||||
PortMappings []PortMappings `json:"portMappings"`
|
||||
PortMappings []PortMapping `json:"portMappings"`
|
||||
}
|
||||
|
||||
// PortDefinitions describes which load balancer port you should access to access the service.
|
||||
type PortDefinitions struct {
|
||||
// PortDefinition describes which load balancer port you should access to access the service.
|
||||
type PortDefinition struct {
|
||||
Labels map[string]string `json:"labels"`
|
||||
Port uint32 `json:"port"`
|
||||
}
|
||||
|
||||
// Network describes the name and type of network the container is attached to.
|
||||
type Network struct {
|
||||
Name string `json:"name"`
|
||||
Mode string `json:"mode"`
|
||||
}
|
||||
|
||||
// App describes a service running on Marathon.
|
||||
|
@ -312,7 +324,13 @@ type App struct {
|
|||
RunningTasks int `json:"tasksRunning"`
|
||||
Labels map[string]string `json:"labels"`
|
||||
Container Container `json:"container"`
|
||||
PortDefinitions []PortDefinitions `json:"portDefinitions"`
|
||||
PortDefinitions []PortDefinition `json:"portDefinitions"`
|
||||
Networks []Network `json:"networks"`
|
||||
}
|
||||
|
||||
// isContainerNet checks if the app's first network is set to mode 'container'.
|
||||
func (app App) isContainerNet() bool {
|
||||
return len(app.Networks) > 0 && app.Networks[0].Mode == "container"
|
||||
}
|
||||
|
||||
// AppList is a list of Marathon apps.
|
||||
|
@ -403,46 +421,109 @@ func createTargetGroup(app *App) *targetgroup.Group {
|
|||
|
||||
func targetsForApp(app *App) []model.LabelSet {
|
||||
targets := make([]model.LabelSet, 0, len(app.Tasks))
|
||||
for _, t := range app.Tasks {
|
||||
if len(t.Ports) == 0 {
|
||||
continue
|
||||
|
||||
var ports []uint32
|
||||
var labels []map[string]string
|
||||
var prefix string
|
||||
|
||||
if len(app.Container.PortMappings) != 0 {
|
||||
// In Marathon 1.5.x the "container.docker.portMappings" object was moved
|
||||
// to "container.portMappings".
|
||||
ports, labels = extractPortMapping(app.Container.PortMappings, app.isContainerNet())
|
||||
prefix = portMappingLabelPrefix
|
||||
|
||||
} else if len(app.Container.Docker.PortMappings) != 0 {
|
||||
// Prior to Marathon 1.5 the port mappings could be found at the path
|
||||
// "container.docker.portMappings".
|
||||
ports, labels = extractPortMapping(app.Container.Docker.PortMappings, app.isContainerNet())
|
||||
prefix = portMappingLabelPrefix
|
||||
|
||||
} else if len(app.PortDefinitions) != 0 {
|
||||
// PortDefinitions deprecates the "ports" array and can be used to specify
|
||||
// a list of ports with metadata in case a mapping is not required.
|
||||
ports = make([]uint32, len(app.PortDefinitions))
|
||||
labels = make([]map[string]string, len(app.PortDefinitions))
|
||||
|
||||
for i := 0; i < len(app.PortDefinitions); i++ {
|
||||
labels[i] = app.PortDefinitions[i].Labels
|
||||
ports[i] = app.PortDefinitions[i].Port
|
||||
}
|
||||
for i := 0; i < len(t.Ports); i++ {
|
||||
targetAddress := targetForTask(&t, i)
|
||||
|
||||
prefix = portDefinitionLabelPrefix
|
||||
}
|
||||
|
||||
// Gather info about the app's 'tasks'. Each instance (container) is considered a task
|
||||
// and can be reachable at one or more host:port endpoints.
|
||||
for _, t := range app.Tasks {
|
||||
|
||||
// There are no labels to gather if only Ports is defined. (eg. with host networking)
|
||||
// Ports can only be gathered from the Task (not from the app) and are guaranteed
|
||||
// to be the same across all tasks. If we haven't gathered any ports by now,
|
||||
// use the task's ports as the port list.
|
||||
if len(ports) == 0 && len(t.Ports) != 0 {
|
||||
ports = t.Ports
|
||||
}
|
||||
|
||||
// Iterate over the ports we gathered using one of the methods above.
|
||||
for i, port := range ports {
|
||||
|
||||
// Each port represents a possible Prometheus target.
|
||||
targetAddress := targetEndpoint(&t, port, app.isContainerNet())
|
||||
target := model.LabelSet{
|
||||
model.AddressLabel: model.LabelValue(targetAddress),
|
||||
taskLabel: model.LabelValue(t.ID),
|
||||
portIndexLabel: model.LabelValue(strconv.Itoa(i)),
|
||||
}
|
||||
if i < len(app.PortDefinitions) {
|
||||
for ln, lv := range app.PortDefinitions[i].Labels {
|
||||
ln = portDefinitionLabelPrefix + strutil.SanitizeLabelName(ln)
|
||||
target[model.LabelName(ln)] = model.LabelValue(lv)
|
||||
}
|
||||
}
|
||||
// Prior to Marathon 1.5 the port mappings could be found at the path
|
||||
// "container.docker.portMappings". When support for Marathon 1.4
|
||||
// is dropped then this section of code can be removed.
|
||||
if i < len(app.Container.Docker.PortMappings) {
|
||||
for ln, lv := range app.Container.Docker.PortMappings[i].Labels {
|
||||
ln = portMappingLabelPrefix + strutil.SanitizeLabelName(ln)
|
||||
target[model.LabelName(ln)] = model.LabelValue(lv)
|
||||
}
|
||||
}
|
||||
// In Marathon 1.5.x the container.docker.portMappings object was moved
|
||||
// to container.portMappings.
|
||||
if i < len(app.Container.PortMappings) {
|
||||
for ln, lv := range app.Container.PortMappings[i].Labels {
|
||||
ln = portMappingLabelPrefix + strutil.SanitizeLabelName(ln)
|
||||
|
||||
// Gather all port labels and set them on the current target, skip if the port has no Marathon labels.
|
||||
// This will happen in the host networking case with only `ports` defined, where
|
||||
// it is inefficient to allocate a list of possibly hundreds of empty label maps per host port.
|
||||
if len(labels) > 0 {
|
||||
for ln, lv := range labels[i] {
|
||||
ln = prefix + strutil.SanitizeLabelName(ln)
|
||||
target[model.LabelName(ln)] = model.LabelValue(lv)
|
||||
}
|
||||
}
|
||||
|
||||
targets = append(targets, target)
|
||||
}
|
||||
}
|
||||
return targets
|
||||
}
|
||||
|
||||
func targetForTask(task *Task, index int) string {
|
||||
return net.JoinHostPort(task.Host, fmt.Sprintf("%d", task.Ports[index]))
|
||||
// Generate a target endpoint string in host:port format.
|
||||
func targetEndpoint(task *Task, port uint32, containerNet bool) string {
|
||||
|
||||
var host string
|
||||
|
||||
// Use the task's ipAddress field when it's in a container network
|
||||
if containerNet && len(task.IPAddresses) > 0 {
|
||||
host = task.IPAddresses[0].Address
|
||||
} else {
|
||||
host = task.Host
|
||||
}
|
||||
|
||||
return net.JoinHostPort(host, fmt.Sprintf("%d", port))
|
||||
}
|
||||
|
||||
// Get a list of ports and a list of labels from a PortMapping.
|
||||
func extractPortMapping(portMappings []PortMapping, containerNet bool) ([]uint32, []map[string]string) {
|
||||
|
||||
ports := make([]uint32, len(portMappings))
|
||||
labels := make([]map[string]string, len(portMappings))
|
||||
|
||||
for i := 0; i < len(portMappings); i++ {
|
||||
|
||||
labels[i] = portMappings[i].Labels
|
||||
|
||||
if containerNet {
|
||||
// If the app is in a container network, connect directly to the container port.
|
||||
ports[i] = portMappings[i].ContainerPort
|
||||
} else {
|
||||
// Otherwise, connect to the randomly-generated service port.
|
||||
ports[i] = portMappings[i].ServicePort
|
||||
}
|
||||
}
|
||||
|
||||
return ports, labels
|
||||
}
|
||||
|
|
|
@ -77,26 +77,22 @@ func TestMarathonSDEmptyList(t *testing.T) {
|
|||
func marathonTestAppList(labels map[string]string, runningTasks int) *AppList {
|
||||
var (
|
||||
task = Task{
|
||||
ID: "test-task-1",
|
||||
Host: "mesos-slave1",
|
||||
Ports: []uint32{31000},
|
||||
ID: "test-task-1",
|
||||
Host: "mesos-slave1",
|
||||
}
|
||||
docker = DockerContainer{
|
||||
Image: "repo/image:tag",
|
||||
PortMappings: []PortMappings{
|
||||
{Labels: labels},
|
||||
},
|
||||
}
|
||||
container = Container{Docker: docker}
|
||||
portMappings = []PortMapping{
|
||||
{Labels: labels, ServicePort: 31000},
|
||||
}
|
||||
container = Container{Docker: docker, PortMappings: portMappings}
|
||||
app = App{
|
||||
ID: "test-service",
|
||||
Tasks: []Task{task},
|
||||
RunningTasks: runningTasks,
|
||||
Labels: labels,
|
||||
Container: container,
|
||||
PortDefinitions: []PortDefinitions{
|
||||
{Labels: make(map[string]string)},
|
||||
},
|
||||
}
|
||||
)
|
||||
return &AppList{
|
||||
|
@ -131,9 +127,6 @@ func TestMarathonSDSendGroup(t *testing.T) {
|
|||
if tgt[model.LabelName(portMappingLabelPrefix+"prometheus")] != "yes" {
|
||||
t.Fatalf("Wrong first portMappings label from the first port: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
if tgt[model.LabelName(portDefinitionLabelPrefix+"prometheus")] != "" {
|
||||
t.Fatalf("Wrong first portDefinitions label from the first port: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
default:
|
||||
t.Fatal("Did not get a target group.")
|
||||
}
|
||||
|
@ -197,6 +190,7 @@ func TestMarathonSDRunAndStop(t *testing.T) {
|
|||
case <-ch:
|
||||
cancel()
|
||||
case <-doneCh:
|
||||
cancel()
|
||||
return
|
||||
case <-timeout:
|
||||
t.Fatalf("Update took too long.")
|
||||
|
@ -204,31 +198,26 @@ func TestMarathonSDRunAndStop(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func marathonTestAppListWithMutiplePorts(labels map[string]string, runningTasks int) *AppList {
|
||||
func marathonTestAppListWithMultiplePorts(labels map[string]string, runningTasks int) *AppList {
|
||||
var (
|
||||
task = Task{
|
||||
ID: "test-task-1",
|
||||
Host: "mesos-slave1",
|
||||
Ports: []uint32{31000, 32000},
|
||||
ID: "test-task-1",
|
||||
Host: "mesos-slave1",
|
||||
}
|
||||
docker = DockerContainer{
|
||||
Image: "repo/image:tag",
|
||||
PortMappings: []PortMappings{
|
||||
{Labels: labels},
|
||||
{Labels: make(map[string]string)},
|
||||
},
|
||||
}
|
||||
container = Container{Docker: docker}
|
||||
portMappings = []PortMapping{
|
||||
{Labels: labels, ServicePort: 31000},
|
||||
{Labels: make(map[string]string), ServicePort: 32000},
|
||||
}
|
||||
container = Container{Docker: docker, PortMappings: portMappings}
|
||||
app = App{
|
||||
ID: "test-service",
|
||||
Tasks: []Task{task},
|
||||
RunningTasks: runningTasks,
|
||||
Labels: labels,
|
||||
Container: container,
|
||||
PortDefinitions: []PortDefinitions{
|
||||
{Labels: make(map[string]string)},
|
||||
{Labels: labels},
|
||||
},
|
||||
}
|
||||
)
|
||||
return &AppList{
|
||||
|
@ -236,11 +225,11 @@ func marathonTestAppListWithMutiplePorts(labels map[string]string, runningTasks
|
|||
}
|
||||
}
|
||||
|
||||
func TestMarathonSDSendGroupWithMutiplePort(t *testing.T) {
|
||||
func TestMarathonSDSendGroupWithMultiplePort(t *testing.T) {
|
||||
var (
|
||||
ch = make(chan []*targetgroup.Group, 1)
|
||||
client = func(client *http.Client, url string) (*AppList, error) {
|
||||
return marathonTestAppListWithMutiplePorts(marathonValidLabel, 1), nil
|
||||
return marathonTestAppListWithMultiplePorts(marathonValidLabel, 1), nil
|
||||
}
|
||||
)
|
||||
if err := testUpdateServices(client, ch); err != nil {
|
||||
|
@ -263,9 +252,6 @@ func TestMarathonSDSendGroupWithMutiplePort(t *testing.T) {
|
|||
if tgt[model.LabelName(portMappingLabelPrefix+"prometheus")] != "yes" {
|
||||
t.Fatalf("Wrong first portMappings label from the first port: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
if tgt[model.LabelName(portDefinitionLabelPrefix+"prometheus")] != "" {
|
||||
t.Fatalf("Wrong first portDefinitions label from the first port: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
tgt = tg.Targets[1]
|
||||
if tgt[model.AddressLabel] != "mesos-slave1:32000" {
|
||||
t.Fatalf("Wrong target address: %s", tgt[model.AddressLabel])
|
||||
|
@ -273,9 +259,6 @@ func TestMarathonSDSendGroupWithMutiplePort(t *testing.T) {
|
|||
if tgt[model.LabelName(portMappingLabelPrefix+"prometheus")] != "" {
|
||||
t.Fatalf("Wrong portMappings label from the second port: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
if tgt[model.LabelName(portDefinitionLabelPrefix+"prometheus")] != "yes" {
|
||||
t.Fatalf("Wrong portDefinitions label from the second port: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
default:
|
||||
t.Fatal("Did not get a target group.")
|
||||
}
|
||||
|
@ -355,12 +338,11 @@ func Test500ErrorHttpResponseWithValidJSONBody(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func marathonTestAppListWithoutPortMappings(labels map[string]string, runningTasks int) *AppList {
|
||||
func marathonTestAppListWithPortDefinitions(labels map[string]string, runningTasks int) *AppList {
|
||||
var (
|
||||
task = Task{
|
||||
ID: "test-task-1",
|
||||
Host: "mesos-slave1",
|
||||
Ports: []uint32{31000, 32000},
|
||||
ID: "test-task-1",
|
||||
Host: "mesos-slave1",
|
||||
}
|
||||
docker = DockerContainer{
|
||||
Image: "repo/image:tag",
|
||||
|
@ -372,9 +354,9 @@ func marathonTestAppListWithoutPortMappings(labels map[string]string, runningTas
|
|||
RunningTasks: runningTasks,
|
||||
Labels: labels,
|
||||
Container: container,
|
||||
PortDefinitions: []PortDefinitions{
|
||||
{Labels: make(map[string]string)},
|
||||
{Labels: labels},
|
||||
PortDefinitions: []PortDefinition{
|
||||
{Labels: make(map[string]string), Port: 31000},
|
||||
{Labels: labels, Port: 32000},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
@ -383,11 +365,11 @@ func marathonTestAppListWithoutPortMappings(labels map[string]string, runningTas
|
|||
}
|
||||
}
|
||||
|
||||
func TestMarathonSDSendGroupWithoutPortMappings(t *testing.T) {
|
||||
func TestMarathonSDSendGroupWithPortDefinitions(t *testing.T) {
|
||||
var (
|
||||
ch = make(chan []*targetgroup.Group, 1)
|
||||
client = func(client *http.Client, url string) (*AppList, error) {
|
||||
return marathonTestAppListWithoutPortMappings(marathonValidLabel, 1), nil
|
||||
return marathonTestAppListWithPortDefinitions(marathonValidLabel, 1), nil
|
||||
}
|
||||
)
|
||||
if err := testUpdateServices(client, ch); err != nil {
|
||||
|
@ -428,7 +410,7 @@ func TestMarathonSDSendGroupWithoutPortMappings(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func marathonTestAppListWithoutPortDefinitions(labels map[string]string, runningTasks int) *AppList {
|
||||
func marathonTestAppListWithPorts(labels map[string]string, runningTasks int) *AppList {
|
||||
var (
|
||||
task = Task{
|
||||
ID: "test-task-1",
|
||||
|
@ -437,10 +419,6 @@ func marathonTestAppListWithoutPortDefinitions(labels map[string]string, running
|
|||
}
|
||||
docker = DockerContainer{
|
||||
Image: "repo/image:tag",
|
||||
PortMappings: []PortMappings{
|
||||
{Labels: labels},
|
||||
{Labels: make(map[string]string)},
|
||||
},
|
||||
}
|
||||
container = Container{Docker: docker}
|
||||
app = App{
|
||||
|
@ -456,11 +434,11 @@ func marathonTestAppListWithoutPortDefinitions(labels map[string]string, running
|
|||
}
|
||||
}
|
||||
|
||||
func TestMarathonSDSendGroupWithoutPortDefinitions(t *testing.T) {
|
||||
func TestMarathonSDSendGroupWithPorts(t *testing.T) {
|
||||
var (
|
||||
ch = make(chan []*targetgroup.Group, 1)
|
||||
client = func(client *http.Client, url string) (*AppList, error) {
|
||||
return marathonTestAppListWithoutPortDefinitions(marathonValidLabel, 1), nil
|
||||
return marathonTestAppListWithPorts(marathonValidLabel, 1), nil
|
||||
}
|
||||
)
|
||||
if err := testUpdateServices(client, ch); err != nil {
|
||||
|
@ -480,7 +458,7 @@ func TestMarathonSDSendGroupWithoutPortDefinitions(t *testing.T) {
|
|||
if tgt[model.AddressLabel] != "mesos-slave1:31000" {
|
||||
t.Fatalf("Wrong target address: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
if tgt[model.LabelName(portMappingLabelPrefix+"prometheus")] != "yes" {
|
||||
if tgt[model.LabelName(portMappingLabelPrefix+"prometheus")] != "" {
|
||||
t.Fatalf("Wrong first portMappings label from the first port: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
if tgt[model.LabelName(portDefinitionLabelPrefix+"prometheus")] != "" {
|
||||
|
@ -504,18 +482,17 @@ func TestMarathonSDSendGroupWithoutPortDefinitions(t *testing.T) {
|
|||
func marathonTestAppListWithContainerPortMappings(labels map[string]string, runningTasks int) *AppList {
|
||||
var (
|
||||
task = Task{
|
||||
ID: "test-task-1",
|
||||
Host: "mesos-slave1",
|
||||
Ports: []uint32{31000, 32000},
|
||||
ID: "test-task-1",
|
||||
Host: "mesos-slave1",
|
||||
}
|
||||
docker = DockerContainer{
|
||||
Image: "repo/image:tag",
|
||||
}
|
||||
container = Container{
|
||||
Docker: docker,
|
||||
PortMappings: []PortMappings{
|
||||
{Labels: labels},
|
||||
{Labels: make(map[string]string)},
|
||||
PortMappings: []PortMapping{
|
||||
{Labels: labels, ServicePort: 31000},
|
||||
{Labels: make(map[string]string), ServicePort: 32000},
|
||||
},
|
||||
}
|
||||
app = App{
|
||||
|
@ -575,3 +552,241 @@ func TestMarathonSDSendGroupWithContainerPortMappings(t *testing.T) {
|
|||
t.Fatal("Did not get a target group.")
|
||||
}
|
||||
}
|
||||
|
||||
func marathonTestAppListWithDockerContainerPortMappings(labels map[string]string, runningTasks int) *AppList {
|
||||
var (
|
||||
task = Task{
|
||||
ID: "test-task-1",
|
||||
Host: "mesos-slave1",
|
||||
}
|
||||
docker = DockerContainer{
|
||||
Image: "repo/image:tag",
|
||||
PortMappings: []PortMapping{
|
||||
{Labels: labels, ServicePort: 31000},
|
||||
{Labels: make(map[string]string), ServicePort: 32000},
|
||||
},
|
||||
}
|
||||
container = Container{
|
||||
Docker: docker,
|
||||
}
|
||||
app = App{
|
||||
ID: "test-service",
|
||||
Tasks: []Task{task},
|
||||
RunningTasks: runningTasks,
|
||||
Labels: labels,
|
||||
Container: container,
|
||||
}
|
||||
)
|
||||
return &AppList{
|
||||
Apps: []App{app},
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarathonSDSendGroupWithDockerContainerPortMappings(t *testing.T) {
|
||||
var (
|
||||
ch = make(chan []*targetgroup.Group, 1)
|
||||
client = func(client *http.Client, url string) (*AppList, error) {
|
||||
return marathonTestAppListWithDockerContainerPortMappings(marathonValidLabel, 1), nil
|
||||
}
|
||||
)
|
||||
if err := testUpdateServices(client, ch); err != nil {
|
||||
t.Fatalf("Got error: %s", err)
|
||||
}
|
||||
select {
|
||||
case tgs := <-ch:
|
||||
tg := tgs[0]
|
||||
|
||||
if tg.Source != "test-service" {
|
||||
t.Fatalf("Wrong target group name: %s", tg.Source)
|
||||
}
|
||||
if len(tg.Targets) != 2 {
|
||||
t.Fatalf("Wrong number of targets: %v", tg.Targets)
|
||||
}
|
||||
tgt := tg.Targets[0]
|
||||
if tgt[model.AddressLabel] != "mesos-slave1:31000" {
|
||||
t.Fatalf("Wrong target address: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
if tgt[model.LabelName(portMappingLabelPrefix+"prometheus")] != "yes" {
|
||||
t.Fatalf("Wrong first portMappings label from the first port: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
if tgt[model.LabelName(portDefinitionLabelPrefix+"prometheus")] != "" {
|
||||
t.Fatalf("Wrong first portDefinitions label from the first port: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
tgt = tg.Targets[1]
|
||||
if tgt[model.AddressLabel] != "mesos-slave1:32000" {
|
||||
t.Fatalf("Wrong target address: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
if tgt[model.LabelName(portMappingLabelPrefix+"prometheus")] != "" {
|
||||
t.Fatalf("Wrong portMappings label from the second port: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
if tgt[model.LabelName(portDefinitionLabelPrefix+"prometheus")] != "" {
|
||||
t.Fatalf("Wrong portDefinitions label from the second port: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
default:
|
||||
t.Fatal("Did not get a target group.")
|
||||
}
|
||||
}
|
||||
|
||||
func marathonTestAppListWithContainerNetworkAndPortMappings(labels map[string]string, runningTasks int) *AppList {
|
||||
var (
|
||||
task = Task{
|
||||
ID: "test-task-1",
|
||||
Host: "mesos-slave1",
|
||||
IPAddresses: []IPAddress{
|
||||
{Address: "1.2.3.4"},
|
||||
},
|
||||
}
|
||||
docker = DockerContainer{
|
||||
Image: "repo/image:tag",
|
||||
}
|
||||
portMappings = []PortMapping{
|
||||
{Labels: labels, ContainerPort: 8080, ServicePort: 31000},
|
||||
{Labels: make(map[string]string), ContainerPort: 1234, ServicePort: 32000},
|
||||
}
|
||||
container = Container{
|
||||
Docker: docker,
|
||||
PortMappings: portMappings,
|
||||
}
|
||||
networks = []Network{
|
||||
{Mode: "container", Name: "test-network"},
|
||||
}
|
||||
app = App{
|
||||
ID: "test-service",
|
||||
Tasks: []Task{task},
|
||||
RunningTasks: runningTasks,
|
||||
Labels: labels,
|
||||
Container: container,
|
||||
Networks: networks,
|
||||
}
|
||||
)
|
||||
return &AppList{
|
||||
Apps: []App{app},
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarathonSDSendGroupWithContainerNetworkAndPortMapping(t *testing.T) {
|
||||
var (
|
||||
ch = make(chan []*targetgroup.Group, 1)
|
||||
client = func(client *http.Client, url string) (*AppList, error) {
|
||||
return marathonTestAppListWithContainerNetworkAndPortMappings(marathonValidLabel, 1), nil
|
||||
}
|
||||
)
|
||||
if err := testUpdateServices(client, ch); err != nil {
|
||||
t.Fatalf("Got error: %s", err)
|
||||
}
|
||||
select {
|
||||
case tgs := <-ch:
|
||||
tg := tgs[0]
|
||||
|
||||
if tg.Source != "test-service" {
|
||||
t.Fatalf("Wrong target group name: %s", tg.Source)
|
||||
}
|
||||
if len(tg.Targets) != 2 {
|
||||
t.Fatalf("Wrong number of targets: %v", tg.Targets)
|
||||
}
|
||||
tgt := tg.Targets[0]
|
||||
if tgt[model.AddressLabel] != "1.2.3.4:8080" {
|
||||
t.Fatalf("Wrong target address: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
if tgt[model.LabelName(portMappingLabelPrefix+"prometheus")] != "yes" {
|
||||
t.Fatalf("Wrong first portMappings label from the first port: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
if tgt[model.LabelName(portDefinitionLabelPrefix+"prometheus")] != "" {
|
||||
t.Fatalf("Wrong first portDefinitions label from the first port: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
tgt = tg.Targets[1]
|
||||
if tgt[model.AddressLabel] != "1.2.3.4:1234" {
|
||||
t.Fatalf("Wrong target address: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
if tgt[model.LabelName(portMappingLabelPrefix+"prometheus")] != "" {
|
||||
t.Fatalf("Wrong portMappings label from the second port: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
if tgt[model.LabelName(portDefinitionLabelPrefix+"prometheus")] != "" {
|
||||
t.Fatalf("Wrong portDefinitions label from the second port: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
default:
|
||||
t.Fatal("Did not get a target group.")
|
||||
}
|
||||
}
|
||||
|
||||
func marathonTestAppListWithContainerNetworkAndPortDefinition(labels map[string]string, runningTasks int) *AppList {
|
||||
var (
|
||||
task = Task{
|
||||
ID: "test-task-1",
|
||||
Host: "mesos-slave1",
|
||||
IPAddresses: []IPAddress{
|
||||
{Address: "1.2.3.4"},
|
||||
},
|
||||
}
|
||||
docker = DockerContainer{
|
||||
Image: "repo/image:tag",
|
||||
}
|
||||
portDefinitions = []PortDefinition{
|
||||
{Labels: labels, Port: 8080},
|
||||
{Labels: make(map[string]string), Port: 1234},
|
||||
}
|
||||
container = Container{
|
||||
Docker: docker,
|
||||
}
|
||||
networks = []Network{
|
||||
{Mode: "container", Name: "test-network"},
|
||||
}
|
||||
app = App{
|
||||
ID: "test-service",
|
||||
Tasks: []Task{task},
|
||||
RunningTasks: runningTasks,
|
||||
Labels: labels,
|
||||
Container: container,
|
||||
Networks: networks,
|
||||
PortDefinitions: portDefinitions,
|
||||
}
|
||||
)
|
||||
return &AppList{
|
||||
Apps: []App{app},
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarathonSDSendGroupWithContainerNetworkAndPortDefinition(t *testing.T) {
|
||||
var (
|
||||
ch = make(chan []*targetgroup.Group, 1)
|
||||
client = func(client *http.Client, url string) (*AppList, error) {
|
||||
return marathonTestAppListWithContainerNetworkAndPortDefinition(marathonValidLabel, 1), nil
|
||||
}
|
||||
)
|
||||
if err := testUpdateServices(client, ch); err != nil {
|
||||
t.Fatalf("Got error: %s", err)
|
||||
}
|
||||
select {
|
||||
case tgs := <-ch:
|
||||
tg := tgs[0]
|
||||
|
||||
if tg.Source != "test-service" {
|
||||
t.Fatalf("Wrong target group name: %s", tg.Source)
|
||||
}
|
||||
if len(tg.Targets) != 2 {
|
||||
t.Fatalf("Wrong number of targets: %v", tg.Targets)
|
||||
}
|
||||
tgt := tg.Targets[0]
|
||||
if tgt[model.AddressLabel] != "1.2.3.4:8080" {
|
||||
t.Fatalf("Wrong target address: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
if tgt[model.LabelName(portMappingLabelPrefix+"prometheus")] != "" {
|
||||
t.Fatalf("Wrong first portMappings label from the first port: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
if tgt[model.LabelName(portDefinitionLabelPrefix+"prometheus")] != "yes" {
|
||||
t.Fatalf("Wrong first portDefinitions label from the first port: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
tgt = tg.Targets[1]
|
||||
if tgt[model.AddressLabel] != "1.2.3.4:1234" {
|
||||
t.Fatalf("Wrong target address: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
if tgt[model.LabelName(portMappingLabelPrefix+"prometheus")] != "" {
|
||||
t.Fatalf("Wrong portMappings label from the second port: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
if tgt[model.LabelName(portDefinitionLabelPrefix+"prometheus")] != "" {
|
||||
t.Fatalf("Wrong portDefinitions label from the second port: %s", tgt[model.AddressLabel])
|
||||
}
|
||||
default:
|
||||
t.Fatal("Did not get a target group.")
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue