Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions pkg/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func (prov *IPAMProvider) Init(params Params) bool {
for ipamLabel := range labelMap {
if _, ok := ipRangeMap[ipamLabel]; !ok {
// Remove all those labels from that are not present in the new ipRangeMap
prov.store.CleanUpLabel(ipamLabel)
prov.store.CleanUpLabel(ipamLabel, "")
}
}

Expand All @@ -81,8 +81,12 @@ func (prov *IPAMProvider) Init(params Params) bool {
prov.ipamLabels[ipamLabel] = true
continue
}
if !strings.Contains(ipRange, rng) {
log.Warningf("[PROV] Only appending to existing IP ranges is supported. Label: %s, Existing Range: %s, New Range: %s", ipamLabel, rng, ipRange)
continue
}
// Exists and range changed, so remove range and add new range
prov.store.CleanUpLabel(ipamLabel)
prov.store.CleanUpLabel(ipamLabel, ipRange)
}

var ips []string
Expand Down
2 changes: 1 addition & 1 deletion pkg/provider/sqlite/mock/mockstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,6 @@ func (ms *MockDBStore) RemoveLabel(label string) bool {
return true
}

func (ms *MockDBStore) CleanUpLabel(label string) {
func (ms *MockDBStore) CleanUpLabel(label string, ipRange string) {
ms.Data.CleanUpFlag = true
}
110 changes: 89 additions & 21 deletions pkg/provider/sqlite/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ package sqlite
import (
"database/sql"
"fmt"
"github.com/F5Networks/f5-ipam-controller/pkg/utils"
"os"

"github.com/F5Networks/f5-ipam-controller/pkg/utils"

log "github.com/F5Networks/f5-ipam-controller/pkg/vlogger"
_ "github.com/mattn/go-sqlite3"
)
Expand Down Expand Up @@ -55,7 +56,7 @@ type StoreProvider interface {
GetLabelMap() map[string]string
AddLabel(label, ipRange string) bool
RemoveLabel(label string) bool
CleanUpLabel(label string)
CleanUpLabel(label string, ipRange string)
}

func fileExists(name string) bool {
Expand Down Expand Up @@ -162,7 +163,25 @@ func (store *DBStore) CreateTables() bool {

func (store *DBStore) InsertIPs(ips []string, ipamLabel string) {
for _, ip := range ips {
err := store.executeStatement(
if utils.IsIPV4Addr(ip) {
ip = utils.Ipv4ToPaddedString(ip)
}
var exists int

queryString := fmt.Sprintf(
"SELECT COUNT(ipaddress) FROM ipaddress_range where ipaddress=\"%s\" AND ipam_label=\"%s\"",
ip,
ipamLabel,
)
err := store.db.QueryRow(queryString).Scan(&exists)
if err == sql.ErrNoRows || exists == 1 {
log.Debugf("[STORE] IP Address %s already allocated, skipping insert", ip)
continue
} else if err != nil {
log.Errorf("[STORE] Unable to query Table 'ipaddress_range': %v", err)
continue
}
err = store.executeStatement(
`INSERT INTO ipaddress_range(ipaddress, status, ipam_label, reference) VALUES (?, ?, ?, ?)`,
ip, AVAILABLE, ipamLabel, utils.RandomString(ReferenceLength))
if err != nil {
Expand All @@ -174,12 +193,12 @@ func (store *DBStore) InsertIPs(ips []string, ipamLabel string) {
func (store *DBStore) DisplayIPRecords() {

row, err := store.db.Query("SELECT * FROM ipaddress_range")
if err != nil {
log.Debugf("%v ", err)
if err != nil && err != sql.ErrNoRows {
log.Errorf("%v", err)
}
columns, err := row.Columns()
if err != nil {
log.Debugf(" err : %v", err)
log.Errorf("err : %v", err)
}
log.Debugf("[STORE] %v", columns)
defer row.Close()
Expand All @@ -189,6 +208,7 @@ func (store *DBStore) DisplayIPRecords() {
var ipamLabel string
var ref string
row.Scan(&ipaddress, &status, &ipamLabel, &ref)
ipaddress = utils.PaddedStringToIPV4(ipaddress)
log.Debugf("[STORE] %v %v %v %v", ipaddress, status, ipamLabel, ref)
}
}
Expand All @@ -215,6 +235,7 @@ func (store *DBStore) AllocateIP(ipamLabel, reference string) string {
if err != nil {
log.Errorf("[STORE] Unable to update row in Table 'ipaddress_range': %v", err)
}
ipaddress = utils.PaddedStringToIPV4(ipaddress)
return ipaddress
}

Expand Down Expand Up @@ -242,6 +263,7 @@ func (store *DBStore) GetIPAddressFromARecord(ipamLabel, hostname string) string
} else if status == AVAILABLE {
return ""
}
ipaddress = utils.PaddedStringToIPV4(ipaddress)

return ipaddress
}
Expand All @@ -264,11 +286,15 @@ func (store *DBStore) GetIPAddressFromReference(ipamLabel, reference string) str
if status == AVAILABLE {
return ""
}
ipaddress = utils.PaddedStringToIPV4(ipaddress)

return ipaddress
}

func (store *DBStore) ReleaseIP(ip string) {
if utils.IsIPV4Addr(ip) {
ip = utils.Ipv4ToPaddedString(ip)
}
deallocateIPSql := fmt.Sprintf("UPDATE ipaddress_range set status=%d, reference=\"%s\" where ipaddress=?",
AVAILABLE,
utils.RandomString(ReferenceLength),
Expand All @@ -281,6 +307,10 @@ func (store *DBStore) ReleaseIP(ip string) {
}

func (store *DBStore) CreateARecord(hostname, ipAddr string) bool {
if utils.IsIPV4Addr(ipAddr) {
ipAddr = utils.Ipv4ToPaddedString(ipAddr)
}

insertARecordSQL := `INSERT INTO a_records(ipaddress, hostname) VALUES (?, ?)`

err := store.executeStatement(insertARecordSQL, ipAddr, hostname)
Expand All @@ -292,6 +322,9 @@ func (store *DBStore) CreateARecord(hostname, ipAddr string) bool {
}

func (store *DBStore) DeleteARecord(hostname, ipAddr string) bool {
if utils.IsIPV4Addr(ipAddr) {
ipAddr = utils.Ipv4ToPaddedString(ipAddr)
}
deleteARecord := "DELETE FROM a_records WHERE ipaddress=? AND hostname=?"

err := store.executeStatement(deleteARecord, ipAddr, hostname)
Expand Down Expand Up @@ -320,15 +353,37 @@ func (store *DBStore) GetLabelMap() map[string]string {
}

func (store *DBStore) AddLabel(label, ipRange string) bool {
err := store.executeStatement(
`INSERT INTO label_map(ipam_label, range) VALUES (?, ?)`,
queryString := fmt.Sprintf(
"SELECT range FROM label_map where ipam_label=\"%s\"",
label,
ipRange,
)
if err != nil {
log.Errorf("[STORE] Unable to Insert row in Table 'label_map': %v", err)
var existingRange string
err := store.db.QueryRow(queryString).Scan(&existingRange)
if err != nil && err != sql.ErrNoRows {
log.Errorf("[STORE] Unable to fetch label %s with error %v", label, err)
return false
}
if existingRange != ipRange {
err := store.executeStatement(
`UPDATE label_map set range=? where ipam_label=?`,
ipRange,
label,
)
if err != nil {
log.Errorf("[STORE] Unable to Update ip range for label %s in Table 'label_map': %v", label, err)
return false
}
} else {
err := store.executeStatement(
`INSERT INTO label_map(ipam_label, range) VALUES (?, ?)`,
label,
ipRange,
)
if err != nil {
log.Errorf("[STORE] Unable to Insert row in Table 'label_map': %v", err)
return false
}
}
return true
}

Expand All @@ -346,10 +401,17 @@ func (store *DBStore) RemoveLabel(label string) bool {

// CleanUpLabel performs DELETE CASCADE of associated rows in all tables
// TODO: Should be replaced by standard DB cascade deletion
func (store *DBStore) CleanUpLabel(label string) {
row, err := store.db.Query(fmt.Sprintf("SELECT ipaddress FROM ipaddress_range WHERE ipam_label = \"%s\"", label))
func (store *DBStore) CleanUpLabel(label string, ipRange string) {
var queryString string

if ipRange == "" {
queryString = fmt.Sprintf("SELECT ipaddress FROM ipaddress_range WHERE ipam_label = \"%s\"", label)
} else {
queryString = fmt.Sprintf("SELECT ipaddress FROM ipaddress_range WHERE ipam_label = \"%s\" AND status = %d", label, AVAILABLE)
}
row, err := store.db.Query(queryString)
if err != nil {
log.Debugf("%v", err)
log.Debugf("[STORE] %v", err)
}

defer row.Close()
Expand All @@ -365,11 +427,17 @@ func (store *DBStore) CleanUpLabel(label string) {
ipAddr,
)
}

_ = store.executeStatement(
"DELETE FROM ipaddress_range WHERE ipam_label=?",
label,
)

_ = store.RemoveLabel(label)
if ipRange == "" {
_ = store.executeStatement(
"DELETE FROM ipaddress_range WHERE ipam_label=?",
label,
)
_ = store.RemoveLabel(label)
} else {
_ = store.executeStatement(
"DELETE FROM ipaddress_range WHERE ipam_label=? AND status=?",
label,
AVAILABLE,
)
}
}
16 changes: 15 additions & 1 deletion pkg/utils/utils.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package utils

import (
"github.com/google/uuid"
"fmt"
"net"
"strings"

"github.com/google/uuid"
)

func IsIPV4Addr(ipAddr string) bool {
Expand Down Expand Up @@ -50,3 +52,15 @@ func RandomString(len int) string {
return ""
}
}
func Ipv4ToPaddedString(ip string) string {
splitIp := strings.Split(ip, ".")
return fmt.Sprintf("%03s.%03s.%03s.%03s", splitIp[0], splitIp[1], splitIp[2], splitIp[3])
}
func PaddedStringToIPV4(paddedIp string) string {
splitIp := strings.Split(paddedIp, ".")
if len(splitIp) == 4 {
return fmt.Sprintf("%s.%s.%s.%s", strings.TrimLeft(splitIp[0], "0"), strings.TrimLeft(splitIp[1], "0"), strings.TrimLeft(splitIp[2], "0"), strings.TrimLeft(splitIp[3], "0"))
} else {
return paddedIp
}
}