-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from yuewko/v.0.0
V.0.0
- Loading branch information
Showing
16 changed files
with
924 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
FROM ubuntu | ||
|
||
ADD infoblox-daemon /usr/local/bin/infoblox-daemon | ||
|
||
|
||
ENTRYPOINT ["/usr/local/bin/infoblox-daemon"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
COMMON_SOURCES=config.go driver-socket.go cmdargs.go | ||
PLUGIN_SOURCES=plugin.go $(COMMON_SOURCES) | ||
DAEMON_SOURCES=daemon.go infoblox-ipam.go $(COMMON_SOURCES) | ||
PLUGIN_BINARY=infoblox-plugin | ||
DAEMON_BINARY=infoblox-daemon | ||
ALL_BINARIES=$(PLUGIN_BINARY) $(DAEMON_BINARY) | ||
|
||
DAEMON_ACI_IMAGE=infoblox-cni-daemon.aci | ||
DAEMON_DOCKER_IMAGE=infoblox-cni-daemon | ||
DEV_IMAGE=$(DOCKERHUB_ID)/$(DAEMON_DOCKER_IMAGE) # Requires DOCKERHUB_ID environment variable | ||
RELEASE_IMAGE=infoblox/$(DAEMON_DOCKER_IMAGE) | ||
|
||
|
||
# Build binary | ||
all: build | ||
|
||
# Build binary - this is the default target | ||
build: $(ALL_BINARIES) | ||
|
||
$(PLUGIN_BINARY): $(PLUGIN_SOURCES) | ||
go build -o $(PLUGIN_BINARY) $(PLUGIN_SOURCES) | ||
|
||
$(DAEMON_BINARY): $(DAEMON_SOURCES) | ||
go build -o $(DAEMON_BINARY) $(DAEMON_SOURCES) | ||
|
||
# Delete binary for clean build | ||
clean: | ||
rm -f $(ALL_BINARIES) | ||
|
||
|
||
# Container Images... | ||
|
||
images: aci-image docker-image | ||
|
||
docker-image: $(DAEMON_BINARY) | ||
docker build -t $(DAEMON_DOCKER_IMAGE) . | ||
|
||
# Push image to user's docker hub. NOTE: requires DOCKERHUB_ID environment variable | ||
push: docker-image | ||
docker tag $(DAEMON_DOCKER_IMAGE) $(DEV_IMAGE) | ||
docker push $(DEV_IMAGE) | ||
|
||
# Push image to infoblox docker hub | ||
push-release: docker-image | ||
docker tag $(DAEMON_DOCKER_IMAGE) $(RELEASE_IMAGE) | ||
docker push $(RELEASE_IMAGE) | ||
|
||
aci-image: $(DAEMON_ACI_IMAGE) | ||
|
||
$(DAEMON_ACI_IMAGE): $(DAEMON_BINARY) | ||
./build-aci.sh | ||
|
||
# Clean everything | ||
clean-all: clean clean-images | ||
|
||
# Delete local docker images | ||
clean-images: | ||
docker rmi -f $(DAEMON_DOCKER_IMAGE) | ||
/bin/rm -f $(DAEMON_ACI_IMAGE) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
#!/bin/bash | ||
|
||
# Build ACI image for infoblox-daemon | ||
|
||
acbuild begin | ||
|
||
acbuild set-name infoblox.com/cni-infoblox-daemon | ||
|
||
acbuild dependency add quay.io/quay/ubuntu:latest | ||
|
||
acbuild mount add run-cni /run/cni | ||
|
||
acbuild copy infoblox-daemon /usr/local/bin/infoblox-daemon | ||
|
||
acbuild set-exec /usr/local/bin/infoblox-daemon | ||
|
||
acbuild write --overwrite infoblox-cni-daemon.aci | ||
|
||
acbuild end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// Copyright 2016 Infoblox Inc. | ||
// All Rights Reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
// not use this file except in compliance with the License. You may obtain | ||
// a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
// License for the specific language governing permissions and limitations | ||
// under the License. | ||
|
||
package main | ||
|
||
import ( | ||
"github.com/containernetworking/cni/pkg/skel" | ||
) | ||
|
||
// Extend skel.CmdArgs to include IfMac | ||
// IfMac is set in the plugin and sent to the daemon | ||
type ExtCmdArgs struct { | ||
skel.CmdArgs | ||
IfMac string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
// Copyright 2016 Infoblox Inc. | ||
// All Rights Reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
// not use this file except in compliance with the License. You may obtain | ||
// a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
// License for the specific language governing permissions and limitations | ||
// under the License. | ||
|
||
package main | ||
|
||
import ( | ||
"flag" | ||
"net" | ||
|
||
"github.com/containernetworking/cni/pkg/types" | ||
) | ||
|
||
const ( | ||
HTTP_REQUEST_TIMEOUT = 60 | ||
HTTP_POOL_CONNECTIONS = 10 | ||
) | ||
|
||
type GridConfig struct { | ||
GridHost string | ||
WapiVer string | ||
WapiPort string | ||
WapiUsername string | ||
WapiPassword string | ||
SslVerify string | ||
HttpRequestTimeout int | ||
HttpPoolConnections int | ||
HttpPoolMaxSize int | ||
} | ||
|
||
type DriverConfig struct { | ||
SocketDir string | ||
DriverName string | ||
NetworkView string | ||
NetworkContainer string | ||
PrefixLength uint | ||
} | ||
|
||
type Config struct { | ||
GridConfig | ||
DriverConfig | ||
} | ||
|
||
func LoadConfig() (config *Config) { | ||
config = new(Config) | ||
|
||
flag.StringVar(&config.GridHost, "grid-host", "192.168.124.200", "IP of Infoblox Grid Host") | ||
flag.StringVar(&config.WapiVer, "wapi-version", "2.0", "Infoblox WAPI Version.") | ||
flag.StringVar(&config.WapiPort, "wapi-port", "443", "Infoblox WAPI Port.") | ||
flag.StringVar(&config.WapiUsername, "wapi-username", "", "Infoblox WAPI Username") | ||
flag.StringVar(&config.WapiPassword, "wapi-password", "", "Infoblox WAPI Password") | ||
flag.StringVar(&config.SslVerify, "ssl-verify", "false", "Specifies whether (true/false) to verify server certificate. If a file path is specified, it is assumed to be a certificate file and will be used to verify server certificate.") | ||
flag.StringVar(&config.NetworkView, "network-view", "default", "Infoblox Network View") | ||
flag.StringVar(&config.NetworkContainer, "network-container", "172.18.0.0/16", "Subnets will be allocated from this container if subnet is not specified in IPAM config") | ||
flag.UintVar(&config.PrefixLength, "prefix-length", 24, "The default CIDR prefix length when allocating a subnet from Network Container") | ||
config.HttpRequestTimeout = HTTP_REQUEST_TIMEOUT | ||
config.HttpPoolConnections = HTTP_POOL_CONNECTIONS | ||
|
||
flag.StringVar(&config.SocketDir, "socket-dir", GetDefaultSocketDir(), "Directory where Infoblox IPAM daemon sockets are created") | ||
flag.StringVar(&config.DriverName, "driver-name", "infoblox", "Name of Infoblox IPAM driver") | ||
|
||
flag.Parse() | ||
|
||
return config | ||
} | ||
|
||
type IPAMConfig struct { | ||
Type string `json:"type"` | ||
SocketDir string `json:"socket-dir"` | ||
NetworkView string `json:"network-view"` | ||
NetworkContainer string `json:"network-container"` | ||
PrefixLength uint `json:"prefix-length"` | ||
Subnet types.IPNet `json:"subnet"` | ||
Gateway net.IP `json:"gateway"` | ||
Routes []types.Route `json:"routes"` | ||
} | ||
|
||
type NetConfig struct { | ||
Name string `json:"name"` | ||
Type string `json:"type"` | ||
Bridge string `json:"bridge"` | ||
IsGateway bool `json:"isGateway"` | ||
IPAM *IPAMConfig `json:"ipam"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
// Copyright 2016 Infoblox Inc. | ||
// All Rights Reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); you may | ||
// not use this file except in compliance with the License. You may obtain | ||
// a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
// License for the specific language governing permissions and limitations | ||
// under the License. | ||
|
||
package main | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"log" | ||
"net" | ||
"net/http" | ||
"net/rpc" | ||
"runtime" | ||
|
||
"github.com/containernetworking/cni/pkg/types" | ||
ibclient "github.com/infobloxopen/infoblox-go-client" | ||
) | ||
|
||
type Infoblox struct { | ||
Drv *InfobloxDriver | ||
} | ||
|
||
func newInfoblox(drv *InfobloxDriver) *Infoblox { | ||
return &Infoblox{ | ||
Drv: drv, | ||
} | ||
} | ||
|
||
// Allocate acquires an IP from Infoblox for a specified container. | ||
func (ib *Infoblox) Allocate(args *ExtCmdArgs, result *types.Result) (err error) { | ||
conf := NetConfig{} | ||
if err = json.Unmarshal(args.StdinData, &conf); err != nil { | ||
return fmt.Errorf("error parsing netconf: %v", err) | ||
} | ||
|
||
cidr := net.IPNet{IP: conf.IPAM.Subnet.IP, Mask: conf.IPAM.Subnet.Mask} | ||
netviewName := conf.IPAM.NetworkView | ||
if netviewName == "" { | ||
netviewName = ib.Drv.networkView | ||
} | ||
log.Printf("RequestNetwork: '%s', '%s'", netviewName, cidr.String()) | ||
netview, _ := ib.Drv.RequestNetworkView(netviewName) | ||
if netview == "" { | ||
return nil | ||
} | ||
|
||
subnet, _ := ib.Drv.RequestNetwork(conf) | ||
if subnet == "" { | ||
return nil | ||
} | ||
|
||
mac := args.IfMac | ||
|
||
log.Printf("RequestAddress: '%s', '%s', '%s'", netviewName, subnet, mac) | ||
ip, _ := ib.Drv.RequestAddress(netviewName, subnet, "", mac, args.ContainerID) | ||
|
||
ipn, _ := types.ParseCIDR(subnet) | ||
ipn.IP = net.ParseIP(ip) | ||
result.IP4 = &types.IPConfig{ | ||
IP: *ipn, | ||
Gateway: conf.IPAM.Gateway, | ||
Routes: conf.IPAM.Routes, | ||
} | ||
|
||
log.Printf("Allocate result: '%s'", result) | ||
return nil | ||
} | ||
|
||
func (ib *Infoblox) Release(args *ExtCmdArgs, reply *struct{}) error { | ||
conf := NetConfig{} | ||
log.Printf("Release: called with args '%v'", *args) | ||
if err := json.Unmarshal(args.StdinData, &conf); err != nil { | ||
return fmt.Errorf("error parsing netconf: %v", err) | ||
} | ||
|
||
ref, err := ib.Drv.ReleaseAddress(conf.IPAM.NetworkView, "", args.IfMac) | ||
log.Printf("IP Address released: '%s'", ref) | ||
|
||
return err | ||
} | ||
|
||
func getListener(driverSocket *DriverSocket) (net.Listener, error) { | ||
socketFile := driverSocket.SetupSocket() | ||
|
||
return net.Listen("unix", socketFile) | ||
} | ||
|
||
func runDaemon(config *Config) { | ||
// since other goroutines (on separate threads) will change namespaces, | ||
// ensure the RPC server does not get scheduled onto those | ||
runtime.LockOSThread() | ||
|
||
log.Printf("Config is '%v'\n", *config) | ||
|
||
conn, err := ibclient.NewConnector( | ||
config.GridHost, | ||
config.WapiVer, | ||
config.WapiPort, | ||
config.WapiUsername, | ||
config.WapiPassword, | ||
config.SslVerify, | ||
config.HttpRequestTimeout, | ||
config.HttpPoolConnections) | ||
|
||
driverSocket := NewDriverSocket(config.SocketDir, config.DriverName) | ||
l, err := getListener(driverSocket) | ||
|
||
objMgr := ibclient.NewObjectManager(conn, "Rkt", "RktEngineID") | ||
|
||
ibDrv := NewInfobloxDriver(objMgr, config.NetworkView, config.NetworkContainer, config.PrefixLength) | ||
|
||
if err != nil { | ||
log.Printf("Error getting listener: %v", err) | ||
return | ||
} | ||
|
||
ib := newInfoblox(ibDrv) | ||
rpc.Register(ib) | ||
rpc.HandleHTTP() | ||
http.Serve(l, nil) | ||
} | ||
|
||
func main() { | ||
config := LoadConfig() | ||
runDaemon(config) | ||
} |
Oops, something went wrong.