// Initializes topology service func (topology *TopologySvc) Initialize() error { log.Println("Parsing", topology.datacenter) ip, _, err := net.ParseCIDR(topology.datacenter.Cidr) if err != nil { return err } topology.datacenter.Prefix = common.IPv4ToInt(ip) return topology.store.connect() }
// handleHost handles request for a specific host's info func (ipam *IPAMSvc) addVm(input interface{}, ctx common.RestContext) (interface{}, error) { vm := input.(*Vm) err := ipam.store.addVm(ipam.dc.EndpointSpaceBits, vm) if err != nil { return nil, err } client, err := common.NewRestClient("", ipam.config.Common.Api.RestTimeoutMillis) if err != nil { return nil, err } // Get host info from topology service topoUrl, err := client.GetServiceUrl(ipam.config.Common.Api.RootServiceUrl, "topology") if err != nil { return nil, err } index := common.IndexResponse{} err = client.Get(topoUrl, &index) if err != nil { return nil, err } hostsUrl := index.Links.FindByRel("host-list") host := common.HostMessage{} hostInfoUrl := fmt.Sprintf("%s/%s", hostsUrl, vm.HostId) err = client.Get(hostInfoUrl, &host) if err != nil { return nil, err } tenantUrl, err := client.GetServiceUrl(ipam.config.Common.Api.RootServiceUrl, "tenant") if err != nil { return nil, err } // TODO follow links once tenant service supports it. For now... t := &tenant.Tenant{} tenantsUrl := fmt.Sprintf("%s/tenants/%s", tenantUrl, vm.TenantId) log.Printf("IPAM calling %s\n", tenantsUrl) err = client.Get(tenantsUrl, t) if err != nil { return nil, err } log.Printf("IPAM received tenant %s ID %d\n", t.Name, t.Id) segmentUrl := fmt.Sprintf("/tenants/%s/segments/%s", vm.TenantId, vm.SegmentId) log.Printf("IPAM calling %s\n", segmentUrl) segment := &tenant.Segment{} err = client.Get(segmentUrl, segment) if err != nil { return nil, err } log.Printf("Constructing IP from Host IP %s, Tenant %d, Segment %d", host.RomanaIp, t.Seq, segment.Seq) vmBits := 32 - ipam.dc.PrefixBits - ipam.dc.PortBits - ipam.dc.TenantBits - ipam.dc.SegmentBits - ipam.dc.EndpointSpaceBits segmentBitShift := vmBits prefixBitShift := 32 - ipam.dc.PrefixBits tenantBitShift := segmentBitShift + ipam.dc.SegmentBits // hostBitShift := tenantBitShift + ipam.dc.TenantBits log.Printf("Parsing Romana IP address of host %s: %s\n", host.Name, host.RomanaIp) hostIp, _, err := net.ParseCIDR(host.RomanaIp) if err != nil { return nil, err } hostIpInt := common.IPv4ToInt(hostIp) vmIpInt := (ipam.dc.Prefix << prefixBitShift) | hostIpInt | (t.Seq << tenantBitShift) | (segment.Seq << segmentBitShift) | vm.EffectiveSeq vmIpIp := common.IntToIPv4(vmIpInt) log.Printf("Constructing (%d << %d) | %d | (%d << %d) | ( %d << %d ) | %d=%s\n", ipam.dc.Prefix, prefixBitShift, hostIpInt, t.Seq, tenantBitShift, segment.Seq, segmentBitShift, vm.EffectiveSeq, vmIpIp.String()) vm.Ip = vmIpIp.String() return vm, nil }
func (s *MySuite) TestStore(c *check.C) { var err error store := ipamStore{} store.ServiceStore = &store storeConfig := make(map[string]interface{}) storeConfig["type"] = "sqlite3" storeConfig["database"] = s.RomanaTestSuite.GetMockSqliteFile("ipam") err = store.SetConfig(storeConfig) c.Assert(err, check.IsNil) cidr := "10.0.0.0/8" ip, _, _ := net.ParseCIDR(cidr) dc := common.Datacenter{Cidr: cidr, IpVersion: 4, Prefix: common.IPv4ToInt(ip), PrefixBits: 8, PortBits: 8, TenantBits: 4, SegmentBits: 4} _, network, _ := net.ParseCIDR("10.1.0.0/16") hostIpInt := common.IPv4ToInt(network.IP) segmentBitShift := uint64(8) tenantBitShift := uint64(segmentBitShift + 4) upToEndpointIpInt := hostIpInt | (1 << tenantBitShift) | (1 << segmentBitShift) // 253 // 127 // 63 // 31 for _, stride := range []uint{0, 1, 2, 4} { // for _, stride := range []uint{0} { err = store.CreateSchema(true) if err != nil { panic(err) } err = store.Connect() if err != nil { panic(err) } dc.EndpointSpaceBits = stride dc.EndpointBits = 8 - stride endpoint := &Endpoint{Id: 0, EffectiveNetworkID: 0, HostId: "X", SegmentID: "X", TenantID: "X"} i := uint(1) firstIp := "" var upperBound uint switch stride { case 0: upperBound = 253 case 1: upperBound = 127 case 2: upperBound = 64 case 4: upperBound = 16 } log.Printf("For %d/%d go until 1= %d", dc.EndpointBits, stride, upperBound) for i = 1; i <= uint(upperBound); i++ { endpoint.Id = 0 msg := fmt.Sprintf("For stride %d, endpoint bits %d, try %d\n", stride, dc.EndpointBits, i) log.Println(msg) err = store.addEndpoint(endpoint, upToEndpointIpInt, dc) if err != nil { c.Error(fmt.Sprintf("Unexpected error on try %d: %v", i, err)) c.FailNow() } log.Printf("%s: Got IP: %s (effective network ID %d)", msg, endpoint.Ip, endpoint.EffectiveNetworkID) if firstIp == "" { firstIp = endpoint.Ip } } // Here we have reached the end... endpoint.Id = 0 err = store.addEndpoint(endpoint, upToEndpointIpInt, dc) if err == nil { c.Error(fmt.Sprintf("Expected error, but got %+v", endpoint)) c.FailNow() } endpoint.Id = 0 _, err = store.deleteEndpoint(firstIp) if err != nil { c.Error(fmt.Sprintf("Unexpected error on try %d: %v", i, err)) c.FailNow() } endpoint.Id = 0 err = store.addEndpoint(endpoint, upToEndpointIpInt, dc) if err != nil { c.Error(fmt.Sprintf("Unexpected error on try %d: %v", i, err)) c.Fail() } c.Assert(endpoint.Ip, check.Equals, firstIp) if c.Failed() { return } endpoint.Id = 0 err = store.addEndpoint(endpoint, upToEndpointIpInt, dc) if err == nil { c.Error(fmt.Sprintf("Expected error, but got %+v", endpoint)) c.FailNow() } } }