Skip to content

Commit

Permalink
Merge pull request #10621 from rajatchopra/f5
Browse files Browse the repository at this point in the history
Merged by openshift-bot
  • Loading branch information
OpenShift Bot authored Oct 12, 2016
2 parents a5c2619 + 6926d71 commit 2cd1700
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 3 deletions.
14 changes: 11 additions & 3 deletions pkg/sdn/api/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

oapi "github.com/openshift/origin/pkg/api"
sdnapi "github.com/openshift/origin/pkg/sdn/api"
sdnplugin "github.com/openshift/origin/pkg/sdn/plugin"
)

// ValidateClusterNetwork tests if required fields in the ClusterNetwork are set.
Expand Down Expand Up @@ -85,9 +86,16 @@ func ValidateClusterNetworkUpdate(obj *sdnapi.ClusterNetwork, old *sdnapi.Cluste
func ValidateHostSubnet(hs *sdnapi.HostSubnet) field.ErrorList {
allErrs := validation.ValidateObjectMeta(&hs.ObjectMeta, false, oapi.MinimalNameRequirements, field.NewPath("metadata"))

_, _, err := net.ParseCIDR(hs.Subnet)
if err != nil {
allErrs = append(allErrs, field.Invalid(field.NewPath("subnet"), hs.Subnet, err.Error()))
if hs.Subnet == "" {
// check if annotation exists, then let the Subnet field be empty
if _, ok := hs.Annotations[sdnplugin.AssignHostSubnetAnnotation]; !ok {
allErrs = append(allErrs, field.Invalid(field.NewPath("subnet"), hs.Subnet, "Field cannot be empty"))
}
} else {
_, _, err := net.ParseCIDR(hs.Subnet)
if err != nil {
allErrs = append(allErrs, field.Invalid(field.NewPath("subnet"), hs.Subnet, err.Error()))
}
}
if net.ParseIP(hs.HostIP) == nil {
allErrs = append(allErrs, field.Invalid(field.NewPath("hostIP"), hs.HostIP, "invalid IP address"))
Expand Down
1 change: 1 addition & 0 deletions pkg/sdn/plugin/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const (
IngressBandwidthAnnotation string = "kubernetes.io/ingress-bandwidth"
EgressBandwidthAnnotation string = "kubernetes.io/egress-bandwidth"
AssignMacVlanAnnotation string = "pod.network.openshift.io/assign-macvlan"
AssignHostSubnetAnnotation string = "pod.network.openshift.io/assign-subnet"
)

func IsOpenShiftNetworkPlugin(pluginName string) bool {
Expand Down
36 changes: 36 additions & 0 deletions pkg/sdn/plugin/subnets.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ func (master *OsdnMaster) SubnetStartMaster(clusterNetwork *net.IPNet, hostSubne
}

go utilwait.Forever(master.watchNodes, 0)
go utilwait.Forever(master.watchSubnets, 0)
return nil
}

Expand Down Expand Up @@ -201,6 +202,41 @@ func (node *OsdnNode) SubnetStartNode() error {
return nil
}

// Only run on the master
// Watch for all hostsubnet events and if one is found with the right annotation, use the SubnetAllocator to dole a real subnet
func (master *OsdnMaster) watchSubnets() {
RunEventQueue(master.osClient, HostSubnets, func(delta cache.Delta) error {
hs := delta.Object.(*osapi.HostSubnet)
name := hs.ObjectMeta.Name
hostIP := hs.HostIP

log.V(5).Infof("Watch %s event for HostSubnet %q", delta.Type, hs.ObjectMeta.Name)
switch delta.Type {
case cache.Sync, cache.Added, cache.Updated:
if _, ok := hs.Annotations[AssignHostSubnetAnnotation]; ok {
// Delete the annotated hostsubnet and create a new one with an assigned subnet
// We do not update (instead of delete+create) because the watchSubnets on the nodes
// will skip the event if it finds that the hostsubnet has the same host
// And we cannot fix the watchSubnets code for node because it will break migration if
// nodes are upgraded after the master
err := master.osClient.HostSubnets().Delete(name)
if err != nil {
log.Errorf("Error in deleting annotated subnet from master, name: %s, ip %s: %v", name, hostIP, err)
return nil
}
err = master.addNode(name, hostIP)
if err != nil {
log.Errorf("Error creating subnet for node %s, ip %s: %v", name, hostIP, err)
return nil
}
}
case cache.Deleted:
// ignore all deleted hostsubnets
}
return nil
})
}

// Only run on the nodes
func (node *OsdnNode) watchSubnets() {
subnets := make(map[string]*osapi.HostSubnet)
Expand Down
7 changes: 7 additions & 0 deletions pkg/util/netutils/subnet_allocator.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package netutils
import (
"fmt"
"net"
"sync"
)

type SubnetAllocator struct {
Expand All @@ -14,6 +15,7 @@ type SubnetAllocator struct {
rightMask uint32
next uint32
allocMap map[string]bool
mutex sync.Mutex
}

func NewSubnetAllocator(network string, hostBits uint32, inUse []string) (*SubnetAllocator, error) {
Expand Down Expand Up @@ -85,6 +87,9 @@ func (sna *SubnetAllocator) GetNetwork() (*net.IPNet, error) {
numSubnets uint32
numSubnetBits uint32
)
sna.mutex.Lock()
defer sna.mutex.Unlock()

baseipu := IPToUint32(sna.network.IP)
netMaskSize, _ := sna.network.Mask.Size()
numSubnetBits = 32 - uint32(netMaskSize) - sna.hostBits
Expand All @@ -109,6 +114,8 @@ func (sna *SubnetAllocator) GetNetwork() (*net.IPNet, error) {
}

func (sna *SubnetAllocator) ReleaseNetwork(ipnet *net.IPNet) error {
sna.mutex.Lock()
defer sna.mutex.Unlock()
if !sna.network.Contains(ipnet.IP) {
return fmt.Errorf("Provided subnet %v doesn't belong to the network %v.", ipnet, sna.network)
}
Expand Down

0 comments on commit 2cd1700

Please sign in to comment.