Пример #1
0
func (r *marathonClient) apiCall(method, uri, body string, result interface{}) (int, string, error) {
	glog.V(DEBUG_LEVEL).Infof("[api]: method: %s, uri: %s, body: %s", method, uri, body)

	status, content, _, err := r.httpRequest(method, uri, body)
	if err != nil {
		return 0, "", err
	}

	glog.V(DEBUG_LEVEL).Infof("[api] result: status: %d, content: %s\n", status, content)
	if status >= 200 && status <= 299 {
		if result != nil {
			if err := r.decodeRequest(strings.NewReader(content), result); err != nil {
				glog.V(DEBUG_LEVEL).Infof("failed to unmarshall the response from marathon, error: %s", err)
				return status, content, ErrInvalidResponse
			}
		}
		return status, content, nil
	}

	switch status {
	case 500:
		return status, "", ErrInvalidResponse
	case 404:
		return status, "", ErrDoesNotExist
	}

	// step: lets decode into a error message
	var message struct {
		Message string `json:"message"`
	}

	if err := r.decodeRequest(strings.NewReader(content), &message); err != nil {
		return status, content, ErrInvalidResponse
	}

	errorMessage := "unknown error"
	if message.Message != "" {
		errorMessage = message.Message
	}

	return status, "", fmt.Errorf("%s", errorMessage)
}
Пример #2
0
func (r *marathonClient) handleMarathonEvent(writer http.ResponseWriter, request *http.Request) {
	body, err := ioutil.ReadAll(request.Body)
	if err != nil {
		return
	}

	// step: process the event and decode the event
	content := string(body[:])
	eventType := new(EventType)
	err = json.NewDecoder(strings.NewReader(content)).Decode(eventType)
	if err != nil {
		glog.V(DEBUG_LEVEL).Infof("failed to decode the event type, content: %s, error: %s", content, err)
		return
	}

	// step: check the type is handled
	event, err := r.GetEvent(eventType.EventType)
	if err != nil {
		glog.V(DEBUG_LEVEL).Infof("unable to retrieve the event, type: %s", eventType.EventType)
		return
	}

	// step: lets decode message
	err = json.NewDecoder(strings.NewReader(content)).Decode(event.Event)
	if err != nil {
		glog.V(DEBUG_LEVEL).Infof("failed to decode the event type: %d, name: %s error: %s", event.ID, err)
		return
	}

	r.RLock()
	defer r.RUnlock()

	// step: check if anyone is listen for this event
	for channel, filter := range r.listeners {
		// step: check if this listener wants this event type
		if event.ID&filter != 0 {
			go func(ch EventsChannel, e *Event) {
				ch <- e
			}(channel, event)
		}
	}
}
Пример #3
0
func main() {
	flag.Parse()
	if Options.method_file == "" {
		glog.Errorf("You have not specified the methods file to import")
		os.Exit(1)
	}

	// step: open and read in the methods yaml
	contents, err := ioutil.ReadFile(Options.method_file)
	if err != nil {
		glog.Errorf("Failed to open|read the methods file: %s, error: %s", Options.method_file, err)
		os.Exit(1)
	}

	// step: unmarshal the yaml
	var methods []*RestMethod
	err = yaml.Unmarshal([]byte(contents), &methods)
	if err != nil {
		glog.Errorf("Failed to unmarshall the method yaml file: %s, error: %s", Options.method_file, err)
		os.Exit(1)
	}

	// step: construct a hash from the methods
	uris := make(map[string]*string, 0)
	for _, method := range methods {
		uris[fmt.Sprintf("%s:%s", method.Method, method.URI)] = &method.Content
	}

	http.HandleFunc("/", func(writer http.ResponseWriter, reader *http.Request) {
		key := fmt.Sprintf("%s:%s", reader.Method, reader.RequestURI)
		glog.V(4).Infof("Request: uri: %s, method: %s", reader.RequestURI, reader.Method)
		if content, found := uris[key]; found {
			glog.V(4).Infof("Content: %s", *content)
			writer.Header().Add("Content-Type", "application/json")
			writer.Write([]byte(*content))
		} else if !found {
			http.Error(writer, "not found", 404)
		}
	})
	glog.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", Options.port), nil))
}
Пример #4
0
// UpdateApplication updates an application in Marathon
// 		application:		the structure holding the application configuration
func (r *marathonClient) UpdateApplication(application *Application) (*DeploymentID, error) {
	result := new(DeploymentID)
	glog.V(DEBUG_LEVEL).Infof("updating application: %s", application)

	uri := fmt.Sprintf("%s/%s", MARATHON_API_APPS, trimRootPath(application.ID))

	if err := r.apiPut(uri, &application, result); err != nil {
		return nil, err
	}

	return result, nil
}
Пример #5
0
// ScaleApplicationInstances changes the number of instance an application is running
// 		name: 		the id used to identify the application
// 		instances:	the number of instances you wish to change to
//    force: used to force the scale operation in case of blocked deployment
func (r *marathonClient) ScaleApplicationInstances(name string, instances int, force bool) (*DeploymentID, error) {
	glog.V(DEBUG_LEVEL).Infof("scaling the application: %s, instance: %d", name, instances)
	changes := new(Application)
	changes.ID = validateID(name)
	changes.Instances = instances
	uri := fmt.Sprintf("%s/%s?force=%t", MARATHON_API_APPS, trimRootPath(name), force)
	deployID := new(DeploymentID)
	if err := r.apiPut(uri, &changes, deployID); err != nil {
		return nil, err
	}

	return deployID, nil
}
Пример #6
0
// RestartApplication performs a rolling restart of marathon application
// 		name: 		the id used to identify the application
func (r *marathonClient) RestartApplication(name string, force bool) (*DeploymentID, error) {
	glog.V(DEBUG_LEVEL).Infof("restarting the application: %s, force: %s", name, force)
	deployment := new(DeploymentID)
	var options struct {
		Force bool `json:"force"`
	}
	options.Force = force
	if err := r.apiPost(fmt.Sprintf("%s/%s/restart", MARATHON_API_APPS, trimRootPath(name)), &options, deployment); err != nil {
		return nil, err
	}

	return deployment, nil
}
Пример #7
0
// AddEventsListener adds your self as a listener to events from Marathon
//		channel:	a EventsChannel used to receive event on
func (r *marathonClient) AddEventsListener(channel EventsChannel, filter int) error {
	r.Lock()
	defer r.Unlock()
	// step: someone has asked to start listening to event, we need to register for events
	// if we haven't done so already
	if err := r.RegisterSubscription(); err != nil {
		return err
	}

	if _, found := r.listeners[channel]; !found {
		glog.V(DEBUG_LEVEL).Infof("adding a watch for events: %d, channel: %v", filter, channel)
		r.listeners[channel] = filter
	}
	return nil
}
Пример #8
0
func (r *marathonClient) httpRequest(method, uri, body string) (int, string, *http.Response, error) {
	var content string

	// step: get a member from the cluster
	marathon, err := r.cluster.GetMember()
	if err != nil {
		return 0, "", nil, err
	}

	url := fmt.Sprintf("%s/%s", marathon, uri)

	glog.V(DEBUG_LEVEL).Infof("[http] request: %s, uri: %s, url: %s", method, uri, url)
	// step: make the http request to marathon
	request, err := http.NewRequest(method, url, strings.NewReader(body))
	if err != nil {
		return 0, "", nil, err
	}

	// step: add any basic auth and the content headers
	if r.config.HttpBasicAuthUser != "" {
		request.SetBasicAuth(r.config.HttpBasicAuthUser, r.config.HttpBasicPassword)
	}
	request.Header.Add("Content-Type", "application/json")
	request.Header.Add("Accept", "application/json")

	response, err := r.httpClient.Do(request)
	if err != nil {
		r.cluster.MarkDown()
		// step: retry the request with another endpoint
		return r.httpRequest(method, uri, body)
	}

	if response.ContentLength != 0 {
		responseContent, err := ioutil.ReadAll(response.Body)
		if err != nil {
			return response.StatusCode, "", response, err
		}
		content = string(responseContent)
	}

	return response.StatusCode, content, response, nil
}