Exemple #1
0
func (policy *PolicySvc) deletePolicyHandler(input interface{}, ctx common.RestContext) (interface{}, error) {
	idStr := strings.TrimSpace(ctx.PathVariables["policyID"])
	if idStr == "" {
		if input == nil {
			return nil, common.NewError400("Request must either be to /policies/{policyID} or have a body.")
		}
		policyDoc := input.(*common.Policy)
		err := policyDoc.Validate()
		if err != nil {
			return nil, err
		}
		log.Printf("IN deletePolicyHandler with %v", policyDoc)
		id, err := policy.store.lookupPolicy(policyDoc.ExternalID)

		if err != nil {
			// 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

			id, err = policy.store.lookupPolicy(policyDoc.ExternalID)
		}

		log.Printf("Found %d / %v (%T) from external ID %s", id, err, err, policyDoc.ExternalID)
		if err != nil {
			return nil, err
		}
		return policy.deletePolicy(id)
	} else {
		if input != nil {
			common.NewError400("Request must either be to /policies/{policyID} or have a body.")
		}
		id, err := strconv.ParseUint(idStr, 10, 64)
		if err != nil {
			return nil, common.NewError404("policy", idStr)
		}
		return policy.deletePolicy(id)
	}
}
Exemple #2
0
// handlePortUpdate updates the Root service's information with real port
// a service listens on (if it was started with anonymous port 0).
// See https://github.com/romanaproject/romana/wiki/Root-service-API
func (root *Root) handlePortUpdate(input interface{}, ctx common.RestContext) (interface{}, error) {
	pathVars := ctx.PathVariables
	serviceName := pathVars["serviceName"]
	log.Printf("RootService.handlePortUpdate: For service %s got %+v\n", serviceName, input)
	if input == nil {
		return nil, common.NewError400("Port update message expected, received nothing")
	}
	portUpdateMsg := input.(*common.PortUpdateMessage)
	serviceConfig := root.config.full.Services[serviceName]
	oldPort := serviceConfig.Common.Api.Port
	serviceConfig.Common.Api.Port = portUpdateMsg.Port
	log.Printf("RootService: registering port %d for service %s (was %d)\n", serviceConfig.Common.Api.Port, serviceName, oldPort)
	return nil, nil
}
Exemple #3
0
// augmentEndpoint augments the endpoint provided with appropriate information
// by looking it up in the appropriate service.
func (policy *PolicySvc) augmentEndpoint(endpoint *common.Endpoint) error {
	tenantSvcUrl, err := policy.client.GetServiceUrl("tenant")
	if err != nil {
		return err
	}
	if endpoint.Peer == common.Wildcard {
		// If a wildcard is specfied, there is nothing to augment
		return nil
	}
	log.Printf("Policy: Augmenting  %#v", endpoint)

	// Code below tries to resolve tenant name into tenant_network_id if possible.
	//
	// TODO this will have to be changed once we implement
	// https://paninetworks.kanbanize.com/ctrl_board/3/cards/319/details
	ten := &tenant.Tenant{}
	if endpoint.TenantNetworkID == nil {
		if endpoint.TenantID != 0 {
			tenantIDToUse := strconv.FormatUint(endpoint.TenantID, 10)
			tenantsUrl := fmt.Sprintf("%s/tenants/%s", tenantSvcUrl, tenantIDToUse)
			log.Printf("Policy: Looking tenant up at %s", tenantsUrl)
			err = policy.client.Get(tenantsUrl, ten)
			if err != nil {
				return err
			}

			endpoint.TenantNetworkID = &ten.NetworkID

		} else if endpoint.TenantExternalID != "" || endpoint.TenantName != "" {
			if endpoint.TenantExternalID != "" {
				ten.ExternalID = endpoint.TenantExternalID
			}
			if endpoint.TenantName != "" {
				ten.Name = endpoint.TenantName
			}
			err = policy.client.Find(ten, common.FindLast)
			if err != nil {
				return err
			}

			endpoint.TenantNetworkID = &ten.NetworkID
		}
	}

	if endpoint.SegmentNetworkID == nil {
		if ten == nil && (endpoint.SegmentID != 0 || endpoint.SegmentExternalID != "" || endpoint.SegmentName != "") {
			return common.NewError400("No tenant information specified, cannot look up segment.")
		}
		segment := &tenant.Segment{}
		if endpoint.SegmentID != 0 {
			segmentIDToUse := strconv.FormatUint(endpoint.SegmentID, 10)
			segmentsUrl := fmt.Sprintf("%s/tenants/%d/segments/%s", tenantSvcUrl, ten.ID, segmentIDToUse)
			log.Printf("Policy: Looking segment up at %s for %#v", segmentsUrl, endpoint)
			err = policy.client.Get(segmentsUrl, &segment)
			if err != nil {
				return err
			}
			endpoint.SegmentNetworkID = &segment.NetworkID
		} else if endpoint.SegmentExternalID != "" || endpoint.SegmentName != "" {
			segmentsUrl := fmt.Sprintf("%s/findLast/segments?tenant_id=%d&", tenantSvcUrl, ten.ID)
			if endpoint.SegmentExternalID != "" {
				segmentsUrl += "external_id=" + endpoint.TenantExternalID + "&"
			}
			if endpoint.SegmentName != "" {
				segmentsUrl += "name=" + endpoint.SegmentName
			}
			log.Printf("Policy: Finding segments at %s for %#v (Tenant %#v %t)", segmentsUrl, endpoint, ten, ten == nil)
			err = policy.client.Get(segmentsUrl, &segment)
			if err != nil {
				return err
			}
			endpoint.SegmentNetworkID = &segment.NetworkID
		}
	}
	return nil
}
Exemple #4
0
func (s *mockSvc) Routes() common.Routes {
	policyDbFile := s.mySuite.RomanaTestSuite.GetMockSqliteFile("policy")
	policyServiceConfig := fmt.Sprintf(`{
			          "common":{
						"api":{"host":"0.0.0.0","port":0}
					 },
			   	      "config":{"store":
			  			 {"type" : "sqlite3",  "database" : "%s" }
			  		  }	 
			        }`, policyDbFile)

	tenantGetRoute := common.Route{
		Method:  "GET",
		Pattern: "/tenants/1",
		Handler: func(input interface{}, ctx common.RestContext) (interface{}, error) {
			return &tenant.Tenant{ID: 1, Name: "default", ExternalID: "default", NetworkID: 1}, nil
		},
	}

	segmentGetRoute := common.Route{
		Method:  "GET",
		Pattern: "/tenants/1/segments/{id}",
		Handler: func(input interface{}, ctx common.RestContext) (interface{}, error) {
			idInt, err := strconv.ParseUint(ctx.PathVariables["id"], 10, 64)
			if err != nil {
				return nil, err
			}
			return &tenant.Segment{ID: idInt, Name: "backend", ExternalID: "backend"}, nil
		},
	}

	policyConfigRoute := common.Route{
		Method:  "GET",
		Pattern: "/config/policy",
		Handler: func(input interface{}, ctx common.RestContext) (interface{}, error) {
			return common.Raw{Body: policyServiceConfig}, nil
		},
	}

	// Simulate agent
	agentAddPolicyRoute := common.Route{
		Method:  "POST",
		Pattern: "/policies",
		Handler: func(input interface{}, ctx common.RestContext) (interface{}, error) {
			log.Printf("Agent received policy: %v", input)
			policyDoc := input.(*common.Policy)
			log.Printf("Agent received policy: %s", policyDoc.Name)
			if policyDoc.Datacenter.TenantBits == 0 {
				return nil, common.NewError400("Datacenter information invalid.")
			}
			return nil, nil
		},
		MakeMessage: func() interface{} { return &common.Policy{} },
	}

	agentDeletePolicyRoute := common.Route{
		Method:  "DELETE",
		Pattern: "/policies",
		Handler: func(input interface{}, ctx common.RestContext) (interface{}, error) {
			log.Printf("Agent received policy: %v", input)
			policyDoc := input.(*common.Policy)
			log.Printf("Agent received policy: %s", policyDoc.Name)
			if policyDoc.Datacenter.TenantBits == 0 {
				return nil, common.NewError400("Datacenter information invalid.")
			}
			return nil, nil
		},
		MakeMessage: func() interface{} { return &common.Policy{} },
	}

	// This simulates both root's and topology's index response
	rootRoute := common.Route{
		Method:  "GET",
		Pattern: "/",
		Handler: func(input interface{}, ctx common.RestContext) (interface{}, error) {
			json := `{"serviceName":"root",
			"Links":
			[
			{"Href":"/config/root","Rel":"root-config"},
			{"Href":"/config/ipam","Rel":"ipam-config"},
			{"Href":"/config/tenant","Rel":"tenant-config"},
			{"Href":"/config/topology","Rel":"topology-config"},
			{"Href":"/config/agent","Rel":"agent-config"},
			{"Href":"/config/policy","Rel":"policy-config"},
			{"Href":"/config/kubernetesListener","Rel":"kubernetesListener-config"},
			{"Href":"/datacenter","Rel":"datacenter"},
			{"Href":"/hosts","Rel":"host-list"},
			{"Href":"SERVICE_URL","Rel":"self"}
			], 
			"Services":
			[
			{"Name":"root","Links":[{"Href":"SERVICE_URL","Rel":"service"}]},
			{"Name":"ipam","Links":[{"Href":"SERVICE_URL","Rel":"service"}]},
			{"Name":"tenant","Links":[{"Href":"SERVICE_URL","Rel":"service"}]},
			{"Name":"topology","Links":[{"Href":"SERVICE_URL","Rel":"service"}]},
			{"Name":"agent","Links":[{"Href":"SERVICE_URL:PORT","Rel":"service"}]},
			{"Name":"policy","Links":[{"Href":"SERVICE_URL","Rel":"service"}]},
			{"Name":"kubernetesListener","Links":[{"Href":"SERVICE_URL","Rel":"service"}]}
			]
			}
			`
			retval := fmt.Sprintf(strings.Replace(json, "SERVICE_URL", s.mySuite.serviceURL, -1))
			//			log.Printf("Using %s->SERVICE_URL, replaced\n\t%swith\n\t%s", s.mySuite.serviceURL, json, retval)
			return common.Raw{Body: retval}, nil
		},
	}

	dcRoute := common.Route{
		Method:  "GET",
		Pattern: "/datacenter",
		Handler: func(input interface{}, ctx common.RestContext) (interface{}, error) {
			json := `
			{"id":0,
			"ip_version":4,
			"cidr":"10.0.0.0/8",
			"prefix_bits":8,
			"port_bits":8,
			"tenant_bits":4,
			"segment_bits":4,
			"endpoint_bits":8,
			"endpoint_space_bits":0,
			"name":"main"}
			`
			return common.Raw{Body: json}, nil
		},
	}

	hostsRoute := common.Route{
		Method:  "GET",
		Pattern: "/hosts",
		Handler: func(input interface{}, ctx common.RestContext) (interface{}, error) {
			hosts := make([]common.Host, 1)
			hosts[0] = common.Host{Ip: "127.0.0.1", AgentPort: s.mySuite.servicePort}
			return hosts, nil
		},
	}

	registerPortRoute := common.Route{
		Method:  "POST",
		Pattern: "/config/kubernetes-listener/port",
		Handler: func(input interface{}, ctx common.RestContext) (interface{}, error) {
			log.Printf("Received %#v", input)
			return "OK", nil
		},
	}

	routes := common.Routes{
		rootRoute,
		tenantGetRoute,
		segmentGetRoute,
		registerPortRoute,
		policyConfigRoute,
		dcRoute,
		hostsRoute,
		agentAddPolicyRoute,
		agentDeletePolicyRoute,
	}
	log.Printf("mockService: Set up routes: %#v", routes)
	return routes
}