Example #1
0
// handleHostListPost handles addition of a host to the current datacenter.
// If the Host.AgentPort is not specified, root service is queried for
// the default Agent port.
func (topology *TopologySvc) handleHostListPost(input interface{}, ctx common.RestContext) (interface{}, error) {
	host := input.(*common.Host)
	// If no agent port is specfied in the creation of new host,
	// get the agent port from root service.
	log.Printf("Host requested with agent port %d", host.AgentPort)
	if host.AgentPort == 0 {
		// Get the one from configuration
		agentConfig, err := topology.client.GetServiceConfig("agent")
		if err != nil {
			return nil, err
		}
		host.AgentPort = agentConfig.Common.Api.Port
		if host.AgentPort == 0 {
			return nil, common.NewError500("Cannot determine port for agent")
		}
	}
	log.Printf("Host will be added with agent port %d", host.AgentPort)
	err := topology.store.addHost(topology.datacenter, host)
	if err != nil {
		return nil, err
	}
	agentURL := fmt.Sprintf("http://%s:%d", host.Ip, host.AgentPort)
	agentLink := common.LinkResponse{Href: agentURL, Rel: "agent"}
	hostLink := common.LinkResponse{Href: hostListPath + "/" + fmt.Sprintf("%d", host.ID), Rel: "self"}
	collectionLink := common.LinkResponse{Href: hostListPath, Rel: "self"}
	host.Links = []common.LinkResponse{agentLink, hostLink, collectionLink}
	return host, nil
}
Example #2
0
// findPolicyByName returns the first policy found corresponding
// to the given policy name. Policy names are not unique unlike
// policy ID's.
func (policy *PolicySvc) findPolicyByName(input interface{}, ctx common.RestContext) (interface{}, error) {
	nameStr := ctx.PathVariables["policyName"]
	log.Printf("In findPolicy(%s)\n", nameStr)
	if nameStr == "" {
		return nil, common.NewError500(fmt.Sprintf("Expected policy name, got %s", nameStr))
	}
	policyDoc, err := policy.store.findPolicyByName(nameStr)
	if err != nil {
		return nil, err
	}
	policyDoc.Datacenter = nil
	return policyDoc, nil
}
Example #3
0
// deletePolicy deletes policy based the following algorithm:
//1. Mark the policy as "deleted" in the backend store.
func (policy *PolicySvc) deletePolicy(id uint64) (interface{}, error) {
	// TODO do we need this to be transactional or not ... case can be made for either.
	err := policy.store.inactivatePolicy(id)
	if err != nil {
		return nil, err
	}
	policyDoc, err := policy.store.getPolicy(id, true)
	log.Printf("Found policy for ID %d: %s (%v)", id, policyDoc, err)
	if err != nil {
		return nil, err
	}
	hosts, err := policy.client.ListHosts()
	if err != nil {
		return nil, err
	}

	if policyDoc.ExternalID == "" {
		// TODO
		// Important! This should really be done in policy agent.
		// Only done here as temporary measure.
		externalId := makeId(policyDoc.AppliedTo, policyDoc.Name)
		log.Printf("Constructing internal policy name = %s", externalId)
		policyDoc.ExternalID = externalId
	}

	errStr := make([]string, 0)
	for _, host := range hosts {
		// TODO make schema configurable
		url := fmt.Sprintf("http://%s:%d/policies", host.Ip, host.AgentPort)
		result := make(map[string]interface{})
		err = policy.client.Delete(url, policyDoc, result)
		log.Printf("Agent at %s returned %v", host.Ip, result)
		if err != nil {
			errStr = append(errStr, fmt.Sprintf("Error deleting policy %d (%s) from host %s: %v. ", id, policyDoc.Name, host.Ip, err))
		}
	}
	if len(errStr) > 0 {
		return nil, common.NewError500(errStr)
	}
	err = policy.store.deletePolicy(id)
	if err != nil {
		return nil, err
	}
	policyDoc.Datacenter = nil
	return policyDoc, nil
}
Example #4
0
// distributePolicy distributes policy to all agents.
// TODO how should error handling work here really?
func (policy *PolicySvc) distributePolicy(policyDoc *common.Policy) error {
	hosts, err := policy.client.ListHosts()
	if err != nil {
		return err
	}
	errStr := make([]string, 0)
	for _, host := range hosts {
		// TODO make schema configurable
		url := fmt.Sprintf("http://%s:%d/policies", host.Ip, host.AgentPort)
		log.Printf("Sending policy %s to agent at %s", policyDoc.Name, url)
		result := make(map[string]interface{})
		err = policy.client.Post(url, policyDoc, &result)
		log.Printf("Agent at %s returned %v", host.Ip, result)
		if err != nil {
			errStr = append(errStr, fmt.Sprintf("Error applying policy %d to host %s: %v. ", policyDoc.ID, host.Ip, err))
		}
	}
	if len(errStr) > 0 {
		return common.NewError500(errStr)
	}
	return nil
}
Example #5
0
File: store.go Project: romana/core
// deleteEndpoint releases the IP(s) owned by the endpoint into assignable
// pool.
func (ipamStore *ipamStore) deleteEndpoint(ip string) (Endpoint, error) {
	tx := ipamStore.DbStore.Db.Begin()
	results := make([]Endpoint, 0)
	tx.Where(&Endpoint{Ip: ip}).Find(&results)
	if len(results) == 0 {
		tx.Rollback()
		return Endpoint{}, common.NewError404("endpoint", ip)
	}
	if len(results) > 1 {
		// This cannot happen by constraints...
		tx.Rollback()
		errMsg := fmt.Sprintf("Expected one result for ip %s, got %v", ip, results)
		log.Printf(errMsg)
		return Endpoint{}, common.NewError500(errors.New(errMsg))
	}
	tx = tx.Model(Endpoint{}).Where("ip = ?", ip).Update("in_use", false)
	err := common.MakeMultiError(tx.GetErrors())
	if err != nil {
		tx.Rollback()
		return Endpoint{}, err
	}
	tx.Commit()
	return results[0], nil
}