1package workerserver
2
3import (
4	"encoding/json"
5	"errors"
6	"fmt"
7	"net/http"
8	"strconv"
9	"time"
10
11	"code.cloudfoundry.org/lager"
12	"github.com/concourse/concourse/atc"
13	"github.com/concourse/concourse/atc/api/accessor"
14	"github.com/concourse/concourse/atc/metric"
15)
16
17type IntMetric int
18
19func (i IntMetric) String() string {
20	return strconv.Itoa(int(i))
21}
22
23func (s *Server) RegisterWorker(w http.ResponseWriter, r *http.Request) {
24	logger := s.logger.Session("register-worker")
25	var registration atc.Worker
26
27	acc := accessor.GetAccessor(r)
28	if !acc.IsSystem() {
29		w.WriteHeader(http.StatusForbidden)
30		return
31	}
32
33	err := json.NewDecoder(r.Body).Decode(&registration)
34	if err != nil {
35		w.WriteHeader(http.StatusBadRequest)
36		return
37	}
38
39	err = registration.Validate()
40	if err != nil {
41		w.WriteHeader(http.StatusBadRequest)
42		fmt.Fprintf(w, err.Error())
43		return
44	}
45
46	var ttl time.Duration
47
48	ttlStr := r.URL.Query().Get("ttl")
49	if len(ttlStr) > 0 {
50		ttl, err = time.ParseDuration(ttlStr)
51		if err != nil {
52			w.WriteHeader(http.StatusBadRequest)
53			fmt.Fprintf(w, "malformed ttl")
54			return
55		}
56	}
57
58	if registration.Name == "" {
59		registration.Name = registration.GardenAddr
60	}
61
62	if registration.CertsPath != nil && *registration.CertsPath == "" {
63		registration.CertsPath = nil
64	}
65
66	metric.WorkerContainers{
67		WorkerName: registration.Name,
68		Containers: registration.ActiveContainers,
69		Platform:   registration.Platform,
70		TeamName:   registration.Team,
71		Tags:       registration.Tags,
72	}.Emit(s.logger)
73
74	metric.WorkerVolumes{
75		WorkerName: registration.Name,
76		Volumes:    registration.ActiveVolumes,
77		Platform:   registration.Platform,
78		TeamName:   registration.Team,
79		Tags:       registration.Tags,
80	}.Emit(s.logger)
81
82	metric.WorkerTasks{
83		WorkerName: registration.Name,
84		Tasks:      registration.ActiveTasks,
85		Platform:   registration.Platform,
86	}.Emit(s.logger)
87
88	if registration.Team != "" {
89		team, found, err := s.teamFactory.FindTeam(registration.Team)
90		if err != nil {
91			logger.Error("failed-to-get-team", err)
92			w.WriteHeader(http.StatusInternalServerError)
93			return
94		}
95
96		if !found {
97			logger.Error("team-not-found", errors.New("team-not-found"), lager.Data{"team-name": registration.Team})
98			w.WriteHeader(http.StatusBadRequest)
99			return
100		}
101
102		_, err = team.SaveWorker(registration, ttl)
103		if err != nil {
104			logger.Error("failed-to-save-worker", err)
105			w.WriteHeader(http.StatusInternalServerError)
106			return
107		}
108	} else {
109		_, err = s.dbWorkerFactory.SaveWorker(registration, ttl)
110		if err != nil {
111			logger.Error("failed-to-save-worker", err)
112			w.WriteHeader(http.StatusInternalServerError)
113			return
114		}
115	}
116
117	w.WriteHeader(http.StatusOK)
118}
119