Skip to content

Commit

Permalink
Feature: Cisco config generator
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanKuchin committed Dec 30, 2023
1 parent e58ed9c commit 49d3f60
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 9 deletions.
17 changes: 12 additions & 5 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,26 @@
"args": [
"${workspaceFolder}/cmd/phpipamsync/"
],
"options": {
"env": {
"GOOS": "windows",
"GOARCH": "amd64"
},
"cwd": "${workspaceFolder}"
},
"problemMatcher": [
"$go"
],
"group": "build",
// "detail": "cd e:\\docs\\src\\go\\sdwanctl; go build ${workspaceFolder}"
"group": "build"
},
{
"type": "go",
"label": "go: build package for linux",
"command": "build",
"args": [
"-o", "cmd/phpipamsync", "${workspaceFolder}/cmd/phpipamsync/"
"-o",
"cmd/phpipamsync",
"${workspaceFolder}/cmd/phpipamsync/"
],
"problemMatcher": [
"$go"
Expand All @@ -30,8 +38,7 @@
"GOARCH": "amd64"
}
},
"group": "build",
// "detail": "cd e:\\docs\\src\\go\\sdwanctl; go build -o cmd/sdwanctl-linux ${workspaceFolder}"
"group": "build"
},
]
}
101 changes: 97 additions & 4 deletions internal/cli/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import (
"encoding/json"
"fmt"
"log"
"net"
"net/netip"
"os"
"strconv"
"strings"

"github.com/ivankuchin/phpipamsync/internal/api_client"
"github.com/ivankuchin/phpipamsync/internal/config_reader"
Expand Down Expand Up @@ -87,6 +90,91 @@ func writeToPiHoleCustom(addresses string, cfg *config_reader.Config) error {
return nil
}

func getSubnetMaskBySubnetID(subnetID string) (string, error) {
mask := ""

prefix, err := netip.ParsePrefix(subnetID)
if err != nil {
log.Printf("Error parsing subnet ID: %s", err.Error())
return mask, err
}

bits := prefix.Bits()
mask = net.IP(net.CIDRMask(bits, 32)).String()

return mask, nil
}

func getGWIPBySubnetID(subnetID string) (string, error) {
ip_addr := ""

prefix, err := netip.ParsePrefix(subnetID)
if err != nil {
log.Printf("Error parsing subnet ID: %s", err.Error())
return ip_addr, err
}

ip_addr = prefix.Addr().Next().String()

return ip_addr, nil
}

func convertMacToClientIdentifier(mac string) string {
cleaned_mac := strings.ReplaceAll(mac, ":", "")
client_identifier := ""

for i := 0; i < len(cleaned_mac); i++ {
if (i-2)%4 == 0 {
client_identifier += "."
}
client_identifier += string(cleaned_mac[i])
}

return "01" + client_identifier
}

func getCiscoDHCPOutput(addresses IPAddresses, cfg *config_reader.Config) (string, error) {
output := ""

mask, err := getSubnetMaskBySubnetID(cfg.Ipam_subnet)
if err != nil {
return output, err
}

gw, err := getGWIPBySubnetID(cfg.Ipam_subnet)
if err != nil {
return output, err
}

for _, address := range addresses.IPAddresses {
switch address.Tag {
case "2": // In Use
if address.Hostname == "" {
log.Printf("WARNING: Skipping %s because hostname is empty", address.IP)
} else if address.IP == "" {
log.Printf("WARNING: Skipping %s because IP is empty", address.Hostname)
} else {
output += "ip dhcp pool " + address.Hostname + "\n"
output += " host " + address.IP + " " + mask + "\n"
switch {
case address.ClientIdentifier != "":
output += " client-identifier " + address.ClientIdentifier + "\n"
case address.Mac != "":
output += " client-identifier " + convertMacToClientIdentifier(address.Mac) + "\n"
}
output += " default-router " + gw + "\n"
output += "!\n"
}
case "3": // Reserved
case "4": // DHCP pool
default:
log.Printf("WARNING: Skipping %s because tag is %s", address.IP, address.Tag)
}
}

return output, nil
}

var getCmd = &cobra.Command{
Use: "get",
Short: "Get information from phpIPAM",
Expand All @@ -99,24 +187,29 @@ var getCiscoDHCP = &cobra.Command{
Long: "Get DHCP config for Cisco IOS devices",
RunE: func(cmd *cobra.Command, args []string) error {

auth := new(api_client.AuthAppCode)
auth := api_client.AuthAppCode{}
err := auth.Login(config_reader.Cfg)
if err != nil {
return err
}
defer auth.Logout()

subnet_id, err := getSubnetID(auth, config_reader.Cfg)
subnet_id, err := getSubnetID(&auth, config_reader.Cfg)
if err != nil {
return err
}

addresses, err := getIPAddressesBySubnetID(subnet_id, auth, config_reader.Cfg)
addresses, err := getIPAddressesBySubnetID(subnet_id, &auth, config_reader.Cfg)
if err != nil {
return err
}

output, err := getCiscoDHCPOutput(addresses, config_reader.Cfg)
if err != nil {
return err
}

fmt.Println(addresses)
fmt.Println(output)

return nil
},
Expand Down
1 change: 1 addition & 0 deletions internal/cli/get_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ type IPAddress struct {
FirewallAddressObject string `json:"firewallAddressObject"`
EditDate string `json:"editDate"`
CustomerID string `json:"customer_id"`
ClientIdentifier string `json:"custom_ClientID"`
}

0 comments on commit 49d3f60

Please sign in to comment.