예제 #1
0
func (i *Installer) updateAgent(uuid string) (*proto.Agent, error) {
	agent := &proto.Agent{
		Uuid:     uuid,
		Hostname: i.hostname,
		Alias:    i.hostname,
		Version:  agent.VERSION,
	}
	data, err := json.Marshal(agent)
	if err != nil {
		return nil, err
	}
	url := pct.URL(i.agentConfig.ApiHostname, "agents", uuid)
	if i.flags["debug"] {
		log.Println(url)
		log.Println(string(data))
	}
	resp, _, err := i.api.Put(i.agentConfig.ApiKey, url, data)
	if i.flags["debug"] {
		log.Printf("resp=%#v\n", resp)
		log.Printf("err=%s\n", err)
	}
	if err != nil {
		return nil, err
	}

	if resp.StatusCode != http.StatusOK {
		return nil, fmt.Errorf("Failed to update agent via API (status code %d)", resp.StatusCode)
	}
	return agent, nil
}
예제 #2
0
func (i *Installer) createMySQLInstance(dsn mysql.DSN) (*proto.MySQLInstance, error) {
	// First use instance.Manager to fill in details about the MySQL server.
	dsnString, _ := dsn.DSN()
	mi := &proto.MySQLInstance{
		Hostname: i.hostname,
		DSN:      dsnString,
	}
	if err := instance.GetMySQLInfo(mi); err != nil {
		if i.flags["debug"] {
			log.Printf("err=%s\n", err)
		}
		return nil, err
	}

	// POST <api>/instances/mysql
	data, err := json.Marshal(mi)
	if err != nil {
		return nil, err
	}
	url := pct.URL(i.agentConfig.ApiHostname, "instances", "mysql")
	if i.flags["debug"] {
		log.Println(url)
	}
	resp, _, err := i.api.Post(i.agentConfig.ApiKey, url, data)
	if i.flags["debug"] {
		log.Printf("resp=%#v\n", resp)
		log.Printf("err=%s\n", err)
	}
	if err != nil {
		return nil, err
	}
	// Create new instance, if it already exist then just use it
	// todo: better handling of duplicate instance
	if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusConflict {
		return nil, fmt.Errorf("Failed to create MySQL instance (status code %d)", resp.StatusCode)
	}

	// API returns URI of new resource in Location header
	uri := resp.Header.Get("Location")
	if uri == "" {
		return nil, fmt.Errorf("API did not return location of new MySQL instance")
	}

	// GET <api>/instances/mysql/id (URI)
	code, data, err := i.api.Get(i.agentConfig.ApiKey, uri)
	if i.flags["debug"] {
		log.Printf("code=%d\n", code)
		log.Printf("err=%s\n", err)
	}
	if err != nil {
		return nil, err
	}
	if code != http.StatusOK {
		return nil, fmt.Errorf("Failed to get new MySQL instance (status code %d)", code)
	}
	if err := json.Unmarshal(data, mi); err != nil {
		return nil, err
	}
	return mi, nil
}
예제 #3
0
func (i *Installer) getMmMySQLConfig(mi *proto.MySQLInstance) (*proto.AgentConfig, error) {
	url := pct.URL(i.agentConfig.ApiHostname, "/configs/mm/default-mysql")
	code, data, err := i.api.Get(i.agentConfig.ApiKey, url)
	if i.flags["debug"] {
		log.Printf("code=%d\n", code)
		log.Printf("err=%s\n", err)
	}
	if err != nil {
		return nil, err
	}
	if code != http.StatusOK {
		return nil, fmt.Errorf("Failed to get default MySQL monitor config (%s, status %d)", url, code)
	}
	config := &mmMySQL.Config{}
	if err := json.Unmarshal(data, config); err != nil {
		return nil, err
	}
	config.Service = "mysql"
	config.InstanceId = mi.Id

	bytes, err := json.Marshal(config)
	if err != nil {
		return nil, err
	}
	agentConfig := &proto.AgentConfig{
		InternalService: "mm",
		ExternalService: proto.ServiceInstance{
			Service:    "mysql",
			InstanceId: mi.Id,
		},
		Config:  string(bytes),
		Running: true,
	}
	return agentConfig, nil
}
예제 #4
0
func (i *Installer) createAgent(configs []proto.AgentConfig) (*proto.Agent, error) {
	agent := &proto.Agent{
		Hostname: i.hostname,
		Version:  agent.VERSION,
		Configs:  configs,
	}
	data, err := json.Marshal(agent)
	if err != nil {
		return nil, err
	}
	url := pct.URL(i.agentConfig.ApiHostname, "agents")
	if i.flags["debug"] {
		log.Println(url)
	}
	resp, _, err := i.api.Post(i.agentConfig.ApiKey, url, data)
	if i.flags["debug"] {
		log.Printf("resp=%#v\n", resp)
		log.Printf("err=%s\n", err)
	}
	if err != nil {
		return nil, err
	}

	if resp.StatusCode == http.StatusCreated || resp.StatusCode == http.StatusConflict {
		// agent was created or already exist - either is ok, continue
	} else if resp.StatusCode == http.StatusForbidden && resp.Header.Get("X-Percona-Agents-Limit") != "" {
		return nil, fmt.Errorf("Maximum number of %s agents exceeded. Remove unused agents or contact Percona to increase limit.", resp.Header.Get("X-Percona-Agents-Limit"))
	} else {
		return nil, fmt.Errorf("Failed to create agent instance (status code %d)", resp.StatusCode)
	}

	// API returns URI of new resource in Location header
	uri := resp.Header.Get("Location")
	if uri == "" {
		return nil, fmt.Errorf("API did not return location of new agent")
	}

	// GET <api>/agents/:uuid
	code, data, err := i.api.Get(i.agentConfig.ApiKey, uri)
	if i.flags["debug"] {
		log.Printf("code=%d\n", code)
		log.Printf("err=%s\n", err)
	}
	if err != nil {
		return nil, err
	}
	if code != http.StatusOK {
		return nil, fmt.Errorf("Failed to get new agent (status code %d)", code)
	}
	if err := json.Unmarshal(data, agent); err != nil {
		return nil, err
	}
	return agent, nil
}
예제 #5
0
func (i *Installer) createServerInstance() (*proto.ServerInstance, error) {
	// POST <api>/instances/server
	si := &proto.ServerInstance{
		Hostname: i.hostname,
	}
	data, err := json.Marshal(si)
	if err != nil {
		return nil, err
	}
	url := pct.URL(i.agentConfig.ApiHostname, "instances", "server")
	if i.flags["debug"] {
		log.Println(url)
	}
	resp, _, err := i.api.Post(i.agentConfig.ApiKey, url, data)
	if i.flags["debug"] {
		log.Printf("resp=%#v\n", resp)
		log.Printf("err=%s\n", err)
	}
	if err != nil {
		return nil, err
	}
	// Create new instance, if it already exist then just use it
	// todo: better handling of duplicate instance
	if resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusConflict {
		return nil, fmt.Errorf("Failed to create server instance (status code %d)", resp.StatusCode)
	}

	// API returns URI of new resource in Location header
	uri := resp.Header.Get("Location")
	if uri == "" {
		return nil, fmt.Errorf("API did not return location of new server instance")
	}

	// GET <api>/instances/server/id (URI)
	code, data, err := i.api.Get(i.agentConfig.ApiKey, uri)
	if i.flags["debug"] {
		log.Printf("code=%d\n", code)
		log.Printf("err=%s\n", err)
	}
	if err != nil {
		return nil, err
	}
	if code != http.StatusOK {
		return nil, fmt.Errorf("Failed to get new server instance (status code %d)", code)
	}
	if err := json.Unmarshal(data, si); err != nil {
		return nil, err
	}
	return si, nil
}