From 50fba1e0dd19db95bab636fd77b1f5e31162ccb1 Mon Sep 17 00:00:00 2001 From: pavel-z1 Date: Tue, 10 Mar 2020 13:18:33 +0200 Subject: [PATCH 01/28] Added Dynamic IP creation by using API method /addresses/first_free/{subnetId}/ --- controllers/addresses/addresses.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/controllers/addresses/addresses.go b/controllers/addresses/addresses.go index 0a32b95..1dd566c 100644 --- a/controllers/addresses/addresses.go +++ b/controllers/addresses/addresses.go @@ -91,6 +91,12 @@ func (c *Controller) CreateAddress(in Address) (message string, err error) { return } +// CreateAddress creates a first free in subnet address by sending a POST request. +func (c *Controller) CreateFirstFreeAddress(id int, in Address) (out string, err error) { + err = c.SendRequest("POST", fmt.Sprintf("/addresses/first_free/%d", id), &in, &out) + return +} + // GetAddressByID GETs an address via its ID. func (c *Controller) GetAddressByID(id int) (out Address, err error) { err = c.SendRequest("GET", fmt.Sprintf("/addresses/%d/", id), &struct{}{}, &out) From 7edd36de1f031bbe8f4a3a074ceb9f5d3e616d4a Mon Sep 17 00:00:00 2001 From: pavel-z1 Date: Wed, 11 Mar 2020 16:28:24 +0200 Subject: [PATCH 02/28] Added gateway parameters to the subnet control --- controllers/addresses/addresses.go | 1 + controllers/subnets/subnets.go | 6 ++++++ phpipam/request/request.go | 3 +++ 3 files changed, 10 insertions(+) diff --git a/controllers/addresses/addresses.go b/controllers/addresses/addresses.go index 1dd566c..dcbff8f 100644 --- a/controllers/addresses/addresses.go +++ b/controllers/addresses/addresses.go @@ -4,6 +4,7 @@ package addresses import ( "fmt" + "log" "github.com/paybyphone/phpipam-sdk-go/phpipam" "github.com/paybyphone/phpipam-sdk-go/phpipam/client" diff --git a/controllers/subnets/subnets.go b/controllers/subnets/subnets.go index 0a5840a..9605dcb 100644 --- a/controllers/subnets/subnets.go +++ b/controllers/subnets/subnets.go @@ -84,6 +84,12 @@ type Subnet struct { // The date of the last edit to this resource. EditDate string `json:"editDate,omitempty"` + // Gateway IP and ID of Gateway IP + Gateway map[string]interface{} `json:"gateway,omitempty"` + + // Gateway IP ID + GatewayID string `json:"gatewayId,omitempty"` + // A map[string]interface{} of custom fields to set on the resource. Note // that this functionality requires PHPIPAM 1.3 or higher with the "Nest // custom fields" flag set on the specific API integration. If this is not diff --git a/phpipam/request/request.go b/phpipam/request/request.go index d8f47dd..4da25b4 100644 --- a/phpipam/request/request.go +++ b/phpipam/request/request.go @@ -7,6 +7,7 @@ import ( "fmt" "io/ioutil" "net/http" + "log" "github.com/paybyphone/phpipam-sdk-go/phpipam/session" ) @@ -114,6 +115,7 @@ func newRequestResponse(r *http.Response) *requestResponse { } defer r.Body.Close() body, err := ioutil.ReadAll(r.Body) + log.Printf("Response Body Debug ................... %s", body) if err != nil { panic(err) } @@ -138,6 +140,7 @@ func (r *Request) Send() error { switch r.Method { case "OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE": bs, err := json.Marshal(r.Input) + log.Printf("Request Body Debug ................... %s", bs) if err != nil { return fmt.Errorf("Error preparing request data: %s", err) } From d784cb582cb0abb8d037ea8912388d4241f33f1e Mon Sep 17 00:00:00 2001 From: pavel-z1 Date: Wed, 11 Mar 2020 16:37:11 +0200 Subject: [PATCH 03/28] Removed not used log module --- controllers/addresses/addresses.go | 1 - 1 file changed, 1 deletion(-) diff --git a/controllers/addresses/addresses.go b/controllers/addresses/addresses.go index dcbff8f..1dd566c 100644 --- a/controllers/addresses/addresses.go +++ b/controllers/addresses/addresses.go @@ -4,7 +4,6 @@ package addresses import ( "fmt" - "log" "github.com/paybyphone/phpipam-sdk-go/phpipam" "github.com/paybyphone/phpipam-sdk-go/phpipam/client" From 1c4e7618bf219c225ba74a0494f8de729cc8f4c5 Mon Sep 17 00:00:00 2001 From: pavel-z1 Date: Wed, 11 Mar 2020 16:44:39 +0200 Subject: [PATCH 04/28] Replaced links from github.com/paybyphone/phpipam-sdk-go to the github.com/pavel-z1/phpipam-sdk-go --- README.md | 4 ++-- controllers/addresses/addresses.go | 6 +++--- controllers/addresses/addresses_test.go | 6 +++--- controllers/sections/sections.go | 8 ++++---- controllers/sections/sections_test.go | 8 ++++---- controllers/subnets/subnets.go | 8 ++++---- controllers/subnets/subnets_test.go | 8 ++++---- controllers/vlans/vlans.go | 6 +++--- controllers/vlans/vlans_test.go | 6 +++--- phpipam/client/client.go | 6 +++--- phpipam/client/client_test.go | 4 ++-- phpipam/request/request.go | 2 +- phpipam/request/request_test.go | 4 ++-- phpipam/session/session.go | 2 +- phpipam/session/session_test.go | 2 +- sdk.go | 2 +- vendor/vendor.json | 2 +- 17 files changed, 42 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index a4b571a..4d8344b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![GoDoc](https://godoc.org/github.com/paybyphone/phpipam-sdk-go?status.svg)](https://godoc.org/github.com/paybyphone/phpipam-sdk-go) +[![GoDoc](https://godoc.org/github.com/pavel-z1/phpipam-sdk-go?status.svg)](https://godoc.org/github.com/pavel-z1/phpipam-sdk-go) # phpipam-sdk-go - Partial SDK for PHPIPAM @@ -15,7 +15,7 @@ provider to help insert data gathered from AWS and beyond. See the [GoDoc][2] for the SDK usage details. -[2]: https://godoc.org/github.com/paybyphone/phpipam-sdk-go +[2]: https://godoc.org/github.com/pavel-z1/phpipam-sdk-go ## A Note on Custom Fields diff --git a/controllers/addresses/addresses.go b/controllers/addresses/addresses.go index 1dd566c..8f6373b 100644 --- a/controllers/addresses/addresses.go +++ b/controllers/addresses/addresses.go @@ -5,9 +5,9 @@ package addresses import ( "fmt" - "github.com/paybyphone/phpipam-sdk-go/phpipam" - "github.com/paybyphone/phpipam-sdk-go/phpipam/client" - "github.com/paybyphone/phpipam-sdk-go/phpipam/session" + "github.com/pavel-z1/phpipam-sdk-go/phpipam" + "github.com/pavel-z1/phpipam-sdk-go/phpipam/client" + "github.com/pavel-z1/phpipam-sdk-go/phpipam/session" ) // Address represents an IP address resource within PHPIPAM. diff --git a/controllers/addresses/addresses_test.go b/controllers/addresses/addresses_test.go index a92f1f0..6189f0a 100644 --- a/controllers/addresses/addresses_test.go +++ b/controllers/addresses/addresses_test.go @@ -8,9 +8,9 @@ import ( "reflect" "testing" - "github.com/paybyphone/phpipam-sdk-go/phpipam" - "github.com/paybyphone/phpipam-sdk-go/phpipam/session" - "github.com/paybyphone/phpipam-sdk-go/testacc" + "github.com/pavel-z1/phpipam-sdk-go/phpipam" + "github.com/pavel-z1/phpipam-sdk-go/phpipam/session" + "github.com/pavel-z1/phpipam-sdk-go/testacc" ) var testCreateAddressInput = Address{ diff --git a/controllers/sections/sections.go b/controllers/sections/sections.go index 775f680..7921693 100644 --- a/controllers/sections/sections.go +++ b/controllers/sections/sections.go @@ -5,10 +5,10 @@ package sections import ( "fmt" - "github.com/paybyphone/phpipam-sdk-go/controllers/subnets" - "github.com/paybyphone/phpipam-sdk-go/phpipam" - "github.com/paybyphone/phpipam-sdk-go/phpipam/client" - "github.com/paybyphone/phpipam-sdk-go/phpipam/session" + "github.com/pavel-z1/phpipam-sdk-go/controllers/subnets" + "github.com/pavel-z1/phpipam-sdk-go/phpipam" + "github.com/pavel-z1/phpipam-sdk-go/phpipam/client" + "github.com/pavel-z1/phpipam-sdk-go/phpipam/session" ) // Section represents a PHPIPAM section. diff --git a/controllers/sections/sections_test.go b/controllers/sections/sections_test.go index f8d19b5..f1f3efa 100644 --- a/controllers/sections/sections_test.go +++ b/controllers/sections/sections_test.go @@ -9,10 +9,10 @@ import ( "testing" "github.com/davecgh/go-spew/spew" - "github.com/paybyphone/phpipam-sdk-go/controllers/subnets" - "github.com/paybyphone/phpipam-sdk-go/phpipam" - "github.com/paybyphone/phpipam-sdk-go/phpipam/session" - "github.com/paybyphone/phpipam-sdk-go/testacc" + "github.com/pavel-z1/phpipam-sdk-go/controllers/subnets" + "github.com/pavel-z1/phpipam-sdk-go/phpipam" + "github.com/pavel-z1/phpipam-sdk-go/phpipam/session" + "github.com/pavel-z1/phpipam-sdk-go/testacc" ) var testListSectionsOutputExpected = []Section{ diff --git a/controllers/subnets/subnets.go b/controllers/subnets/subnets.go index 9605dcb..b2acb3d 100644 --- a/controllers/subnets/subnets.go +++ b/controllers/subnets/subnets.go @@ -5,10 +5,10 @@ package subnets import ( "fmt" - "github.com/paybyphone/phpipam-sdk-go/controllers/addresses" - "github.com/paybyphone/phpipam-sdk-go/phpipam" - "github.com/paybyphone/phpipam-sdk-go/phpipam/client" - "github.com/paybyphone/phpipam-sdk-go/phpipam/session" + "github.com/pavel-z1/phpipam-sdk-go/controllers/addresses" + "github.com/pavel-z1/phpipam-sdk-go/phpipam" + "github.com/pavel-z1/phpipam-sdk-go/phpipam/client" + "github.com/pavel-z1/phpipam-sdk-go/phpipam/session" ) // Subnet represents a PHPIPAM subnet. diff --git a/controllers/subnets/subnets_test.go b/controllers/subnets/subnets_test.go index 16d5540..d58f20e 100644 --- a/controllers/subnets/subnets_test.go +++ b/controllers/subnets/subnets_test.go @@ -9,10 +9,10 @@ import ( "reflect" "testing" - "github.com/paybyphone/phpipam-sdk-go/controllers/addresses" - "github.com/paybyphone/phpipam-sdk-go/phpipam" - "github.com/paybyphone/phpipam-sdk-go/phpipam/session" - "github.com/paybyphone/phpipam-sdk-go/testacc" + "github.com/pavel-z1/phpipam-sdk-go/controllers/addresses" + "github.com/pavel-z1/phpipam-sdk-go/phpipam" + "github.com/pavel-z1/phpipam-sdk-go/phpipam/session" + "github.com/pavel-z1/phpipam-sdk-go/testacc" ) var testCreateSubnetInput = Subnet{ diff --git a/controllers/vlans/vlans.go b/controllers/vlans/vlans.go index 09de919..a7e99e4 100644 --- a/controllers/vlans/vlans.go +++ b/controllers/vlans/vlans.go @@ -5,9 +5,9 @@ package vlans import ( "fmt" - "github.com/paybyphone/phpipam-sdk-go/phpipam" - "github.com/paybyphone/phpipam-sdk-go/phpipam/client" - "github.com/paybyphone/phpipam-sdk-go/phpipam/session" + "github.com/pavel-z1/phpipam-sdk-go/phpipam" + "github.com/pavel-z1/phpipam-sdk-go/phpipam/client" + "github.com/pavel-z1/phpipam-sdk-go/phpipam/session" ) // VLAN represents a PHPIPAM VLAN. diff --git a/controllers/vlans/vlans_test.go b/controllers/vlans/vlans_test.go index dc998ed..433b995 100644 --- a/controllers/vlans/vlans_test.go +++ b/controllers/vlans/vlans_test.go @@ -8,9 +8,9 @@ import ( "reflect" "testing" - "github.com/paybyphone/phpipam-sdk-go/phpipam" - "github.com/paybyphone/phpipam-sdk-go/phpipam/session" - "github.com/paybyphone/phpipam-sdk-go/testacc" + "github.com/pavel-z1/phpipam-sdk-go/phpipam" + "github.com/pavel-z1/phpipam-sdk-go/phpipam/session" + "github.com/pavel-z1/phpipam-sdk-go/testacc" ) var testCreateVLANInput = VLAN{ diff --git a/phpipam/client/client.go b/phpipam/client/client.go index b8fd830..d8e6db9 100644 --- a/phpipam/client/client.go +++ b/phpipam/client/client.go @@ -5,9 +5,9 @@ package client import ( "fmt" - "github.com/paybyphone/phpipam-sdk-go/phpipam" - "github.com/paybyphone/phpipam-sdk-go/phpipam/request" - "github.com/paybyphone/phpipam-sdk-go/phpipam/session" + "github.com/pavel-z1/phpipam-sdk-go/phpipam" + "github.com/pavel-z1/phpipam-sdk-go/phpipam/request" + "github.com/pavel-z1/phpipam-sdk-go/phpipam/session" ) // Client encompasses a generic client object that is further extended by diff --git a/phpipam/client/client_test.go b/phpipam/client/client_test.go index 03f2ae8..89e7495 100644 --- a/phpipam/client/client_test.go +++ b/phpipam/client/client_test.go @@ -8,8 +8,8 @@ import ( "reflect" "testing" - "github.com/paybyphone/phpipam-sdk-go/phpipam" - "github.com/paybyphone/phpipam-sdk-go/phpipam/session" + "github.com/pavel-z1/phpipam-sdk-go/phpipam" + "github.com/pavel-z1/phpipam-sdk-go/phpipam/session" ) const testDateStamp = "2999-12-31 23:59:59" diff --git a/phpipam/request/request.go b/phpipam/request/request.go index 4da25b4..26343bd 100644 --- a/phpipam/request/request.go +++ b/phpipam/request/request.go @@ -9,7 +9,7 @@ import ( "net/http" "log" - "github.com/paybyphone/phpipam-sdk-go/phpipam/session" + "github.com/pavel-z1/phpipam-sdk-go/phpipam/session" ) // APIResponse represents a PHPIPAM response body. Both successful and diff --git a/phpipam/request/request_test.go b/phpipam/request/request_test.go index 2a7e80e..7f92ada 100644 --- a/phpipam/request/request_test.go +++ b/phpipam/request/request_test.go @@ -9,8 +9,8 @@ import ( "strings" "testing" - "github.com/paybyphone/phpipam-sdk-go/phpipam" - "github.com/paybyphone/phpipam-sdk-go/phpipam/session" + "github.com/pavel-z1/phpipam-sdk-go/phpipam" + "github.com/pavel-z1/phpipam-sdk-go/phpipam/session" ) const errorResponseText = ` diff --git a/phpipam/session/session.go b/phpipam/session/session.go index 9329683..69daf2e 100644 --- a/phpipam/session/session.go +++ b/phpipam/session/session.go @@ -3,7 +3,7 @@ package session import ( "github.com/imdario/mergo" - "github.com/paybyphone/phpipam-sdk-go/phpipam" + "github.com/pavel-z1/phpipam-sdk-go/phpipam" ) // timeLayout represents the datetime format returned by the PHPIPAM api. diff --git a/phpipam/session/session_test.go b/phpipam/session/session_test.go index b1f81ab..7d1cfc5 100644 --- a/phpipam/session/session_test.go +++ b/phpipam/session/session_test.go @@ -4,7 +4,7 @@ import ( "reflect" "testing" - "github.com/paybyphone/phpipam-sdk-go/phpipam" + "github.com/pavel-z1/phpipam-sdk-go/phpipam" ) func phpipamConfig() phpipam.Config { diff --git a/sdk.go b/sdk.go index be5009c..e339fd2 100644 --- a/sdk.go +++ b/sdk.go @@ -6,5 +6,5 @@ // Terraform provider to help insert data gathered from AWS and beyond. // // For SDK usage, see the GoDoc at -// https://godoc.org/github.com/paybyphone/phpipam-sdk-go. +// https://godoc.org/github.com/pavel-z1/phpipam-sdk-go. package sdk diff --git a/vendor/vendor.json b/vendor/vendor.json index 91b13c7..ceee059 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -9,5 +9,5 @@ "revisionTime": "2016-05-17T06:44:35Z" } ], - "rootPath": "github.com/paybyphone/phpipam-sdk-go" + "rootPath": "github.com/pavel-z1/phpipam-sdk-go" } From 4fa2cd9fddf7ed76d83af2f13e9ad0ba5f11cffb Mon Sep 17 00:00:00 2001 From: pavel-z1 <53462452+pavel-z1@users.noreply.github.com> Date: Wed, 11 Mar 2020 23:17:32 +0200 Subject: [PATCH 05/28] Set theme jekyll-theme-leap-day --- _config.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 _config.yml diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..b849713 --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-leap-day \ No newline at end of file From a1ff3ad17e47f3892a955b5191d9bdceb7875263 Mon Sep 17 00:00:00 2001 From: pavel-z1 Date: Fri, 13 Mar 2020 08:06:39 +0100 Subject: [PATCH 06/28] Added debug of Request URL --- go.mod | 1 + phpipam/request/request.go | 1 + 2 files changed, 2 insertions(+) create mode 100644 go.mod diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..a3e9b3c --- /dev/null +++ b/go.mod @@ -0,0 +1 @@ +module github.com/pavel-z1/phpipam-sdk-go diff --git a/phpipam/request/request.go b/phpipam/request/request.go index 26343bd..9c985e0 100644 --- a/phpipam/request/request.go +++ b/phpipam/request/request.go @@ -145,6 +145,7 @@ func (r *Request) Send() error { return fmt.Errorf("Error preparing request data: %s", err) } buf := bytes.NewBuffer(bs) + log.Printf("Request URL Debug ...................Method: %s, UR: %s/%s%s", r.Method, r.Session.Config.Endpoint, r.Session.Config.AppID, r.URI) req, err = http.NewRequest(r.Method, fmt.Sprintf("%s/%s%s", r.Session.Config.Endpoint, r.Session.Config.AppID, r.URI), buf) req.Header.Add("Content-Type", "application/json") default: From d0ff3300814c6a264161e5555c0554fd3247c270 Mon Sep 17 00:00:00 2001 From: pavel-z1 Date: Fri, 13 Mar 2020 09:42:22 +0100 Subject: [PATCH 07/28] Added fix for /api/myapp/addresses/first_free/id/ url --- controllers/addresses/addresses.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/addresses/addresses.go b/controllers/addresses/addresses.go index 8f6373b..f5e7df7 100644 --- a/controllers/addresses/addresses.go +++ b/controllers/addresses/addresses.go @@ -93,7 +93,7 @@ func (c *Controller) CreateAddress(in Address) (message string, err error) { // CreateAddress creates a first free in subnet address by sending a POST request. func (c *Controller) CreateFirstFreeAddress(id int, in Address) (out string, err error) { - err = c.SendRequest("POST", fmt.Sprintf("/addresses/first_free/%d", id), &in, &out) + err = c.SendRequest("POST", fmt.Sprintf("/addresses/first_free/%d/", id), &in, &out) return } From 90f3b2a7cdc84f0aa71448cf911e665d2c50a302 Mon Sep 17 00:00:00 2001 From: Jos van Bakel Date: Tue, 24 Mar 2020 19:15:34 +0100 Subject: [PATCH 08/28] Missing custom fields is not an error --- phpipam/client/client.go | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/phpipam/client/client.go b/phpipam/client/client.go index d8e6db9..48aed9c 100644 --- a/phpipam/client/client.go +++ b/phpipam/client/client.go @@ -99,8 +99,12 @@ func (c *Client) GetCustomFieldsSchema(controller string) (out map[string]phpipa func (c *Client) GetCustomFields(id int, controller string) (out map[string]interface{}, err error) { var schema map[string]phpipam.CustomField schema, err = c.GetCustomFieldsSchema(controller) - if err != nil { - return + switch { + case err.Error() == "Error from API (200): No custom fields defined": + err = nil + return + case err != nil: + return } out, err = c.getCustomFieldsRequest(id, controller, schema) @@ -143,8 +147,13 @@ func (c *Client) getCustomFieldsRequest(id int, controller string, schema map[st func (c *Client) UpdateCustomFields(id int, in map[string]interface{}, controller string) (message string, err error) { var schema map[string]phpipam.CustomField schema, err = c.GetCustomFieldsSchema(controller) - if err != nil { - return + switch { + // Ignore this error if the caller is not setting any fields. + case len(in) == 0 && err.Error() == "Error from API (200): No custom fields defined": + err = nil + return + case err != nil: + return } message, err = c.updateCustomFieldsRequest(id, in, controller, schema) return From f6826881bb37b6ae2970cdab252169018daaae4b Mon Sep 17 00:00:00 2001 From: pavel-z1 Date: Sat, 16 May 2020 10:44:44 +0300 Subject: [PATCH 09/28] Added support of HTTPS Insecure connections (without ssl issuer validation). --- go.mod | 4 ++++ phpipam/phpipam.go | 3 +++ phpipam/request/request.go | 7 ++++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index a3e9b3c..29d2c1b 100644 --- a/go.mod +++ b/go.mod @@ -1 +1,5 @@ module github.com/pavel-z1/phpipam-sdk-go + +require github.com/imdario/mergo v0.0.0-20160517064435-50d4dbd4eb0e + +go 1.13 diff --git a/phpipam/phpipam.go b/phpipam/phpipam.go index 4f6e25c..2d9e60d 100644 --- a/phpipam/phpipam.go +++ b/phpipam/phpipam.go @@ -44,6 +44,9 @@ type Config struct { // The user name for the PHPIPAM account. Username string + + // Allow HTTPS connection without verification issuer + Insecure bool } // DefaultConfigProvider supplies a default configuration: diff --git a/phpipam/request/request.go b/phpipam/request/request.go index 9c985e0..3ca88c8 100644 --- a/phpipam/request/request.go +++ b/phpipam/request/request.go @@ -3,11 +3,12 @@ package request import ( "bytes" + "crypto/tls" "encoding/json" "fmt" "io/ioutil" - "net/http" "log" + "net/http" "github.com/pavel-z1/phpipam-sdk-go/phpipam/session" ) @@ -131,7 +132,11 @@ func newRequestResponse(r *http.Response) *requestResponse { func (r *Request) Send() error { var req *http.Request var err error + tr := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: r.Session.Config.Insecure}, + } client := &http.Client{ + Transport: tr, CheckRedirect: func(req *http.Request, via []*http.Request) error { return http.ErrUseLastResponse }, From 190be9a535aeaa203b77cba0f0e13a2b44b7e486 Mon Sep 17 00:00:00 2001 From: jkrivas Date: Tue, 7 Jul 2020 17:53:40 +0300 Subject: [PATCH 10/28] add function to create first available child subnet --- controllers/subnets/subnets.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/controllers/subnets/subnets.go b/controllers/subnets/subnets.go index b2acb3d..180389f 100644 --- a/controllers/subnets/subnets.go +++ b/controllers/subnets/subnets.go @@ -117,6 +117,12 @@ func (c *Controller) CreateSubnet(in Subnet) (message string, err error) { return } +// CreateFirstFreeSubnet creates a first free child subnet inside subnet with specified mask by sending a POST request. +func (c *Controller) CreateFirstFreeSubnet(id int, mask int, in Subnet) (out string, err error) { + err = c.SendRequest("POST", fmt.Sprintf("/subnets/%d/first_subnet/%d/", id, mask), &in, &out) + return +} + // GetSubnetByID GETs a subnet via its ID. func (c *Controller) GetSubnetByID(id int) (out Subnet, err error) { err = c.SendRequest("GET", fmt.Sprintf("/subnets/%d/", id), &struct{}{}, &out) From 872061f9d3e0165214ab9ab3719d2bdc236bbb62 Mon Sep 17 00:00:00 2001 From: jkrivas Date: Wed, 8 Jul 2020 10:53:18 +0300 Subject: [PATCH 11/28] add get next free subnet function --- controllers/subnets/subnets.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/controllers/subnets/subnets.go b/controllers/subnets/subnets.go index 180389f..cfa925f 100644 --- a/controllers/subnets/subnets.go +++ b/controllers/subnets/subnets.go @@ -118,8 +118,8 @@ func (c *Controller) CreateSubnet(in Subnet) (message string, err error) { } // CreateFirstFreeSubnet creates a first free child subnet inside subnet with specified mask by sending a POST request. -func (c *Controller) CreateFirstFreeSubnet(id int, mask int, in Subnet) (out string, err error) { - err = c.SendRequest("POST", fmt.Sprintf("/subnets/%d/first_subnet/%d/", id, mask), &in, &out) +func (c *Controller) CreateFirstFreeSubnet(id int, mask int, in Subnet) (message string, err error) { + err = c.SendRequest("POST", fmt.Sprintf("/subnets/%d/first_subnet/%d/", id, mask), &in, &message) return } @@ -141,6 +141,12 @@ func (c *Controller) GetSubnetsByCIDR(cidr string) (out []Subnet, err error) { return } +// GetFirstFreeSubnet GETs the first free child subnet inside subnet with specified mask +func (c *Controller) GetFirstFreeSubnet(id int, mask int) (message string, err error) { + err = c.SendRequest("GET", fmt.Sprintf("/subnets/%d/first_subnet/%d/", id, mask), &struct{}{}, &message) + return +} + // GetFirstFreeAddress GETs the first free IP address in a subnet and returns // it as a string. This can be used to automatically determine the next address // you should use. If there are no more available addresses, the string will be From 86aacb20e2d324e4f5727170c65f45bf9eeebae8 Mon Sep 17 00:00:00 2001 From: jkrivas Date: Wed, 8 Jul 2020 16:30:01 +0300 Subject: [PATCH 12/28] add unit tests --- controllers/subnets/subnets_test.go | 65 +++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/controllers/subnets/subnets_test.go b/controllers/subnets/subnets_test.go index d58f20e..ed14d62 100644 --- a/controllers/subnets/subnets_test.go +++ b/controllers/subnets/subnets_test.go @@ -31,6 +31,21 @@ const testCreateSubnetOutputJSON = ` } ` +var testCreateFirstFreeSubnetInput = Subnet{ + Description: "Subnet1", +} + +const testCreateFirstFreeSubnetOutputExpected = "10.10.4.0/25" +const testCreateFirstFreeSubnetOutputJSON = ` +{ + "code": 201, + "success": true, + "message": "Subnet created", + "id": "10", + "data": "10.10.4.0/25" +} +` + var testGetSubnetByIDOutputExpected = Subnet{ ID: 8, SubnetAddress: "10.10.3.0", @@ -189,6 +204,15 @@ const testGetSubnetsByCIDROutputJSON = ` } ` +const testGetFirstFreeSubnetOutputExpected = "10.10.4.0/25" +const testGetFirstFreeSubnetOutputJSON = ` +{ + "code": 200, + "success": true, + "data": "10.10.4.0/25" +} +` + const testGetFirstFreeAddressOutputExpected = "10.10.1.1" const testGetFirstFreeAddressOutputJSON = ` { @@ -503,6 +527,27 @@ func TestCreateSubnet(t *testing.T) { } } +func TestCreateFirstFreeSubnet(t *testing.T){ + ts := httpCreatedTestServer(testCreateFirstFreeSubnetOutputJSON) + defer ts.Close() + sess := fullSessionConfig() + sess.Config.Endpoint = ts.URL + client := NewController(sess) + + in := testCreateFirstFreeSubnetInput + mask := 25 + id := 2 + expected := testCreateFirstFreeSubnetOutputExpected + actual, err := client.CreateFirstFreeSubnet(id, mask, in) + if err != nil { + t.Fatalf("Bad: %s", err) + } + + if !reflect.DeepEqual(expected, actual) { + t.Fatalf("Expected %#v, got %#v", expected, actual) + } +} + func TestGetSubnetByID(t *testing.T) { ts := httpOKTestServer(testGetSubnetByIDOutputJSON) defer ts.Close() @@ -539,6 +584,26 @@ func TestGetSubnetsByCIDR(t *testing.T) { } } +func TestGetFirstFreeSubnet(t *testing.T) { + ts := httpOKTestServer(testGetFirstFreeSubnetOutputJSON) + defer ts.Close() + sess := fullSessionConfig() + sess.Config.Endpoint = ts.URL + client := NewController(sess) + + id := 2 + mask := 25 + expected := testGetFirstFreeSubnetOutputExpected + actual, err := client.GetFirstFreeSubnet(id, mask) + if err != nil { + t.Fatalf("Bad: %s", err) + } + + if !reflect.DeepEqual(expected, actual) { + t.Fatalf("Expected %#v, got %#v", expected, actual) + } +} + func TestGetFirstFreeAddress(t *testing.T) { ts := httpOKTestServer(testGetFirstFreeAddressOutputJSON) defer ts.Close() From c193c4afc981f915155b72aea5a6dd8854fc66a9 Mon Sep 17 00:00:00 2001 From: pavel-z1 Date: Fri, 18 Sep 2020 11:12:49 +0300 Subject: [PATCH 13/28] Fixed crash when using custom_field_filter with phpipam_addresses data object --- phpipam/client/client.go | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/phpipam/client/client.go b/phpipam/client/client.go index 48aed9c..e20c3e0 100644 --- a/phpipam/client/client.go +++ b/phpipam/client/client.go @@ -4,6 +4,7 @@ package client import ( "fmt" + "log" "github.com/pavel-z1/phpipam-sdk-go/phpipam" "github.com/pavel-z1/phpipam-sdk-go/phpipam/request" @@ -100,11 +101,9 @@ func (c *Client) GetCustomFields(id int, controller string) (out map[string]inte var schema map[string]phpipam.CustomField schema, err = c.GetCustomFieldsSchema(controller) switch { - case err.Error() == "Error from API (200): No custom fields defined": - err = nil - return - case err != nil: - return + case err != nil: + log.Printf("Error getting custom Fields: %s", err) + return } out, err = c.getCustomFieldsRequest(id, controller, schema) @@ -148,12 +147,12 @@ func (c *Client) UpdateCustomFields(id int, in map[string]interface{}, controlle var schema map[string]phpipam.CustomField schema, err = c.GetCustomFieldsSchema(controller) switch { - // Ignore this error if the caller is not setting any fields. - case len(in) == 0 && err.Error() == "Error from API (200): No custom fields defined": - err = nil - return - case err != nil: - return + // Ignore this error if the caller is not setting any fields. + case len(in) == 0 && err.Error() == "Error from API (200): No custom fields defined": + err = nil + return + case err != nil: + return } message, err = c.updateCustomFieldsRequest(id, in, controller, schema) return From 4e09538eb5d71dfbd5406ac75f1c3b552b16a3e0 Mon Sep 17 00:00:00 2001 From: Preben Berg Date: Tue, 7 Jun 2022 13:40:43 +0200 Subject: [PATCH 14/28] Expand Nameserver information --- controllers/subnets/subnets.go | 3 +++ controllers/subnets/subnets_test.go | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/controllers/subnets/subnets.go b/controllers/subnets/subnets.go index cfa925f..caf844c 100644 --- a/controllers/subnets/subnets.go +++ b/controllers/subnets/subnets.go @@ -43,6 +43,9 @@ type Subnet struct { // The ID of the nameserver to attache the subnet to. NameserverID int `json:"nameserverId,string,omitempty"` + // The ID and IPs of the nameservers for the subnet + Nameservers map[string]interface{} `json:"nameservers,omitempty"` + // true if the name should be displayed in listing instead of the subnet // address. ShowName phpipam.BoolIntString `json:"showName,omitempty"` diff --git a/controllers/subnets/subnets_test.go b/controllers/subnets/subnets_test.go index ed14d62..39948c4 100644 --- a/controllers/subnets/subnets_test.go +++ b/controllers/subnets/subnets_test.go @@ -77,6 +77,13 @@ const testGetSubnetByIDOutputJSON = ` "DNSrecursive": "0", "DNSrecords": "0", "nameserverId": "0", + "nameservers": { + "id": "0", + "name": "mynameserver.example.com", + "namesrv1": "1.2.3.4", + "description": "a nameserver description", + "permissions": 1 + }, "scanAgent": null, "isFolder": "0", "isFull": "0", From d16ccb0e5d4ad1715c28b3ca6d281ea53b85ff26 Mon Sep 17 00:00:00 2001 From: pavel-z1 Date: Wed, 15 Jun 2022 14:12:25 +0300 Subject: [PATCH 15/28] Added search Subnet by CIDR and SectionID --- controllers/subnets/subnets.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/controllers/subnets/subnets.go b/controllers/subnets/subnets.go index caf844c..1111e7b 100644 --- a/controllers/subnets/subnets.go +++ b/controllers/subnets/subnets.go @@ -144,6 +144,11 @@ func (c *Controller) GetSubnetsByCIDR(cidr string) (out []Subnet, err error) { return } +func (c *Controller) GetSubnetsByCIDRAndSection(cidr string, section_id int) (out []Subnet, err error) { + err = c.SendRequest("GET", fmt.Sprintf("/subnets/cidr/%s/?filter_by=sectionId\\&filter_value=%d", cidr, section_id), &struct{}{}, &out) + return +} + // GetFirstFreeSubnet GETs the first free child subnet inside subnet with specified mask func (c *Controller) GetFirstFreeSubnet(id int, mask int) (message string, err error) { err = c.SendRequest("GET", fmt.Sprintf("/subnets/%d/first_subnet/%d/", id, mask), &struct{}{}, &message) From c6caeb5123ae2d4521486a04bb810969b80ada51 Mon Sep 17 00:00:00 2001 From: pavel-z1 Date: Wed, 15 Jun 2022 14:12:25 +0300 Subject: [PATCH 16/28] Added search Subnet by CIDR and SectionID --- controllers/subnets/subnets.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/controllers/subnets/subnets.go b/controllers/subnets/subnets.go index caf844c..5ae2cae 100644 --- a/controllers/subnets/subnets.go +++ b/controllers/subnets/subnets.go @@ -144,6 +144,11 @@ func (c *Controller) GetSubnetsByCIDR(cidr string) (out []Subnet, err error) { return } +func (c *Controller) GetSubnetsByCIDRAndSection(cidr string, section_id int) (out []Subnet, err error) { + err = c.SendRequest("GET", fmt.Sprintf("/subnets/cidr/%s/?filter_by=sectionId&filter_value=%d", cidr, section_id), &struct{}{}, &out) + return +} + // GetFirstFreeSubnet GETs the first free child subnet inside subnet with specified mask func (c *Controller) GetFirstFreeSubnet(id int, mask int) (message string, err error) { err = c.SendRequest("GET", fmt.Sprintf("/subnets/%d/first_subnet/%d/", id, mask), &struct{}{}, &message) From 5c787bd9508924357df08857a2ed37d9c4178dfd Mon Sep 17 00:00:00 2001 From: pavel-z1 <53462452+pavel-z1@users.noreply.github.com> Date: Wed, 15 Jun 2022 14:38:31 +0300 Subject: [PATCH 17/28] Revert "Feature search in section by CIDR" --- controllers/subnets/subnets.go | 5 ----- 1 file changed, 5 deletions(-) diff --git a/controllers/subnets/subnets.go b/controllers/subnets/subnets.go index 1111e7b..caf844c 100644 --- a/controllers/subnets/subnets.go +++ b/controllers/subnets/subnets.go @@ -144,11 +144,6 @@ func (c *Controller) GetSubnetsByCIDR(cidr string) (out []Subnet, err error) { return } -func (c *Controller) GetSubnetsByCIDRAndSection(cidr string, section_id int) (out []Subnet, err error) { - err = c.SendRequest("GET", fmt.Sprintf("/subnets/cidr/%s/?filter_by=sectionId\\&filter_value=%d", cidr, section_id), &struct{}{}, &out) - return -} - // GetFirstFreeSubnet GETs the first free child subnet inside subnet with specified mask func (c *Controller) GetFirstFreeSubnet(id int, mask int) (message string, err error) { err = c.SendRequest("GET", fmt.Sprintf("/subnets/%d/first_subnet/%d/", id, mask), &struct{}{}, &message) From a12e85c8e525102bcbcea58402181711b96964f2 Mon Sep 17 00:00:00 2001 From: meisterfischy Date: Wed, 21 Sep 2022 16:34:29 +0200 Subject: [PATCH 18/28] Added token login support Sets the password as the token, if the username is empty. This way one can login using an api token. --- phpipam/client/client.go | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/phpipam/client/client.go b/phpipam/client/client.go index e20c3e0..3e80162 100644 --- a/phpipam/client/client.go +++ b/phpipam/client/client.go @@ -29,16 +29,20 @@ func NewClient(s *session.Session) *Client { // loginSession logs in a session via the user controller. This is the only // valid operation if the session does not have a token yet. func loginSession(s *session.Session) error { - var out session.Token - r := request.NewRequest(s) - r.Method = "POST" - r.URI = "/user/" - r.Input = &struct{}{} - r.Output = &out - if err := r.Send(); err != nil { - return err - } - s.Token = out + if s.Config.Username == "" { + s.Token.String = s.Config.Password + } else { + var out session.Token + r := request.NewRequest(s) + r.Method = "POST" + r.URI = "/user/" + r.Input = &struct{}{} + r.Output = &out + if err := r.Send(); err != nil { + return err + } + s.Token = out + } return nil } From 18cc3466f935df55f1401ed9fea2b13dc9d70b45 Mon Sep 17 00:00:00 2001 From: Cristian Calin Date: Fri, 17 Mar 2023 14:13:57 +0200 Subject: [PATCH 19/28] enable the http client to pick up proxy from environment --- go.sum | 2 ++ phpipam/request/request.go | 1 + 2 files changed, 3 insertions(+) create mode 100644 go.sum diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..117449d --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/imdario/mergo v0.0.0-20160517064435-50d4dbd4eb0e h1:zIX9lnwsSCcX3oc3J5w16I+3zmf6a+vdf80ygUqpah8= +github.com/imdario/mergo v0.0.0-20160517064435-50d4dbd4eb0e/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= diff --git a/phpipam/request/request.go b/phpipam/request/request.go index 3ca88c8..a9ab422 100644 --- a/phpipam/request/request.go +++ b/phpipam/request/request.go @@ -134,6 +134,7 @@ func (r *Request) Send() error { var err error tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: r.Session.Config.Insecure}, + Proxy: http.ProxyFromEnvironment, } client := &http.Client{ Transport: tr, From 1688b87fffbf46c6680d9f662536ac15233a8ff2 Mon Sep 17 00:00:00 2001 From: Anatoly Date: Thu, 30 Mar 2023 14:35:45 +1300 Subject: [PATCH 20/28] Adding option to search an ip with in a subnet When having multiple subnets with same ip range this will return the address in the given subnet. Those subnet may not talk to each other, but still exist under one phpIPAM instance especially on ones migrated from previous versions --- controllers/addresses/addresses.go | 8 ++++ controllers/addresses/addresses_test.go | 59 +++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/controllers/addresses/addresses.go b/controllers/addresses/addresses.go index f5e7df7..31c39d2 100644 --- a/controllers/addresses/addresses.go +++ b/controllers/addresses/addresses.go @@ -112,6 +112,14 @@ func (c *Controller) GetAddressesByIP(ipaddr string) (out []Address, err error) return } +// GetAddressesByIP searches for an address by its IP with in given subnet +// When having multiple subnets with same ip range this will return the address in the given subnet +// Those subnet may not talk to each other but still exist under on phpIPAM instance especially on ones migrated from previous versions +func (c *Controller) GetAddressesByIpInSubnet(ipaddr string,subnetID int) (out Address, err error) { + err = c.SendRequest("GET", fmt.Sprintf("/addresses/%s/%d", ipaddr,subnetID), &struct{}{}, &out) + return +} + // GetAddressCustomFieldsSchema GETs the custom fields for the addresses controller via // client.GetCustomFieldsSchema. func (c *Controller) GetAddressCustomFieldsSchema() (out map[string]phpipam.CustomField, err error) { diff --git a/controllers/addresses/addresses_test.go b/controllers/addresses/addresses_test.go index 6189f0a..7c062bb 100644 --- a/controllers/addresses/addresses_test.go +++ b/controllers/addresses/addresses_test.go @@ -127,6 +127,46 @@ const testGetAddressesByIPOutputJSON = ` } ` +var testGetAddressesByIpInSubnetOutputExpected = Address{ + ID: 11, + SubnetID: 3, + IPAddress: "10.10.1.10", + Description: "foobar", + +} + +const testGetAddressesByIpInSubnetOutputJSON = ` +{ + "code": 200, + "success": true, + "data": + { + "id": "11", + "subnetId": "3", + "ip": "10.10.1.10", + "is_gateway": null, + "description": "foobar", + "hostname": null, + "mac": null, + "owner": null, + "port": null, + "note": null, + "lastSeen": null, + "excludePing": null, + "PTRignore": null, + "PTR": "0", + "firewallAddressObject": null, + "editDate": null, + "links": [ + { + "rel": "self", + "href": "/api/test/addresses/11/" + } + ] + } +} +` + var testGetAddressCustomFieldsSchemaExpected = map[string]phpipam.CustomField{ "CustomTestAddresses": phpipam.CustomField{ Name: "CustomTestAddresses", @@ -277,6 +317,25 @@ func TestGetAddressesByIP(t *testing.T) { } } +func TestGetAddressesByIpInSubnet(t *testing.T) { + ts := httpOKTestServer(testGetAddressesByIpInSubnetOutputJSON) + defer ts.Close() + sess := fullSessionConfig() + sess.Config.Endpoint = ts.URL + client := NewController(sess) + + expected := testGetAddressesByIpInSubnetOutputExpected + actual, err := client.GetAddressesByIpInSubnet("10.10.1.10/24",3) + if err != nil { + t.Fatalf("Bad: %s", err) + } + + if !reflect.DeepEqual(expected, actual) { + t.Fatalf("Expected %#v, got %#v", expected, actual) + } +} + + func TestGetAddressCustomFieldsSchema(t *testing.T) { ts := httpOKTestServer(testGetAddressCustomFieldsSchemaJSON) defer ts.Close() From 85f25adf2bf8e9f0e7dea3c8e5d631160987bf1d Mon Sep 17 00:00:00 2001 From: Yannick Martin Date: Tue, 14 Mar 2023 10:34:23 +0100 Subject: [PATCH 21/28] Added missing Nameservers details in testGetSubnetByIDOutputExpected --- controllers/subnets/subnets_test.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/controllers/subnets/subnets_test.go b/controllers/subnets/subnets_test.go index 39948c4..2392e10 100644 --- a/controllers/subnets/subnets_test.go +++ b/controllers/subnets/subnets_test.go @@ -52,6 +52,13 @@ var testGetSubnetByIDOutputExpected = Subnet{ Mask: 24, SectionID: 1, MasterSubnetID: 2, + Nameservers: map[string]interface{}{ + "id": "0", + "name": "mynameserver.example.com", + "namesrv1": "1.2.3.4", + "description": "a nameserver description", + "permissions": "1", + }, } const testGetSubnetByIDOutputJSON = ` @@ -82,7 +89,7 @@ const testGetSubnetByIDOutputJSON = ` "name": "mynameserver.example.com", "namesrv1": "1.2.3.4", "description": "a nameserver description", - "permissions": 1 + "permissions": "1" }, "scanAgent": null, "isFolder": "0", @@ -534,7 +541,7 @@ func TestCreateSubnet(t *testing.T) { } } -func TestCreateFirstFreeSubnet(t *testing.T){ +func TestCreateFirstFreeSubnet(t *testing.T) { ts := httpCreatedTestServer(testCreateFirstFreeSubnetOutputJSON) defer ts.Close() sess := fullSessionConfig() From de8e01323b0fe3892d4148c7849279d1eff33aaa Mon Sep 17 00:00:00 2001 From: Yannick Martin Date: Fri, 31 Mar 2023 12:08:16 +0200 Subject: [PATCH 22/28] Added logging level support to prevent debug message in production environment --- README.md | 9 +++++++++ go.mod | 13 ++++++++++++- phpipam/client/client.go | 26 +++++++++++++++++++++++--- phpipam/request/request.go | 28 ++++++++++++++++++++++++---- vendor/vendor.json | 19 +++++++++++++++++++ 5 files changed, 87 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 4d8344b..ca41493 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,15 @@ fields, enable the nested functionality - otherwise, ensure that your fields are not required and choose sane defaults if it's absolutely necessary for data to be present. +## A Note on Logging + +This software uses apex library to handle logging. You can control verbosity by +setting environment variable PHPIPAMSDK_LOGLEVEL to one of supported value: +* debug +* info +* warn +* error +* fatal ## License diff --git a/go.mod b/go.mod index 29d2c1b..f83cebe 100644 --- a/go.mod +++ b/go.mod @@ -1,5 +1,16 @@ module github.com/pavel-z1/phpipam-sdk-go -require github.com/imdario/mergo v0.0.0-20160517064435-50d4dbd4eb0e +require ( + github.com/Bowery/prompt v0.0.0-20190916142128-fa8279994f75 // indirect + github.com/apex/log v1.9.0 // indirect + github.com/dchest/safefile v0.0.0-20151022103144-855e8d98f185 // indirect + github.com/go-logfmt/logfmt v0.6.0 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect + github.com/imdario/mergo v0.0.0-20160517064435-50d4dbd4eb0e + github.com/kardianos/govendor v1.0.9 // indirect + github.com/pkg/errors v0.9.1 // indirect + golang.org/x/tools v0.7.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) go 1.13 diff --git a/phpipam/client/client.go b/phpipam/client/client.go index 3e80162..c6618d7 100644 --- a/phpipam/client/client.go +++ b/phpipam/client/client.go @@ -4,8 +4,10 @@ package client import ( "fmt" - "log" + "os" + "github.com/apex/log" + "github.com/apex/log/handlers/logfmt" "github.com/pavel-z1/phpipam-sdk-go/phpipam" "github.com/pavel-z1/phpipam-sdk-go/phpipam/request" "github.com/pavel-z1/phpipam-sdk-go/phpipam/session" @@ -20,12 +22,30 @@ type Client struct { // NewClient creates a new client. func NewClient(s *session.Session) *Client { + log.SetLevel(log.InfoLevel) + log.SetHandler(logfmt.New(os.Stderr)) + + env_loglevel := os.Getenv("PHPIPAMSDK_LOGLEVEL") + if env_loglevel != "" { + loglevel, err := log.ParseLevel(env_loglevel) + if err == nil { + log.SetLevel(loglevel) + } else { + log.Warnf("Invalid log level, defaulting to info: %s", err) + } + } + c := &Client{ Session: s, } return c } +// change logger level, default is info +func SetLevel(level log.Level) { + log.SetLevel(level) +} + // loginSession logs in a session via the user controller. This is the only // valid operation if the session does not have a token yet. func loginSession(s *session.Session) error { @@ -42,7 +62,7 @@ func loginSession(s *session.Session) error { return err } s.Token = out - } + } return nil } @@ -106,7 +126,7 @@ func (c *Client) GetCustomFields(id int, controller string) (out map[string]inte schema, err = c.GetCustomFieldsSchema(controller) switch { case err != nil: - log.Printf("Error getting custom Fields: %s", err) + log.Warnf("Error getting custom Fields: %s", err) return } diff --git a/phpipam/request/request.go b/phpipam/request/request.go index 3ca88c8..4da2b42 100644 --- a/phpipam/request/request.go +++ b/phpipam/request/request.go @@ -7,9 +7,11 @@ import ( "encoding/json" "fmt" "io/ioutil" - "log" "net/http" + "os" + "github.com/apex/log" + "github.com/apex/log/handlers/logfmt" "github.com/pavel-z1/phpipam-sdk-go/phpipam/session" ) @@ -116,7 +118,7 @@ func newRequestResponse(r *http.Response) *requestResponse { } defer r.Body.Close() body, err := ioutil.ReadAll(r.Body) - log.Printf("Response Body Debug ................... %s", body) + log.Debugf("Response Body Debug ................... %s", body) if err != nil { panic(err) } @@ -145,12 +147,12 @@ func (r *Request) Send() error { switch r.Method { case "OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE": bs, err := json.Marshal(r.Input) - log.Printf("Request Body Debug ................... %s", bs) + log.Debugf("Request Body Debug ................... %s", bs) if err != nil { return fmt.Errorf("Error preparing request data: %s", err) } buf := bytes.NewBuffer(bs) - log.Printf("Request URL Debug ...................Method: %s, UR: %s/%s%s", r.Method, r.Session.Config.Endpoint, r.Session.Config.AppID, r.URI) + log.Debugf("Request URL Debug ...................Method: %s, UR: %s/%s%s", r.Method, r.Session.Config.Endpoint, r.Session.Config.AppID, r.URI) req, err = http.NewRequest(r.Method, fmt.Sprintf("%s/%s%s", r.Session.Config.Endpoint, r.Session.Config.AppID, r.URI), buf) req.Header.Add("Content-Type", "application/json") default: @@ -195,8 +197,26 @@ func (r *Request) Send() error { // NewRequest creates a new request instance with configuration set. func NewRequest(s *session.Session) *Request { + log.SetLevel(log.InfoLevel) + log.SetHandler(logfmt.New(os.Stderr)) + + env_loglevel := os.Getenv("PHPIPAMSDK_LOGLEVEL") + if env_loglevel != "" { + loglevel, err := log.ParseLevel(env_loglevel) + if err == nil { + log.SetLevel(loglevel) + } else { + log.Warnf("Invalid log level, defaulting to info: %s", err) + } + } + r := &Request{ Session: s, } return r } + +// change logger level, default is info +func SetLevel(level log.Level) { + log.SetLevel(level) +} diff --git a/vendor/vendor.json b/vendor/vendor.json index ceee059..f734c70 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -2,11 +2,30 @@ "comment": "", "ignore": "test", "package": [ + { + "checksumSHA1": "XiHV3bYcd1RJ03nIT/U4QFynF6w=", + "path": "github.com/apex/log", + "revision": "3edb93e9f62c13dccdbf0759bd9da5b71dc60926", + "revisionTime": "2020-08-18T07:36:17Z", + "version": "v1.9.0", + "versionExact": "v1.9.0" + }, { "checksumSHA1": "hwGdeQbcfc2RvIQS5wAaYRKJDd4=", "path": "github.com/imdario/mergo", "revision": "50d4dbd4eb0e84778abe37cefef140271d96fade", "revisionTime": "2016-05-17T06:44:35Z" + }, + { + "checksumSHA1": "Qo2E/26skb9mZQ3b2Mh6QDkpBLs=", + "path": "github.com/pkg/errors", + "revision": "5dd12d0cfe7f152f80558d591504ce685299311e", + "revisionTime": "2020-12-14T06:45:52Z" + }, + { + "checksumSHA1": "zamq7bor1Nt+tXE3sJ3lH21K/f4=", + "path": "log", + "revision": "" } ], "rootPath": "github.com/pavel-z1/phpipam-sdk-go" From d963038d2a9c706f0d2b925762ae19b4d789ca7d Mon Sep 17 00:00:00 2001 From: pavel-z1 <53462452+pavel-z1@users.noreply.github.com> Date: Wed, 26 Apr 2023 12:18:57 +0300 Subject: [PATCH 23/28] Added resolveDNS option --- controllers/subnets/subnets.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/controllers/subnets/subnets.go b/controllers/subnets/subnets.go index 5ae2cae..62893ec 100644 --- a/controllers/subnets/subnets.go +++ b/controllers/subnets/subnets.go @@ -88,10 +88,10 @@ type Subnet struct { EditDate string `json:"editDate,omitempty"` // Gateway IP and ID of Gateway IP - Gateway map[string]interface{} `json:"gateway,omitempty"` + Gateway map[string]interface{} `json:"gateway,omitempty"` // Gateway IP ID - GatewayID string `json:"gatewayId,omitempty"` + GatewayID string `json:"gatewayId,omitempty"` // A map[string]interface{} of custom fields to set on the resource. Note // that this functionality requires PHPIPAM 1.3 or higher with the "Nest @@ -99,6 +99,9 @@ type Subnet struct { // enabled, this map will be nil on GETs and POSTs and PATCHes with this // field set will fail. Use the explicit custom field functions instead. CustomFields map[string]interface{} `json:"custom_fields,omitempty"` + + // Controls enabling resolve DNS function. + ResolveDNS phpipam.BoolIntString `json:"resolveDNS,omitempty"` } // Controller is the base client for the Subnets controller. From b4cce26d50cc3b720ceef5b623297509e4b9a743 Mon Sep 17 00:00:00 2001 From: pavel-z1 <53462452+pavel-z1@users.noreply.github.com> Date: Wed, 10 May 2023 08:14:50 +0300 Subject: [PATCH 24/28] Added l2domains controller. Vlans - added function GetVLANsByNumberAndDomainID --- controllers/l2domains/l2domains.go | 82 ++++++++++++++++++++ controllers/vlans/vlans.go | 5 ++ go.mod | 5 +- go.sum | 115 +++++++++++++++++++++++++++++ 4 files changed, 205 insertions(+), 2 deletions(-) create mode 100644 controllers/l2domains/l2domains.go diff --git a/controllers/l2domains/l2domains.go b/controllers/l2domains/l2domains.go new file mode 100644 index 0000000..3b66bcf --- /dev/null +++ b/controllers/l2domains/l2domains.go @@ -0,0 +1,82 @@ +// Package l2domains provides types and methods for working with the l2domains +// controller. +package l2domains + +import ( + "fmt" + + "github.com/pavel-z1/phpipam-sdk-go/controllers/vlans" + //"github.com/pavel-z1/phpipam-sdk-go/phpipam" + "github.com/pavel-z1/phpipam-sdk-go/phpipam/client" + "github.com/pavel-z1/phpipam-sdk-go/phpipam/session" +) + +// L2Domain represents a PHPIPAM l2domain. +type L2Domain struct { + // The L2 domain ID. + ID int `json:"id,string,omitempty"` + + // The L2 domains name. + Name string `json:"name,omitempty"` + + // The l2domain's description. + Description string `json:"description,omitempty"` + + // The ID of the section's parent, if nested. + Sections string `json:"sections,omitempty"` +} + +// Controller is the base client for the L2Domains controller. +type Controller struct { + client.Client +} + +// NewController returns a new instance of the client for the L2Domains controller. +func NewController(sess *session.Session) *Controller { + c := &Controller{ + Client: *client.NewClient(sess), + } + return c +} + +// ListL2Domains lists all l2domains. +func (c *Controller) ListL2Domains() (out []L2Domain, err error) { + err = c.SendRequest("GET", "/l2domains/", &struct{}{}, &out) + return +} + +// CreateL2Domain creates a l2domain by sending a POST request. +func (c *Controller) CreateL2Domain(in L2Domain) (message string, err error) { + err = c.SendRequest("POST", "/l2domains/", &in, &message) + return +} + +// GetL2DomainByID GETs a l2domain via its ID. +func (c *Controller) GetL2DomainByID(id int) (out L2Domain, err error) { + err = c.SendRequest("GET", fmt.Sprintf("/l2domains/%d/", id), &struct{}{}, &out) + return +} + +// GetL2DomainByName GETs a l2domain via its name. +func (c *Controller) GetL2DomainByName(name string) (out []L2Domain, err error) { + err = c.SendRequest("GET", fmt.Sprintf("/l2domains/?filter_by=name&filter_value=%s", name), &struct{}{}, &out) + return +} + +// GetVlansInL2Domain GETs the vlans in a l2domains by l2domain ID. +func (c *Controller) GetVlansInl2Domain(id int) (out []vlans.VLAN, err error) { + err = c.SendRequest("GET", fmt.Sprintf("/l2domains/%d/vlans/", id), &struct{}{}, &out) + return +} + +// UpdateL2Domain updates a l2domain by sending a PATCH request. +func (c *Controller) UpdateL2Domain(in L2Domain) (err error) { + err = c.SendRequest("PATCH", "/l2domains/", &in, &struct{}{}) + return +} + +// DeleteL2Domain deletes a l2domain by sending a DELETE request. All subnets and +func (c *Controller) DeleteL2Domain(id int) (err error) { + err = c.SendRequest("DELETE", fmt.Sprintf("/l2domains/%d/", id), &struct{}{}, &struct{}{}) + return +} diff --git a/controllers/vlans/vlans.go b/controllers/vlans/vlans.go index a7e99e4..0ee3a13 100644 --- a/controllers/vlans/vlans.go +++ b/controllers/vlans/vlans.go @@ -75,6 +75,11 @@ func (c *Controller) GetVLANsByNumber(id int) (out []VLAN, err error) { return } +func (c *Controller) GetVLANsByNumberAndDomainID(vlan_id int, domain_id int) (out []VLAN, err error) { + err = c.SendRequest("GET", fmt.Sprintf("/vlans/search/%d/?filter_by=domainId&filter_value=%d", vlan_id, domain_id), &struct{}{}, &out) + return +} + // GetVLANCustomFieldsSchema GETs the custom fields for the vlans controller via // client.GetCustomFieldsSchema. func (c *Controller) GetVLANCustomFieldsSchema() (out map[string]phpipam.CustomField, err error) { diff --git a/go.mod b/go.mod index f83cebe..bbea607 100644 --- a/go.mod +++ b/go.mod @@ -2,14 +2,15 @@ module github.com/pavel-z1/phpipam-sdk-go require ( github.com/Bowery/prompt v0.0.0-20190916142128-fa8279994f75 // indirect - github.com/apex/log v1.9.0 // indirect + github.com/apex/log v1.9.0 + github.com/davecgh/go-spew v1.1.1 github.com/dchest/safefile v0.0.0-20151022103144-855e8d98f185 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/imdario/mergo v0.0.0-20160517064435-50d4dbd4eb0e github.com/kardianos/govendor v1.0.9 // indirect github.com/pkg/errors v0.9.1 // indirect - golang.org/x/tools v0.7.0 // indirect + golang.org/x/tools v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index 117449d..d266db3 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,117 @@ +github.com/Bowery/prompt v0.0.0-20190916142128-fa8279994f75 h1:xGHheKK44eC6K0u5X+DZW/fRaR1LnDdqPHMZMWx5fv8= +github.com/Bowery/prompt v0.0.0-20190916142128-fa8279994f75/go.mod h1:4/6eNcqZ09BZ9wLK3tZOjBA1nDj+B0728nlX5YRlSmQ= +github.com/apex/log v1.9.0 h1:FHtw/xuaM8AgmvDDTI9fiwoAL25Sq2cxojnZICUU8l0= +github.com/apex/log v1.9.0/go.mod h1:m82fZlWIuiWzWP04XCTXmnX0xRkYYbCdYn8jbJeLBEA= +github.com/apex/logs v1.0.0/go.mod h1:XzxuLZ5myVHDy9SAmYpamKKRNApGj54PfYLcFrXqDwo= +github.com/aphistic/golf v0.0.0-20180712155816-02c07f170c5a/go.mod h1:3NqKYiepwy8kCu4PNA+aP7WUV72eXWJeP9/r3/K9aLE= +github.com/aphistic/sweet v0.2.0/go.mod h1:fWDlIh/isSE9n6EPsRmC0det+whmX6dJid3stzu0Xys= +github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dchest/safefile v0.0.0-20151022103144-855e8d98f185 h1:3T8ZyTDp5QxTx3NU48JVb2u+75xc040fofcBaN+6jPA= +github.com/dchest/safefile v0.0.0-20151022103144-855e8d98f185/go.mod h1:cFRxtTwTOJkz2x3rQUNCYKWC93yP1VKjR8NUhqFxZNU= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= +github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/imdario/mergo v0.0.0-20160517064435-50d4dbd4eb0e h1:zIX9lnwsSCcX3oc3J5w16I+3zmf6a+vdf80ygUqpah8= github.com/imdario/mergo v0.0.0-20160517064435-50d4dbd4eb0e/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= +github.com/kardianos/govendor v1.0.9 h1:WOH3FcVI9eOgnIZYg96iwUwrL4eOVx+aQ66oyX2R8Yc= +github.com/kardianos/govendor v1.0.9/go.mod h1:yvmR6q9ZZ7nSF5Wvh40v0wfP+3TwwL8zYQp+itoZSVM= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= +github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= +github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= +github.com/smartystreets/gunit v1.0.0/go.mod h1:qwPWnhz6pn0NnRBP++URONOVyNkPyr4SauJk4cUOwJs= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tj/assert v0.0.0-20171129193455-018094318fb0/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0= +github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk= +github.com/tj/go-buffer v1.1.0/go.mod h1:iyiJpfFcR2B9sXu7KvjbT9fpM4mOelRSDTbntVj52Uc= +github.com/tj/go-elastic v0.0.0-20171221160941-36157cbbebc2/go.mod h1:WjeM0Oo1eNAjXGDx2yma7uG2XoyRZTq1uv3M/o7imD0= +github.com/tj/go-kinesis v0.0.0-20171128231115-08b17f58cb1b/go.mod h1:/yhzCV0xPfx6jb1bBgRFjl5lytqVqZXEaeqWP8lTEao= +github.com/tj/go-spin v1.1.0/go.mod h1:Mg1mzmePZm4dva8Qz60H2lHwmJ2loum4VIrLgVnKwh4= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= +golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 270c62bf166cb481e7bdd1bbfba439136f21e7e5 Mon Sep 17 00:00:00 2001 From: Matthieu C Date: Thu, 11 May 2023 19:47:16 +0200 Subject: [PATCH 25/28] Avoid sending an empty body --- phpipam/request/request.go | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/phpipam/request/request.go b/phpipam/request/request.go index 0e095ba..f0ed144 100644 --- a/phpipam/request/request.go +++ b/phpipam/request/request.go @@ -147,15 +147,20 @@ func (r *Request) Send() error { switch r.Method { case "OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE": - bs, err := json.Marshal(r.Input) - log.Debugf("Request Body Debug ................... %s", bs) - if err != nil { - return fmt.Errorf("Error preparing request data: %s", err) + if r.Input != nil { + bs, err := json.Marshal(r.Input) + log.Debugf("Request Body Debug ................... %s", bs) + if err != nil { + return fmt.Errorf("Error preparing request data: %s", err) + } + buf := bytes.NewBuffer(bs) + req, err = http.NewRequest(r.Method, fmt.Sprintf("%s/%s%s", r.Session.Config.Endpoint, r.Session.Config.AppID, r.URI), buf) + } else { + req, err = http.NewRequest(r.Method, fmt.Sprintf("%s/%s%s", r.Session.Config.Endpoint, r.Session.Config.AppID, r.URI), nil) } - buf := bytes.NewBuffer(bs) - log.Debugf("Request URL Debug ...................Method: %s, UR: %s/%s%s", r.Method, r.Session.Config.Endpoint, r.Session.Config.AppID, r.URI) - req, err = http.NewRequest(r.Method, fmt.Sprintf("%s/%s%s", r.Session.Config.Endpoint, r.Session.Config.AppID, r.URI), buf) + req.Header.Add("Content-Type", "application/json") + log.Debugf("Request URL Debug ...................Method: %s, UR: %s/%s%s", r.Method, r.Session.Config.Endpoint, r.Session.Config.AppID, r.URI) default: return fmt.Errorf("API request method %s not supported by PHPIPAM", r.Method) } From 275b2facc361c695098c3bee8e98ed3e1fb9b872 Mon Sep 17 00:00:00 2001 From: Matthieu Courtois Date: Fri, 12 May 2023 21:39:43 +0200 Subject: [PATCH 26/28] fix(request): don't add body on GET request --- phpipam/request/request.go | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/phpipam/request/request.go b/phpipam/request/request.go index f0ed144..55bd382 100644 --- a/phpipam/request/request.go +++ b/phpipam/request/request.go @@ -146,24 +146,22 @@ func (r *Request) Send() error { } switch r.Method { - case "OPTIONS", "GET", "POST", "PUT", "PATCH", "DELETE": - if r.Input != nil { - bs, err := json.Marshal(r.Input) - log.Debugf("Request Body Debug ................... %s", bs) - if err != nil { - return fmt.Errorf("Error preparing request data: %s", err) - } - buf := bytes.NewBuffer(bs) - req, err = http.NewRequest(r.Method, fmt.Sprintf("%s/%s%s", r.Session.Config.Endpoint, r.Session.Config.AppID, r.URI), buf) - } else { - req, err = http.NewRequest(r.Method, fmt.Sprintf("%s/%s%s", r.Session.Config.Endpoint, r.Session.Config.AppID, r.URI), nil) + case "OPTIONS", "POST", "PUT", "PATCH", "DELETE": + bs, err := json.Marshal(r.Input) + log.Debugf("Request Body Debug ................... %s", bs) + if err != nil { + return fmt.Errorf("Error preparing request data: %s", err) } - + buf := bytes.NewBuffer(bs) + req, err = http.NewRequest(r.Method, fmt.Sprintf("%s/%s%s", r.Session.Config.Endpoint, r.Session.Config.AppID, r.URI), buf) req.Header.Add("Content-Type", "application/json") - log.Debugf("Request URL Debug ...................Method: %s, UR: %s/%s%s", r.Method, r.Session.Config.Endpoint, r.Session.Config.AppID, r.URI) + case "GET": + req, err = http.NewRequest(r.Method, fmt.Sprintf("%s/%s%s", r.Session.Config.Endpoint, r.Session.Config.AppID, r.URI), nil) + default: return fmt.Errorf("API request method %s not supported by PHPIPAM", r.Method) } + log.Debugf("Request URL Debug ...................Method: %s, UR: %s/%s%s", r.Method, r.Session.Config.Endpoint, r.Session.Config.AppID, r.URI) if err != nil { panic(err) From 05c01a0ec35ad7d2d906ab738da83aa526ea5727 Mon Sep 17 00:00:00 2001 From: "Jon \"The Nice Guy\" Spriggs" Date: Tue, 5 Sep 2023 22:13:18 +0100 Subject: [PATCH 27/28] Add isPool to the Subnet struct --- controllers/subnets/subnets.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/controllers/subnets/subnets.go b/controllers/subnets/subnets.go index 62893ec..71e2f64 100644 --- a/controllers/subnets/subnets.go +++ b/controllers/subnets/subnets.go @@ -75,6 +75,9 @@ type Subnet struct { // Controls if we are adding a subnet or folder. IsFolder phpipam.BoolIntString `json:"isFolder,omitempty"` + // Marks the subnet as permitting allocation of the network and broadcast addresses. + IsPool phpipam.BoolIntString `json:"isPool,omitempty"` + // Marks the subnet as used. IsFull phpipam.BoolIntString `json:"isFull,omitempty"` From 532fa71c2109ce025a915d396a1fb0a760122754 Mon Sep 17 00:00:00 2001 From: pavel-z1 <> Date: Fri, 17 May 2024 12:58:11 +0300 Subject: [PATCH 28/28] Backward compatibility of phpipam API format for phpipam 1.6.0 and higher --- phpipam/request/request.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/phpipam/request/request.go b/phpipam/request/request.go index 55bd382..546e349 100644 --- a/phpipam/request/request.go +++ b/phpipam/request/request.go @@ -155,8 +155,10 @@ func (r *Request) Send() error { buf := bytes.NewBuffer(bs) req, err = http.NewRequest(r.Method, fmt.Sprintf("%s/%s%s", r.Session.Config.Endpoint, r.Session.Config.AppID, r.URI), buf) req.Header.Add("Content-Type", "application/json") + req.Header.Add("api-stringify-results", "1") case "GET": req, err = http.NewRequest(r.Method, fmt.Sprintf("%s/%s%s", r.Session.Config.Endpoint, r.Session.Config.AppID, r.URI), nil) + req.Header.Add("api-stringify-results", "1") default: return fmt.Errorf("API request method %s not supported by PHPIPAM", r.Method)