diff --git a/src/entity/network.go b/src/entity/network.go index bdb3e08b..c8b0d538 100644 --- a/src/entity/network.go +++ b/src/entity/network.go @@ -10,16 +10,20 @@ const ( NetworkCollectionName string = "networks" ) +type PhysicalPort struct { + Name string `bson:"name" json:"name"` + MTU int `bson:"maximumTransmissionUnit" MTC:"maximumTransmissionUnit"` + VlanTags []int `bson:"vlanTag" MTC:"vlanTag"` +} + type Network struct { - ID bson.ObjectId `bson:"_id,omitempty" json:"id"` - DisplayName string `bson:"displayName" json:"displayName"` - BridgeName string `bson:"bridgeName" json:"bridgeName"` - BridgeType string `bson:"bridgeType" json:"bridgeType"` - Node string `bson:"node" json:"node"` - Interface string `bson:"interface" json:"interface"` - Ports []int32 `bson:"ports" json:"ports"` - MTU int32 `bson:"maximumTransmissionUnit" MTC:"maximumTransmissionUnit"` - CreatedAt *time.Time `bson:"createdAt,omitempty" json:"createdAt,omitempty"` + ID bson.ObjectId `bson:"_id,omitempty" json:"id"` + DisplayName string `bson:"displayName" json:"displayName"` + BridgeName string `bson:"bridgeName" json:"bridgeName"` + BridgeType string `bson:"bridgeType" json:"bridgeType"` + Node string `bson:"node" json:"node"` + PhysicalPorts []PhysicalPort `bson:"physicalPorts" json:"physicalPorts"` + CreatedAt *time.Time `bson:"createdAt,omitempty" json:"createdAt,omitempty"` } //GetCollection - get model mongo collection name. diff --git a/src/server/handler_network.go b/src/server/handler_network.go index 9dfa761e..957fa86b 100644 --- a/src/server/handler_network.go +++ b/src/server/handler_network.go @@ -27,6 +27,16 @@ func CreateNetworkHandler(ctx *web.Context) { session := as.Mongo.NewSession() defer session.Close() + // Check whether vlangTag is 0~4095 + for _, pp := range network.PhysicalPorts { + for _, vlangTag := range pp.VlanTags { + if vlangTag < 0 || vlangTag > 4095 { + response.BadRequest(req.Request, resp.ResponseWriter, fmt.Errorf("the vlangTag %v in PhysicalPort %v should between 0 and 4095", pp.Name, vlangTag)) + return + } + } + } + // Check whether this displayname has been used query := bson.M{"displayName": network.DisplayName} existed := entity.Network{} @@ -42,21 +52,6 @@ func CreateNetworkHandler(ctx *web.Context) { return } - // Check whether this Interface has been used - query = bson.M{"node": network.Node, "interface": network.Interface} - existed = entity.Network{} - if err := session.FindOne(entity.NetworkCollectionName, query, &existed); err != nil { - if err.Error() != mgo.ErrNotFound.Error() { - logger.Error(err) - response.InternalServerError(req.Request, resp.ResponseWriter, err) - return - } - } - if len(existed.ID) > 1 { - response.Conflict(req.Request, resp, fmt.Errorf("interface %s on the Node %s has already be used", network.Interface, network.Node)) - return - } - // Check whether this bridge has been used query = bson.M{"bridgeName": network.BridgeName} existed = entity.Network{} diff --git a/src/server/handler_network_test.go b/src/server/handler_network_test.go index c0f43719..4b87750c 100644 --- a/src/server/handler_network_test.go +++ b/src/server/handler_network_test.go @@ -20,14 +20,17 @@ func TestCreateNetwork(t *testing.T) { cf := config.MustRead("../../config/testing.json") sp := serviceprovider.New(cf) + eth1 := entity.PhysicalPort{ + Name: "eth1", + MTU: 1500, + VlanTags: []int{2043, 2143, 2243}, + } network := entity.Network{ - DisplayName: "OVS Bridge", - BridgeName: "obsbr1", - BridgeType: "ovs", - Node: "node1", - Interface: "eth3", - Ports: []int32{2043, 2143, 2243}, - MTU: 1500, + DisplayName: "OVS Bridge", + BridgeName: "obsbr1", + BridgeType: "ovs", + Node: "node1", + PhysicalPorts: []entity.PhysicalPort{eth1}, } session := sp.Mongo.NewSession() @@ -49,18 +52,26 @@ func TestCreateNetwork(t *testing.T) { assertResponseCode(t, http.StatusOK, httpWriter) } -func TestConflictDisplayName(t *testing.T) { +func TestWrongVlangTag(t *testing.T) { cf := config.MustRead("../../config/testing.json") sp := serviceprovider.New(cf) + eth1 := entity.PhysicalPort{ + Name: "eth1", + MTU: 1500, + VlanTags: []int{1234, 2143, 2243}, + } + eth2 := entity.PhysicalPort{ + Name: "eth2", + MTU: 1500, + VlanTags: []int{1234, 2143, 50000}, + } network := entity.Network{ - DisplayName: "OVS Bridge", - BridgeName: "obsbr1", - BridgeType: "ovs", - Node: "node1", - Interface: "eth3", - Ports: []int32{2043, 2143, 2243}, - MTU: 1500, + DisplayName: "OVS Bridge", + BridgeName: "obsbr1", + BridgeType: "ovs", + Node: "node1", + PhysicalPorts: []entity.PhysicalPort{eth1, eth2}, } session := sp.Mongo.NewSession() @@ -79,43 +90,24 @@ func TestConflictDisplayName(t *testing.T) { service := newNetworkService(sp) wc.Add(service) wc.Dispatch(httpWriter, httpRequest) - assertResponseCode(t, http.StatusOK, httpWriter) - - networkWithSameName := entity.Network{ - DisplayName: "OVS Bridge", - BridgeName: "obsbr2", - BridgeType: "ovs", - Node: "node2", - Interface: "eth4", - Ports: []int32{2043, 2143, 2243}, - MTU: 1500, - } - - bodyBytesConflict, err := json.MarshalIndent(networkWithSameName, "", " ") - assert.NoError(t, err) - - bodyReaderConflict := strings.NewReader(string(bodyBytesConflict)) - httpRequestConflict, err := http.NewRequest("POST", "http://localhost:7890/v1/networks", bodyReaderConflict) - assert.NoError(t, err) - - httpRequestConflict.Header.Add("Content-Type", "application/json") - httpWriterConflict := httptest.NewRecorder() - wc.Dispatch(httpWriterConflict, httpRequestConflict) - assertResponseCode(t, http.StatusConflict, httpWriterConflict) + assertResponseCode(t, http.StatusBadRequest, httpWriter) } -func TestConflictBridgeName(t *testing.T) { +func TestConflictDisplayName(t *testing.T) { cf := config.MustRead("../../config/testing.json") sp := serviceprovider.New(cf) + eth1 := entity.PhysicalPort{ + Name: "eth1", + MTU: 1500, + VlanTags: []int{2043, 2143, 2243}, + } network := entity.Network{ - DisplayName: "OVS Bridge", - BridgeName: "obsbr1", - BridgeType: "ovs", - Node: "node1", - Interface: "eth3", - Ports: []int32{2043, 2143, 2243}, - MTU: 1500, + DisplayName: "OVS Bridge", + BridgeName: "obsbr1", + BridgeType: "ovs", + Node: "node1", + PhysicalPorts: []entity.PhysicalPort{eth1}, } session := sp.Mongo.NewSession() @@ -136,17 +128,15 @@ func TestConflictBridgeName(t *testing.T) { wc.Dispatch(httpWriter, httpRequest) assertResponseCode(t, http.StatusOK, httpWriter) - networkWithSameName := entity.Network{ - DisplayName: "test", - BridgeName: "obsbr1", - BridgeType: "ovs", - Node: "node2", - Interface: "eth4", - Ports: []int32{2043, 2143, 2243}, - MTU: 1500, + networkWithSameInterface := entity.Network{ + DisplayName: "OVS Bridge", + BridgeName: "obsbr2", + BridgeType: "ovs", + Node: "node1", + PhysicalPorts: []entity.PhysicalPort{eth1}, } - bodyBytesConflict, err := json.MarshalIndent(networkWithSameName, "", " ") + bodyBytesConflict, err := json.MarshalIndent(networkWithSameInterface, "", " ") assert.NoError(t, err) bodyReaderConflict := strings.NewReader(string(bodyBytesConflict)) @@ -159,18 +149,21 @@ func TestConflictBridgeName(t *testing.T) { assertResponseCode(t, http.StatusConflict, httpWriterConflict) } -func TestConflictInterface(t *testing.T) { +func TestConflictBridgeName(t *testing.T) { cf := config.MustRead("../../config/testing.json") sp := serviceprovider.New(cf) + eth1 := entity.PhysicalPort{ + Name: "eth1", + MTU: 1500, + VlanTags: []int{2043, 2143, 2243}, + } network := entity.Network{ - DisplayName: "OVS Bridge", - BridgeName: "obsbr1", - BridgeType: "ovs", - Node: "node1", - Interface: "eth3", - Ports: []int32{2043, 2143, 2243}, - MTU: 1500, + DisplayName: "OVS Bridge", + BridgeName: "obsbr1", + BridgeType: "ovs", + Node: "node1", + PhysicalPorts: []entity.PhysicalPort{eth1}, } session := sp.Mongo.NewSession() @@ -192,13 +185,11 @@ func TestConflictInterface(t *testing.T) { assertResponseCode(t, http.StatusOK, httpWriter) networkWithSameName := entity.Network{ - DisplayName: "test", - BridgeName: "test", - BridgeType: "ovs", - Node: "node1", - Interface: "eth3", - Ports: []int32{2043, 2143, 2243}, - MTU: 1500, + DisplayName: "OVS", + BridgeName: "obsbr1", + BridgeType: "ovs", + Node: "node2", + PhysicalPorts: []entity.PhysicalPort{eth1}, } bodyBytesConflict, err := json.MarshalIndent(networkWithSameName, "", " ") @@ -212,21 +203,23 @@ func TestConflictInterface(t *testing.T) { httpWriterConflict := httptest.NewRecorder() wc.Dispatch(httpWriterConflict, httpRequestConflict) assertResponseCode(t, http.StatusConflict, httpWriterConflict) - } func TestDeleteNetwork(t *testing.T) { cf := config.MustRead("../../config/testing.json") sp := serviceprovider.New(cf) + eth1 := entity.PhysicalPort{ + Name: "eth1", + MTU: 1500, + VlanTags: []int{2043, 2143, 2243}, + } network := entity.Network{ - DisplayName: "OVS Bridge", - BridgeName: "obsbr1", - BridgeType: "ovs", - Node: "node1", - Interface: "eth3", - Ports: []int32{2043, 2143, 2243}, - MTU: 1500, + DisplayName: "OVS Bridge", + BridgeName: "obsbr1", + BridgeType: "ovs", + Node: "node1", + PhysicalPorts: []entity.PhysicalPort{eth1}, } bodyBytes, err := json.MarshalIndent(network, "", " ") @@ -283,14 +276,17 @@ func TestUpdateNetwork(t *testing.T) { cf := config.MustRead("../../config/testing.json") sp := serviceprovider.New(cf) + eth1 := entity.PhysicalPort{ + Name: "eth1", + MTU: 1500, + VlanTags: []int{2043, 2143, 2243}, + } network := entity.Network{ - DisplayName: "OVS Bridge", - BridgeName: "obsbr1", - BridgeType: "ovs", - Node: "node1", - Interface: "eth3", - Ports: []int32{2043, 2143, 2243}, - MTU: 1500, + DisplayName: "OVS Bridge", + BridgeName: "obsbr1", + BridgeType: "ovs", + Node: "node1", + PhysicalPorts: []entity.PhysicalPort{eth1}, } session := sp.Mongo.NewSession() @@ -340,14 +336,17 @@ func TestWrongUpdateNetwork(t *testing.T) { cf := config.MustRead("../../config/testing.json") sp := serviceprovider.New(cf) + eth1 := entity.PhysicalPort{ + Name: "eth1", + MTU: 1500, + VlanTags: []int{2043, 2143, 2243}, + } network := entity.Network{ - DisplayName: "OVS Bridge", - BridgeName: "obsbr1", - BridgeType: "ovs", - Node: "node1", - Interface: "eth3", - Ports: []int32{2043, 2143, 2243}, - MTU: 1500, + DisplayName: "OVS Bridge", + BridgeName: "obsbr1", + BridgeType: "ovs", + Node: "node1", + PhysicalPorts: []entity.PhysicalPort{eth1}, } session := sp.Mongo.NewSession()