diff --git a/go.mod b/go.mod index 459743865..36a323e9b 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/go-openapi/strfmt v0.21.2 github.com/gophercloud/gophercloud v0.24.0 github.com/gophercloud/utils v0.0.0-20220307143606-8e7800759d16 - github.com/infobloxopen/infoblox-go-client/v2 v2.0.0 + github.com/infobloxopen/infoblox-go-client/v2 v2.1.0 github.com/miekg/dns v1.1.44 github.com/netlify/open-api v1.1.0 github.com/onsi/ginkgo/v2 v2.1.6 @@ -137,3 +137,6 @@ require ( sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) + +// need open PR https://github.com/infobloxopen/infoblox-go-client/pull/195 +replace github.com/infobloxopen/infoblox-go-client/v2 => github.com/MartinWeindel/infoblox-go-client/v2 v2.0.0-20221122085954-b7d80ebb106b diff --git a/go.sum b/go.sum index c0ec76e21..9f3467508 100644 --- a/go.sum +++ b/go.sum @@ -98,6 +98,8 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/MartinWeindel/infoblox-go-client/v2 v2.0.0-20221122085954-b7d80ebb106b h1:5ltgdUOqRohN2Z/Xg8D0XUq2/Dir5kHvutd8CIkMZis= +github.com/MartinWeindel/infoblox-go-client/v2 v2.0.0-20221122085954-b7d80ebb106b/go.mod h1:+lznx4ASBSUZ2i6qwlgyn0v3eKDxBHNU5aRJzghAFbw= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= @@ -501,8 +503,6 @@ github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/infobloxopen/infoblox-go-client/v2 v2.0.0 h1:SoGI4PkU2zxGU2SCtpZA7rhd2GyNPsVuE1Ydno6B0Y8= -github.com/infobloxopen/infoblox-go-client/v2 v2.0.0/go.mod h1:+lznx4ASBSUZ2i6qwlgyn0v3eKDxBHNU5aRJzghAFbw= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= diff --git a/pkg/controller/provider/infoblox/access.go b/pkg/controller/provider/infoblox/access.go index 1480c7381..872dfece0 100644 --- a/pkg/controller/provider/infoblox/access.go +++ b/pkg/controller/provider/infoblox/access.go @@ -18,10 +18,8 @@ package infoblox import ( - "bytes" "encoding/json" "fmt" - "net/http" "strconv" "strings" @@ -34,17 +32,19 @@ import ( type access struct { ibclient.IBConnector - metrics provider.Metrics - view string + requestBuilder ibclient.HttpRequestBuilder + metrics provider.Metrics + view string } var _ raw.Executor = (*access)(nil) -func NewAccess(client ibclient.IBConnector, view string, metrics provider.Metrics) *access { +func NewAccess(client ibclient.IBConnector, requestBuilder ibclient.HttpRequestBuilder, view string, metrics provider.Metrics) *access { return &access{ - IBConnector: client, - metrics: metrics, - view: view, + IBConnector: client, + requestBuilder: requestBuilder, + metrics: metrics, + view: view, } } @@ -90,11 +90,11 @@ func (this *access) NewRecord(fqdn string, rtype string, value string, zone prov if n, err := strconv.Unquote(value); err == nil && !strings.Contains(value, " ") { value = n } - record = (*RecordTXT)(ibclient.NewRecordTXT(ibclient.RecordTXT{ - Name: fqdn, - Text: value, - View: this.view, - })) + r := ibclient.NewEmptyRecordTXT() + r.Name = fqdn + r.Text = value + r.View = this.view + record = (*RecordTXT)(r) } if record != nil { record.SetTTL(int(ttl)) @@ -104,27 +104,21 @@ func (this *access) NewRecord(fqdn string, rtype string, value string, zone prov func (this *access) GetRecordSet(dnsName, rtype string, zone provider.DNSHostedZone) (raw.RecordSet, error) { this.metrics.AddZoneRequests(zone.Id().ID, provider.M_LISTRECORDS, 1) - c := this.IBConnector.(*ibclient.Connector) if rtype != dns.RS_TXT { return nil, fmt.Errorf("record type %s not supported for GetRecord", rtype) } execRequest := func(forceProxy bool) ([]byte, error) { - rt := ibclient.NewRecordTXT(ibclient.RecordTXT{}) - urlStr := c.RequestBuilder.BuildUrl(ibclient.GET, rt.ObjectType(), "", rt.ReturnFields(), &ibclient.QueryParams{}) - urlStr += "&name=" + dnsName - if forceProxy { - urlStr += "&_proxy_search=GM" - } - req, err := http.NewRequest("GET", urlStr, new(bytes.Buffer)) + rt := ibclient.NewEmptyRecordTXT() + queryParams := ibclient.NewQueryParams(forceProxy, map[string]string{"name": dnsName, "view": this.view, "zone": zone.Key()}) + req, err := this.requestBuilder.BuildRequest(ibclient.GET, rt, "", queryParams) if err != nil { return nil, err } - req.Header.Set("Content-Type", "application/json") - req.SetBasicAuth(c.HostConfig.Username, c.HostConfig.Password) - return c.Requestor.SendRequest(req) + requestor := &ibclient.WapiHttpRequestor{} + return requestor.SendRequest(req) } resp, err := execRequest(false) diff --git a/pkg/controller/provider/infoblox/handler.go b/pkg/controller/provider/infoblox/handler.go index d83508f7a..58d35539c 100644 --- a/pkg/controller/provider/infoblox/handler.go +++ b/pkg/controller/provider/infoblox/handler.go @@ -19,11 +19,10 @@ package infoblox import ( "context" + "crypto/x509" "encoding/json" "fmt" - "io/ioutil" "net/url" - "os" "strconv" "github.com/gardener/controller-manager-library/pkg/logger" @@ -115,9 +114,12 @@ func NewHandler(config *provider.DNSHandlerConfig) (provider.DNSHandler, error) config.Logger.Infof("creating infoblox handler for %s", *infobloxConfig.Host) hostConfig := ibclient.HostConfig{ - Host: *infobloxConfig.Host, - Port: strconv.Itoa(*infobloxConfig.Port), - Version: *infobloxConfig.Version, + Host: *infobloxConfig.Host, + Port: strconv.Itoa(*infobloxConfig.Port), + Version: *infobloxConfig.Version, + } + + authCfg := ibclient.AuthConfig{ Username: username, Password: password, } @@ -127,25 +129,17 @@ func NewHandler(config *provider.DNSHandlerConfig) (provider.DNSHandler, error) verify = strconv.FormatBool(*infobloxConfig.SSLVerify) } - if infobloxConfig.CaCert != nil && verify == "true" { - tmpfile, err := ioutil.TempFile("", "cacert") - if err != nil { - return nil, fmt.Errorf("cannot create temporary file for cacert: %w", err) - } - defer os.Remove(tmpfile.Name()) - if _, err := tmpfile.Write([]byte(*infobloxConfig.CaCert)); err != nil { - return nil, fmt.Errorf("cannot write temporary file for cacert: %w", err) - } - if err := tmpfile.Close(); err != nil { - return nil, fmt.Errorf("cannot close temporary file for cacert: %w", err) - } - verify = tmpfile.Name() - } transportConfig := ibclient.NewTransportConfig( verify, *infobloxConfig.RequestTimeout, *infobloxConfig.PoolConnections, ) + if infobloxConfig.CaCert != nil && verify == "true" { + transportConfig.CertPool, err = h.createCertPool([]byte(*infobloxConfig.CaCert)) + if err != nil { + return nil, fmt.Errorf("cannot create cert pool for cacert: %w", err) + } + } if infobloxConfig.ProxyURL != nil && *infobloxConfig.ProxyURL != "" { u, err := url.Parse(*infobloxConfig.ProxyURL) if err != nil { @@ -154,17 +148,21 @@ func NewHandler(config *provider.DNSHandlerConfig) (provider.DNSHandler, error) transportConfig.ProxyUrl = u } - var requestBuilder ibclient.HttpRequestBuilder = &ibclient.WapiRequestBuilder{} + rb, err := ibclient.NewWapiRequestBuilder(hostConfig, authCfg) + if err != nil { + return nil, err + } + var requestBuilder ibclient.HttpRequestBuilder = rb if infobloxConfig.MaxResults != 0 { // wrap request builder which sets _max_results parameter on GET requests requestBuilder = NewMaxResultsRequestBuilder(infobloxConfig.MaxResults, requestBuilder) } - client, err := ibclient.NewConnector(hostConfig, transportConfig, requestBuilder, &ibclient.WapiHttpRequestor{}) + client, err := ibclient.NewConnector(hostConfig, authCfg, transportConfig, requestBuilder, &ibclient.WapiHttpRequestor{}) if err != nil { return nil, err } - h.access = NewAccess(client, *h.infobloxConfig.View, config.Metrics) + h.access = NewAccess(client, requestBuilder, *h.infobloxConfig.View, config.Metrics) h.ZoneCache, err = config.ZoneCacheFactory.CreateZoneCache(provider.CacheZonesOnly, config.Metrics, h.getZones, h.getZoneState) if err != nil { @@ -182,7 +180,7 @@ func (h *Handler) getZones(cache provider.ZoneCache) (provider.DNSHostedZones, e h.config.Metrics.AddGenericRequests(provider.M_LISTZONES, 1) obj := ibclient.NewZoneAuth(ibclient.ZoneAuth{}) err := h.access.GetObject(obj, "", &ibclient.QueryParams{}, &raw) - if err != nil { + if filterNotFound(err) != nil { return nil, err } @@ -196,14 +194,10 @@ func (h *Handler) getZones(cache provider.ZoneCache) (provider.DNSHostedZones, e h.config.Metrics.AddZoneRequests(z.Ref, provider.M_LISTRECORDS, 1) var resN []RecordNS - objN := ibclient.NewRecordNS( - ibclient.RecordNS{ - Zone: z.Fqdn, - View: *h.infobloxConfig.View, - }, - ) - err = h.access.GetObject(objN, "", &ibclient.QueryParams{}, &resN) - if err != nil { + objN := ibclient.NewRecordNS(ibclient.RecordNS{}) + params := ibclient.NewQueryParams(false, map[string]string{"view": *h.infobloxConfig.View, "zone": z.Fqdn}) + err = h.access.GetObject(objN, "", params, &resN) + if filterNotFound(err) != nil { return nil, fmt.Errorf("could not fetch NS records from zone '%s': %s", z.Fqdn, err) } forwarded := []string{} @@ -222,13 +216,12 @@ func (h *Handler) getZoneState(zone provider.DNSHostedZone, cache provider.ZoneC state := raw.NewState() rt := provider.M_LISTRECORDS + params := ibclient.NewQueryParams(false, map[string]string{"view": *h.infobloxConfig.View, "zone": zone.Key()}) + h.config.Metrics.AddZoneRequests(zone.Id().ID, rt, 1) var resA []RecordA - objA := ibclient.NewEmptyRecordA() - objA.Zone = zone.Key() - objA.View = *h.infobloxConfig.View - err := h.access.GetObject(objA, "", &ibclient.QueryParams{}, &resA) - if err != nil { + err := h.access.GetObject(ibclient.NewEmptyRecordA(), "", params, &resA) + if filterNotFound(err) != nil { return nil, fmt.Errorf("could not fetch A records from zone '%s': %s", zone.Key(), err) } for _, res := range resA { @@ -237,11 +230,8 @@ func (h *Handler) getZoneState(zone provider.DNSHostedZone, cache provider.ZoneC h.config.Metrics.AddZoneRequests(zone.Id().ID, rt, 1) var resAAAA []RecordAAAA - objAAAA := ibclient.NewEmptyRecordAAAA() - objAAAA.Zone = zone.Key() - objAAAA.View = *h.infobloxConfig.View - err = h.access.GetObject(objAAAA, "", &ibclient.QueryParams{}, &resAAAA) - if err != nil { + err = h.access.GetObject(ibclient.NewEmptyRecordAAAA(), "", params, &resAAAA) + if filterNotFound(err) != nil { return nil, fmt.Errorf("could not fetch AAAA records from zone '%s': %s", zone.Key(), err) } for _, res := range resAAAA { @@ -250,11 +240,8 @@ func (h *Handler) getZoneState(zone provider.DNSHostedZone, cache provider.ZoneC h.config.Metrics.AddZoneRequests(zone.Id().ID, rt, 1) var resC []RecordCNAME - objC := ibclient.NewEmptyRecordCNAME() - objC.Zone = zone.Key() - objC.View = *h.infobloxConfig.View - err = h.access.GetObject(objC, "", &ibclient.QueryParams{}, &resC) - if err != nil { + err = h.access.GetObject(ibclient.NewEmptyRecordCNAME(), "", params, &resC) + if filterNotFound(err) != nil { return nil, fmt.Errorf("could not fetch CNAME records from zone '%s': %s", zone.Key(), err) } for _, res := range resC { @@ -263,14 +250,8 @@ func (h *Handler) getZoneState(zone provider.DNSHostedZone, cache provider.ZoneC h.config.Metrics.AddZoneRequests(zone.Id().ID, rt, 1) var resT []RecordTXT - objT := ibclient.NewRecordTXT( - ibclient.RecordTXT{ - Zone: zone.Key(), - View: *h.infobloxConfig.View, - }, - ) - err = h.access.GetObject(objT, "", &ibclient.QueryParams{}, &resT) - if err != nil { + err = h.access.GetObject(ibclient.NewEmptyRecordTXT(), "", params, &resT) + if filterNotFound(err) != nil { return nil, fmt.Errorf("could not fetch TXT records from zone '%s': %s", zone.Key(), err) } for _, res := range resT { @@ -325,3 +306,21 @@ func (h *Handler) DeleteRecordSet(logger logger.LogContext, zone provider.DNSHos } return nil } + +func (h *Handler) createCertPool(cert []byte) (*x509.CertPool, error) { + caPool := x509.NewCertPool() + if !caPool.AppendCertsFromPEM(cert) { + return nil, fmt.Errorf("cannot append certificate") + } + return caPool, nil +} + +func filterNotFound(err error) error { + if err == nil { + return nil + } + if _, ok := err.(*ibclient.NotFoundError); ok { + return nil + } + return err +} diff --git a/pkg/controller/provider/infoblox/state.go b/pkg/controller/provider/infoblox/state.go index ebedb830d..725988244 100644 --- a/pkg/controller/provider/infoblox/state.go +++ b/pkg/controller/provider/infoblox/state.go @@ -85,7 +85,7 @@ func (r *RecordTXT) GetDNSName() string { return r.Name } func (r *RecordTXT) GetSetIdentifier() string { return "" } func (r *RecordTXT) GetValue() string { return raw.EnsureQuotedText(r.Text) } func (r *RecordTXT) GetTTL() int { return int(r.Ttl) } -func (r *RecordTXT) SetTTL(ttl int) { r.Ttl = uint(ttl); r.UseTtl = ttl != 0 } +func (r *RecordTXT) SetTTL(ttl int) { r.Ttl = uint32(ttl); r.UseTtl = ttl != 0 } func (r *RecordTXT) Copy() raw.Record { n := *r; return &n } func (r *RecordTXT) PrepareUpdate() raw.Record { n := *r; n.Zone = ""; n.View = ""; return &n } diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/v2/CHANGELOG.rst b/vendor/github.com/infobloxopen/infoblox-go-client/v2/CHANGELOG.rst new file mode 100644 index 000000000..488db85b3 --- /dev/null +++ b/vendor/github.com/infobloxopen/infoblox-go-client/v2/CHANGELOG.rst @@ -0,0 +1,61 @@ +=================================== +Infoblox Go Client Release Notes +=================================== + +.. contents:: Topics + +v2.1.1 +====== + +This is just a bugfix release. + +v2.1.0 +====== + +Release Summary +--------------- + +- Enhancements in Host Record functionality +- Code refinements + +Minor Changes +------------- + +- `SearchHostRecordByAltId` function to search Host Record By alternative ID from terraform. +- The code for every record has been seperated and added under a new file. + + +v2.0.0 +====== + +Release Summary +--------------- + +Create, Update, Delete and Get operation on below records are being added or enhanced. + +- Network View with comment and EAs +- IPv4 and IPv6 network containers with comment and EAs +- IPv4 and IPv6 network with comment and EAs +- Host Record with comment, EAs, EnableDns, EnableDhcp, UseTtl, Ttl, Alias attributes +- Fixed Address record with comment and EAs +- A record with comment, EAs, UseTtl, Ttl +- AAAA record with comment, EAs, UseTtl, Ttl +- PTR record with comment, EAs, UseTtl, Ttl +- Added IPv6 support for PTR record +- CNAME record with comment, EAs, UseTtl, Ttl +- Adds a compile-time check to the interface to make sure it stays in sync with the actual implementation. +- Added apt UTs and updated respective UTs + +Minor Changes +------------- + +- Added default value of network view in AllocateIP, CreateHostRecord and CreatePTRRecord Function + +Bugfixes +------------- + +- IPv6 Support `#86 `_ +- Possibility to UPDATE a CNAME entry `#110 `_ +- Feature Request: Ability to add comments `#116 `_ +- Feature: Add ability to set extensible attributes when creating a network `#119 `_ +- Feature request: add host aliases get/create/update `#126 `_ diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/v2/README.md b/vendor/github.com/infobloxopen/infoblox-go-client/v2/README.md index fd36798a1..3f2268004 100644 --- a/vendor/github.com/infobloxopen/infoblox-go-client/v2/README.md +++ b/vendor/github.com/infobloxopen/infoblox-go-client/v2/README.md @@ -10,19 +10,23 @@ This library is compatible with Go 1.2+ - [Usage](#Usage) ## Build Status +[![Build Status](https://travis-ci.org/infobloxopen/infoblox-go-client.svg?branch=master)](https://travis-ci.org/infobloxopen/infoblox-go-client) -| Master | Develop | -| ----------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [![Build Status](https://travis-ci.org/infobloxopen/infoblox-go-client.svg?branch=master)](https://travis-ci.org/infobloxopen/infoblox-go-client) | [![Build Status](https://travis-ci.org/infobloxopen/infoblox-go-client.svg?branch=develop)](https://travis-ci.org/infobloxopen/infoblox-go-client) | - -The newly developed features will be available under `develop` branch. After validation they would be merged to `master`. ## Prerequisites * Infoblox GRID with 2.5 or above WAPI support * Go 1.2 or above ## Installation - go get github.com/infobloxopen/infoblox-go-client + To get the latest released version [v2.1.0](https://github.com/infobloxopen/infoblox-go-client/releases/tag/v2.1.0) of Go Client use below command. + + `go get github.com/infobloxopen/infoblox-go-client/v2` + + To get the previous major version [v1.1.1](https://github.com/infobloxopen/infoblox-go-client/releases/tag/v1.1.1) use below command. + + `go get github.com/infobloxopen/infoblox-go-client` + + Note: Go client version v2.0.0 and above have breaking changes and are not backward compatible. ## Usage @@ -59,6 +63,7 @@ The newly developed features will be available under `develop` branch. After val * AllocateIP * AllocateNetwork + * AllocateNetworkContainer * CreateARecord * CreateAAAARecord * CreateZoneAuth @@ -96,6 +101,7 @@ The newly developed features will be available under `develop` branch. After val * GetFixedAddressByRef * GetHostRecord * GetHostRecordByRef + * SearchHostRecordByAltId * GetIpAddressFromHostRecord * GetNetwork * GetNetworkByRef @@ -105,6 +111,8 @@ The newly developed features will be available under `develop` branch. After val * GetNetworkViewByRef * GetPTRRecordByRef * GetPTRRecord + * GetTXTRecord + * GetTXTRecordByRef * GetZoneAuthByRef * GetZoneDelegated * GetUpgradeStatus (2.7 or above) @@ -120,6 +128,7 @@ The newly developed features will be available under `develop` branch. After val * UpdateNetworkContainer * UpdateNetworkView * UpdatePTRRecord + * UpdateTXTRecord * UpdateARecord * UpdateZoneDelegated diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/v2/connector.go b/vendor/github.com/infobloxopen/infoblox-go-client/v2/connector.go index 19f1d9c14..8ed0862c2 100644 --- a/vendor/github.com/infobloxopen/infoblox-go-client/v2/connector.go +++ b/vendor/github.com/infobloxopen/infoblox-go-client/v2/connector.go @@ -19,17 +19,23 @@ import ( "golang.org/x/net/publicsuffix" ) -type HostConfig struct { - Host string - Version string - Port string +type AuthConfig struct { Username string Password string + + ClientCert []byte + ClientKey []byte +} + +type HostConfig struct { + Host string + Version string + Port string } type TransportConfig struct { SslVerify bool - certPool *x509.CertPool + CertPool *x509.CertPool HttpRequestTimeout time.Duration // in seconds HttpPoolConnections int ProxyUrl *url.URL @@ -49,32 +55,34 @@ func NewTransportConfig(sslVerify string, httpRequestTimeout int, httpPoolConnec return } if !caPool.AppendCertsFromPEM(cert) { - err = fmt.Errorf("Cannot append certificate from file '%s'", sslVerify) + err = fmt.Errorf("cannot append certificate from file '%s'", sslVerify) return } - cfg.certPool = caPool + cfg.CertPool = caPool cfg.SslVerify = true } cfg.HttpPoolConnections = httpPoolConnections cfg.HttpRequestTimeout = time.Duration(httpRequestTimeout) + return } type HttpRequestBuilder interface { - Init(HostConfig) + Init(HostConfig, AuthConfig) BuildUrl(r RequestType, objType string, ref string, returnFields []string, queryParams *QueryParams) (urlStr string) BuildBody(r RequestType, obj IBObject) (jsonStr []byte) BuildRequest(r RequestType, obj IBObject, ref string, queryParams *QueryParams) (req *http.Request, err error) } type HttpRequestor interface { - Init(TransportConfig) + Init(AuthConfig, TransportConfig) SendRequest(*http.Request) ([]byte, error) } type WapiRequestBuilder struct { - HostConfig HostConfig + hostCfg HostConfig + authCfg AuthConfig } type WapiHttpRequestor struct { @@ -89,10 +97,11 @@ type IBConnector interface { } type Connector struct { - HostConfig HostConfig - TransportConfig TransportConfig - RequestBuilder HttpRequestBuilder - Requestor HttpRequestor + hostCfg HostConfig + authCfg AuthConfig + transportCfg TransportConfig + requestBuilder HttpRequestBuilder + requestor HttpRequestor } type RequestType int @@ -123,21 +132,41 @@ func getHTTPResponseError(resp *http.Response) error { defer resp.Body.Close() content, _ := ioutil.ReadAll(resp.Body) msg := fmt.Sprintf("WAPI request error: %d('%s')\nContents:\n%s\n", resp.StatusCode, resp.Status, content) - log.Printf(msg) + if resp.StatusCode == http.StatusNotFound { + return NewNotFoundError(msg) + } return errors.New(msg) } -func (whr *WapiHttpRequestor) Init(cfg TransportConfig) { +func (whr *WapiHttpRequestor) Init(authCfg AuthConfig, trCfg TransportConfig) { + var certList []tls.Certificate + + clientAuthType := tls.NoClientCert + + if authCfg.ClientKey != nil && authCfg.ClientCert != nil { + cert, err := tls.X509KeyPair(authCfg.ClientCert, authCfg.ClientKey) + if err != nil { + log.Fatal("Invalid certificate key pair (PEM format error): ", err) + } + + certList = []tls.Certificate{cert} + clientAuthType = tls.RequestClientCert + } + tr := &http.Transport{ - TLSClientConfig: &tls.Config{InsecureSkipVerify: !cfg.SslVerify, - RootCAs: cfg.certPool, - Renegotiation: tls.RenegotiateOnceAsClient}, - MaxIdleConnsPerHost: cfg.HttpPoolConnections, - Proxy: http.ProxyFromEnvironment, + TLSClientConfig: &tls.Config{ + RootCAs: trCfg.CertPool, + ClientAuth: clientAuthType, + Certificates: certList, + InsecureSkipVerify: !trCfg.SslVerify, + Renegotiation: tls.RenegotiateOnceAsClient, + }, + MaxIdleConnsPerHost: trCfg.HttpPoolConnections, + Proxy: http.ProxyFromEnvironment, } - if cfg.ProxyUrl != nil { - tr.Proxy = http.ProxyURL(cfg.ProxyUrl) + if trCfg.ProxyUrl != nil { + tr.Proxy = http.ProxyURL(trCfg.ProxyUrl) } // All users of cookiejar should import "golang.org/x/net/publicsuffix" @@ -146,7 +175,11 @@ func (whr *WapiHttpRequestor) Init(cfg TransportConfig) { log.Fatal(err) } - whr.client = http.Client{Jar: jar, Transport: tr, Timeout: cfg.HttpRequestTimeout * time.Second} + whr.client = http.Client{ + Jar: jar, + Transport: tr, + Timeout: trCfg.HttpRequestTimeout * time.Second, + } } func (whr *WapiHttpRequestor) SendRequest(req *http.Request) (res []byte, err error) { @@ -156,7 +189,7 @@ func (whr *WapiHttpRequestor) SendRequest(req *http.Request) (res []byte, err er return } else if !(resp.StatusCode == http.StatusOK || (resp.StatusCode == http.StatusCreated && - req.Method == RequestType(CREATE).toMethod())) { + req.Method == CREATE.toMethod())) { err := getHTTPResponseError(resp) return nil, err } @@ -170,12 +203,22 @@ func (whr *WapiHttpRequestor) SendRequest(req *http.Request) (res []byte, err er return } -func (wrb *WapiRequestBuilder) Init(cfg HostConfig) { - wrb.HostConfig = cfg +func NewWapiRequestBuilder(hostCfg HostConfig, authCfg AuthConfig) (*WapiRequestBuilder, error) { + wrb := WapiRequestBuilder{ + hostCfg: hostCfg, + authCfg: authCfg, + } + + return &wrb, nil +} + +func (wrb *WapiRequestBuilder) Init(hostCfg HostConfig, authCfg AuthConfig) { + wrb.hostCfg = hostCfg + wrb.authCfg = authCfg } func (wrb *WapiRequestBuilder) BuildUrl(t RequestType, objType string, ref string, returnFields []string, queryParams *QueryParams) (urlStr string) { - path := []string{"wapi", "v" + wrb.HostConfig.Version} + path := []string{"wapi", "v" + wrb.hostCfg.Version} if len(ref) > 0 { path = append(path, ref) } else { @@ -188,12 +231,14 @@ func (wrb *WapiRequestBuilder) BuildUrl(t RequestType, objType string, ref strin if len(returnFields) > 0 { vals.Set("_return_fields", strings.Join(returnFields, ",")) } - // TODO need to get this from individual objects in future - if queryParams.forceProxy { - vals.Set("_proxy_search", "GM") - } - for k, v := range queryParams.searchFields { - vals.Set(k, v) + if queryParams != nil { + // TODO need to get this from individual objects in future + if queryParams.forceProxy { + vals.Set("_proxy_search", "GM") + } + for k, v := range queryParams.searchFields { + vals.Set(k, v) + } } qry = vals.Encode() @@ -201,7 +246,7 @@ func (wrb *WapiRequestBuilder) BuildUrl(t RequestType, objType string, ref strin u := url.URL{ Scheme: "https", - Host: wrb.HostConfig.Host + ":" + wrb.HostConfig.Port, + Host: wrb.hostCfg.Host + ":" + wrb.hostCfg.Port, Path: strings.Join(path, "/"), RawQuery: qry, } @@ -250,24 +295,36 @@ func (wrb *WapiRequestBuilder) BuildRequest(t RequestType, obj IBObject, ref str req, err = http.NewRequest(t.toMethod(), urlStr, bytes.NewBuffer(bodyStr)) if err != nil { - log.Printf("err1: '%s'", err) + log.Printf("cannot build request: '%s'", err) return } req.Header.Set("Content-Type", "application/json") - req.SetBasicAuth(wrb.HostConfig.Username, wrb.HostConfig.Password) + if wrb.authCfg.Username != "" { + req.SetBasicAuth(wrb.authCfg.Username, wrb.authCfg.Password) + } return } func (c *Connector) makeRequest(t RequestType, obj IBObject, ref string, queryParams *QueryParams) (res []byte, err error) { var req *http.Request - req, err = c.RequestBuilder.BuildRequest(t, obj, ref, queryParams) - res, err = c.Requestor.SendRequest(req) + req, err = c.requestBuilder.BuildRequest(t, obj, ref, queryParams) if err != nil { - /* Forcing the request to redirect to Grid Master by making forcedProxy=true */ - queryParams.forceProxy = true - req, err = c.RequestBuilder.BuildRequest(t, obj, ref, queryParams) - res, err = c.Requestor.SendRequest(req) + return + } + res, err = c.requestor.SendRequest(req) + if err != nil { + if queryParams != nil { + /* Forcing the request to redirect to Grid Master by making forcedProxy=true */ + queryParams.forceProxy = true + req, err = c.requestBuilder.BuildRequest(t, obj, ref, queryParams) + if err != nil { + return + } + res, err = c.requestor.SendRequest(req) + } else { + return nil, err + } } return @@ -284,42 +341,50 @@ func (c *Connector) CreateObject(obj IBObject) (ref string, err error) { err = json.Unmarshal(resp, &ref) if err != nil { - log.Printf("Cannot unmarshall '%s', err: '%s'\n", string(resp), err) + log.Printf("cannot unmarshall '%s', err: '%s'\n", string(resp), err) return } return } -// TODO: distinguish between "not found" and other kinds of errors. func (c *Connector) GetObject( obj IBObject, ref string, queryParams *QueryParams, res interface{}) (err error) { resp, err := c.makeRequest(GET, obj, ref, queryParams) + if err != nil { + return + } //to check empty underlying value of interface var result interface{} err = json.Unmarshal(resp, &result) if err != nil { - log.Printf("Cannot unmarshall to check empty value '%s', err: '%s'\n", string(resp), err) + log.Printf("cannot unmarshall to check empty value '%s': '%s'\n", string(resp), err) } var data []interface{} if resp == nil || (reflect.TypeOf(result) == reflect.TypeOf(data) && len(result.([]interface{})) == 0) { + if queryParams == nil { + err = NewNotFoundError("requested object not found") + return + } queryParams.forceProxy = true resp, err = c.makeRequest(GET, obj, ref, queryParams) } if err != nil { log.Printf("GetObject request error: '%s'\n", err) } - if len(resp) == 0 { - return - } err = json.Unmarshal(resp, res) if err != nil { - log.Printf("Cannot unmarshall '%s', err: '%s'\n", string(resp), err) + log.Printf("cannot unmarshall '%s', err: '%s'\n", string(resp), err) return } + + if string(resp) == "[]" { + return NewNotFoundError("not found") + } + return } @@ -334,7 +399,7 @@ func (c *Connector) DeleteObject(ref string) (refRes string, err error) { err = json.Unmarshal(resp, &refRes) if err != nil { - log.Printf("Cannot unmarshall '%s', err: '%s'\n", string(resp), err) + log.Printf("cannot unmarshall '%s': '%s'\n", string(resp), err) return } @@ -346,13 +411,13 @@ func (c *Connector) UpdateObject(obj IBObject, ref string) (refRes string, err e refRes = "" resp, err := c.makeRequest(UPDATE, obj, ref, queryParams) if err != nil { - log.Printf("Failed to update object %s: %s", obj.ObjectType(), err) + log.Printf("failed to update object %s: %s", obj.ObjectType(), err) return } err = json.Unmarshal(resp, &refRes) if err != nil { - log.Printf("Cannot unmarshall update object response'%s', err: '%s'\n", string(resp), err) + log.Printf("cannot unmarshall update object response'%s', err: '%s'\n", string(resp), err) return } return @@ -385,21 +450,22 @@ func validateConnector(c *Connector) (err error) { return } -func NewConnector(hostConfig HostConfig, transportConfig TransportConfig, +func NewConnector(hostConfig HostConfig, authCfg AuthConfig, transportConfig TransportConfig, requestBuilder HttpRequestBuilder, requestor HttpRequestor) (res *Connector, err error) { res = nil connector := &Connector{ - HostConfig: hostConfig, - TransportConfig: transportConfig, + hostCfg: hostConfig, + authCfg: authCfg, + transportCfg: transportConfig, } - //connector.RequestBuilder = WapiRequestBuilder{WaipHostConfig: connector.HostConfig} - connector.RequestBuilder = requestBuilder - connector.RequestBuilder.Init(connector.HostConfig) + //connector.requestBuilder = WapiRequestBuilder{WaipHostConfig: connector.hostCfg} + connector.requestBuilder = requestBuilder + connector.requestBuilder.Init(connector.hostCfg, connector.authCfg) - connector.Requestor = requestor - connector.Requestor.Init(connector.TransportConfig) + connector.requestor = requestor + connector.requestor.Init(connector.authCfg, connector.transportCfg) res = connector err = ValidateConnector(connector) diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager.go b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager.go index 636725796..7afdb193a 100644 --- a/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager.go +++ b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager.go @@ -4,18 +4,16 @@ import ( "encoding/json" "errors" "fmt" - "net" - "net/url" - "regexp" - "strings" ) // Compile-time interface checks var _ IBObjectManager = new(ObjectManager) type IBObjectManager interface { + GetDNSView(name string) (*DNSView, error) AllocateIP(netview string, cidr string, ipAddr string, isIPv6 bool, macOrDuid string, name string, comment string, eas EA) (*FixedAddress, error) AllocateNetwork(netview string, cidr string, isIPv6 bool, prefixLen uint, comment string, eas EA) (network *Network, err error) + AllocateNetworkContainer(netview string, cidr string, isIPv6 bool, prefixLen uint, comment string, eas EA) (netContainer *NetworkContainer, err error) CreateARecord(netView string, dnsView string, name string, cidr string, ipAddr string, ttl uint32, useTTL bool, comment string, ea EA) (*RecordA, error) CreateAAAARecord(netView string, dnsView string, recordName string, cidr string, ipAddr string, useTtl bool, ttl uint32, comment string, eas EA) (*RecordAAAA, error) CreateZoneAuth(fqdn string, ea EA) (*ZoneAuth, error) @@ -27,7 +25,7 @@ type IBObjectManager interface { CreateNetworkContainer(netview string, cidr string, isIPv6 bool, comment string, eas EA) (*NetworkContainer, error) CreateNetworkView(name string, comment string, setEas EA) (*NetworkView, error) CreatePTRRecord(networkView string, dnsView string, ptrdname string, recordName string, cidr string, ipAddr string, useTtl bool, ttl uint32, comment string, eas EA) (*RecordPTR, error) - CreateTXTRecord(recordname string, text string, ttl uint, dnsview string) (*RecordTXT, error) + CreateTXTRecord(dnsView string, recordName string, text string, ttl uint32, useTtl bool, comment string, eas EA) (*RecordTXT, error) CreateZoneDelegated(fqdn string, delegate_to []NameServer) (*ZoneDelegated, error) DeleteARecord(ref string) (string, error) DeleteAAAARecord(ref string) (string, error) @@ -51,6 +49,7 @@ type IBObjectManager interface { GetFixedAddress(netview string, cidr string, ipAddr string, isIPv6 bool, macOrDuid string) (*FixedAddress, error) GetFixedAddressByRef(ref string) (*FixedAddress, error) GetHostRecord(netview string, dnsview string, recordName string, ipv4addr string, ipv6addr string) (*HostRecord, error) + SearchHostRecordByAltId(internalId string, ref string, eaNameForInternalId string) (*HostRecord, error) GetHostRecordByRef(ref string) (*HostRecord, error) GetIpAddressFromHostRecord(host HostRecord) (string, error) GetNetwork(netview string, cidr string, isIPv6 bool, ea EA) (*Network, error) @@ -61,6 +60,8 @@ type IBObjectManager interface { GetNetworkViewByRef(ref string) (*NetworkView, error) GetPTRRecord(dnsview string, ptrdname string, recordName string, ipAddr string) (*RecordPTR, error) GetPTRRecordByRef(ref string) (*RecordPTR, error) + GetTXTRecord(dnsview string, name string) (*RecordTXT, error) + GetTXTRecordByRef(ref string) (*RecordTXT, error) GetZoneAuthByRef(ref string) (*ZoneAuth, error) GetZoneDelegated(fqdn string) (*ZoneDelegated, error) GetCapacityReport(name string) ([]CapacityReport, error) @@ -72,27 +73,16 @@ type IBObjectManager interface { UpdateAAAARecord(ref string, netView string, recordName string, cidr string, ipAddr string, useTtl bool, ttl uint32, comment string, setEas EA) (*RecordAAAA, error) UpdateCNAMERecord(ref string, canonical string, recordName string, useTtl bool, ttl uint32, comment string, setEas EA) (*RecordCNAME, error) UpdateFixedAddress(fixedAddrRef string, netview string, name string, cidr string, ipAddr string, matchclient string, macOrDuid string, comment string, eas EA) (*FixedAddress, error) - UpdateHostRecord(hostRref string, enabledns bool, enabledhcp bool, name string, netview string, ipv4cidr string, ipv6cidr string, ipv4Addr string, ipv6Addr string, macAddress string, duid string, useTtl bool, ttl uint32, comment string, eas EA, aliases []string) (*HostRecord, error) + UpdateHostRecord(hostRref string, enabledns bool, enabledhcp bool, name string, netview string, dnsView string, ipv4cidr string, ipv6cidr string, ipv4Addr string, ipv6Addr string, macAddress string, duid string, useTtl bool, ttl uint32, comment string, eas EA, aliases []string) (*HostRecord, error) UpdateNetwork(ref string, setEas EA, comment string) (*Network, error) UpdateNetworkContainer(ref string, setEas EA, comment string) (*NetworkContainer, error) UpdateNetworkView(ref string, name string, comment string, setEas EA) (*NetworkView, error) UpdatePTRRecord(ref string, netview string, ptrdname string, name string, cidr string, ipAddr string, useTtl bool, ttl uint32, comment string, setEas EA) (*RecordPTR, error) + UpdateTXTRecord(ref string, recordName string, text string, ttl uint32, useTtl bool, comment string, eas EA) (*RecordTXT, error) UpdateARecord(ref string, name string, ipAddr string, cidr string, netview string, ttl uint32, useTTL bool, comment string, eas EA) (*RecordA, error) UpdateZoneDelegated(ref string, delegate_to []NameServer) (*ZoneDelegated, error) } -type NotFoundError struct { - msg string -} - -func (e *NotFoundError) Error() string { - return "not found" -} - -func NewNotFoundError(msg string) *NotFoundError { - return &NotFoundError{msg: msg} -} - type ObjectManager struct { connector IBConnector cmpType string @@ -109,1383 +99,6 @@ func NewObjectManager(connector IBConnector, cmpType string, tenantID string) IB return objMgr } -func (objMgr *ObjectManager) CreateNetworkView(name string, comment string, setEas EA) (*NetworkView, error) { - networkView := NewNetworkView(name, comment, setEas, "") - - ref, err := objMgr.connector.CreateObject(networkView) - networkView.Ref = ref - - return networkView, err -} - -func (objMgr *ObjectManager) makeNetworkView(netviewName string) (netviewRef string, err error) { - var netviewObj *NetworkView - if netviewObj, err = objMgr.GetNetworkView(netviewName); err != nil { - return - } - if netviewObj == nil { - if netviewObj, err = objMgr.CreateNetworkView(netviewName, "", nil); err != nil { - return - } - } - - netviewRef = netviewObj.Ref - - return -} - -func (objMgr *ObjectManager) CreateDefaultNetviews(globalNetview string, localNetview string) (globalNetviewRef string, localNetviewRef string, err error) { - if globalNetviewRef, err = objMgr.makeNetworkView(globalNetview); err != nil { - return - } - - if localNetviewRef, err = objMgr.makeNetworkView(localNetview); err != nil { - return - } - - return -} - -func (objMgr *ObjectManager) CreateNetwork(netview string, cidr string, isIPv6 bool, comment string, eas EA) (*Network, error) { - network := NewNetwork(netview, cidr, isIPv6, comment, eas) - - ref, err := objMgr.connector.CreateObject(network) - if err != nil { - return nil, err - } - network.Ref = ref - - return network, err -} - -func (objMgr *ObjectManager) CreateNetworkContainer(netview string, cidr string, isIPv6 bool, comment string, eas EA) (*NetworkContainer, error) { - container := NewNetworkContainer(netview, cidr, isIPv6, comment, eas) - - ref, err := objMgr.connector.CreateObject(container) - if err != nil { - return nil, err - } - - container.Ref = ref - return container, nil -} - -func (objMgr *ObjectManager) GetNetworkView(name string) (*NetworkView, error) { - var res []NetworkView - - netview := NewEmptyNetworkView() - sf := map[string]string{ - "name": name, - } - queryParams := NewQueryParams(false, sf) - err := objMgr.connector.GetObject(netview, "", queryParams, &res) - - if err != nil { - return nil, err - } - if res == nil || len(res) == 0 { - return nil, fmt.Errorf("network view '%s' not found", name) - } - - return &res[0], nil -} - -func (objMgr *ObjectManager) GetNetworkViewByRef(ref string) (*NetworkView, error) { - res := NewEmptyNetworkView() - queryParams := NewQueryParams(false, nil) - if err := objMgr.connector.GetObject(res, ref, queryParams, &res); err != nil { - return nil, err - } - if res == nil { - return nil, fmt.Errorf("network view not found") - } - - return res, nil -} - -func (objMgr *ObjectManager) UpdateNetworkView(ref string, name string, comment string, setEas EA) (*NetworkView, error) { - - nv := NewEmptyNetworkView() - - err := objMgr.connector.GetObject( - nv, ref, NewQueryParams(false, nil), nv) - if err != nil { - return nil, err - } - cleanName := strings.TrimSpace(name) - if cleanName != "" { - nv.Name = cleanName - } - nv.Comment = comment - nv.Ea = setEas - - updatedRef, err := objMgr.connector.UpdateObject(nv, ref) - nv.Ref = updatedRef - - return nv, err -} - -func BuildNetworkViewFromRef(ref string) *NetworkView { - // networkview/ZG5zLm5ldHdvcmtfdmlldyQyMw:global_view/false - r := regexp.MustCompile(`networkview/\w+:([^/]+)/\w+`) - m := r.FindStringSubmatch(ref) - - if m == nil { - return nil - } - - return &NetworkView{ - Ref: ref, - Name: m[1], - } -} - -func BuildNetworkFromRef(ref string) (*Network, error) { - // network/ZG5zLm5ldHdvcmskODkuMC4wLjAvMjQvMjU:89.0.0.0/24/global_view - r := regexp.MustCompile(`network/\w+:(\d+\.\d+\.\d+\.\d+/\d+)/(.+)`) - m := r.FindStringSubmatch(ref) - - if m == nil { - return nil, fmt.Errorf("CIDR format not matched") - } - - newNet := NewNetwork(m[2], m[1], false, "", nil) - newNet.Ref = ref - return newNet, nil -} - -func (objMgr *ObjectManager) GetNetwork(netview string, cidr string, isIPv6 bool, ea EA) (*Network, error) { - if netview != "" && cidr != "" { - var res []Network - - network := NewNetwork(netview, cidr, isIPv6, "", ea) - - network.Cidr = cidr - - if ea != nil && len(ea) > 0 { - network.eaSearch = EASearch(ea) - } - - sf := map[string]string{ - "network_view": netview, - "network": cidr, - } - queryParams := NewQueryParams(false, sf) - err := objMgr.connector.GetObject(network, "", queryParams, &res) - - if err != nil { - return nil, err - } else if res == nil || len(res) == 0 { - return nil, NewNotFoundError( - fmt.Sprintf( - "Network with cidr: %s in network view: %s is not found.", - cidr, netview)) - } - - return &res[0], nil - } else { - err := fmt.Errorf("both network view and cidr values are required") - return nil, err - } -} - -func (objMgr *ObjectManager) GetNetworkByRef(ref string) (*Network, error) { - r := regexp.MustCompile("^ipv6network\\/.+") - isIPv6 := r.MatchString(ref) - - network := NewNetwork("", "", isIPv6, "", nil) - err := objMgr.connector.GetObject(network, ref, NewQueryParams(false, nil), network) - return network, err -} - -// TODO normalize IPv4 and IPv6 addresses -func (objMgr *ObjectManager) GetNetworkContainer(netview string, cidr string, isIPv6 bool, eaSearch EA) (*NetworkContainer, error) { - var res []NetworkContainer - - nc := NewNetworkContainer(netview, cidr, isIPv6, "", nil) - nc.eaSearch = EASearch(eaSearch) - sf := map[string]string{ - "network_view": netview, - "network": cidr, - } - queryParams := NewQueryParams(false, sf) - err := objMgr.connector.GetObject(nc, "", queryParams, &res) - if err != nil { - return nil, err - } else if res == nil || len(res) == 0 { - return nil, NewNotFoundError("network container not found") - } - - return &res[0], nil -} - -func (objMgr *ObjectManager) GetNetworkContainerByRef(ref string) (*NetworkContainer, error) { - nc := NewNetworkContainer("", "", false, "", nil) - - err := objMgr.connector.GetObject( - nc, ref, NewQueryParams(false, nil), nc) - if err != nil { - return nil, err - } - - return nc, nil -} - -func GetIPAddressFromRef(ref string) string { - // fixedaddress/ZG5zLmJpbmRfY25h:12.0.10.1/external - r := regexp.MustCompile(`fixedaddress/\w+:(\d+\.\d+\.\d+\.\d+)/.+`) - m := r.FindStringSubmatch(ref) - - if m != nil { - return m[1] - } - return "" -} - -func (objMgr *ObjectManager) AllocateIP( - netview string, - cidr string, - ipAddr string, - isIPv6 bool, - macOrDuid string, - name string, - comment string, - eas EA) (*FixedAddress, error) { - - if isIPv6 { - if len(macOrDuid) == 0 { - return nil, fmt.Errorf("the DUID field cannot be left empty") - } - } else { - if len(macOrDuid) == 0 { - macOrDuid = MACADDR_ZERO - } - } - if ipAddr == "" && cidr != "" { - if netview == "" { - netview = "default" - } - ipAddr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netview) - } - fixedAddr := NewFixedAddress( - netview, name, ipAddr, cidr, macOrDuid, "", eas, "", isIPv6, comment) - ref, err := objMgr.connector.CreateObject(fixedAddr) - if err != nil { - return nil, err - } - - fixedAddr.Ref = ref - fixedAddr, err = objMgr.GetFixedAddressByRef(ref) - - return fixedAddr, err -} - -func (objMgr *ObjectManager) AllocateNetwork( - netview string, - cidr string, - isIPv6 bool, - prefixLen uint, - comment string, - eas EA) (network *Network, err error) { - - network = nil - cidr = fmt.Sprintf("func:nextavailablenetwork:%s,%s,%d", cidr, netview, prefixLen) - networkReq := NewNetwork(netview, cidr, isIPv6, comment, eas) - - ref, err := objMgr.connector.CreateObject(networkReq) - if err == nil { - if isIPv6 { - network, err = BuildIPv6NetworkFromRef(ref) - } else { - network, err = BuildNetworkFromRef(ref) - } - } - - return -} - -func (objMgr *ObjectManager) GetFixedAddress(netview string, cidr string, ipAddr string, isIpv6 bool, macOrDuid string) (*FixedAddress, error) { - var res []FixedAddress - - fixedAddr := NewEmptyFixedAddress(isIpv6) - sf := map[string]string{ - "network_view": netview, - "network": cidr, - } - if isIpv6 { - sf["ipv6addr"] = ipAddr - if macOrDuid != "" { - sf["duid"] = macOrDuid - } - } else { - sf["ipv4addr"] = ipAddr - if macOrDuid != "" { - sf["mac"] = macOrDuid - } - } - - queryParams := NewQueryParams(false, sf) - err := objMgr.connector.GetObject(fixedAddr, "", queryParams, &res) - - if err != nil || res == nil || len(res) == 0 { - return nil, err - } - - return &res[0], nil -} - -func (objMgr *ObjectManager) GetFixedAddressByRef(ref string) (*FixedAddress, error) { - r := regexp.MustCompile("^ipv6fixedaddress/.+") - isIPv6 := r.MatchString(ref) - - fixedAddr := NewEmptyFixedAddress(isIPv6) - err := objMgr.connector.GetObject( - fixedAddr, ref, NewQueryParams(false, nil), &fixedAddr) - return fixedAddr, err -} - -func (objMgr *ObjectManager) DeleteFixedAddress(ref string) (string, error) { - return objMgr.connector.DeleteObject(ref) -} - -// validation for match_client -func validateMatchClient(value string) bool { - matchClientList := [5]string{ - "MAC_ADDRESS", - "CLIENT_ID", - "RESERVED", - "CIRCUIT_ID", - "REMOTE_ID"} - - for _, val := range matchClientList { - if val == value { - return true - } - } - return false -} - -func (objMgr *ObjectManager) UpdateFixedAddress( - fixedAddrRef string, - netview string, - name string, - cidr string, - ipAddr string, - matchClient string, - macOrDuid string, - comment string, - eas EA) (*FixedAddress, error) { - - r := regexp.MustCompile("^ipv6fixedaddress/.+") - isIPv6 := r.MatchString(fixedAddrRef) - if !isIPv6 { - if !validateMatchClient(matchClient) { - return nil, fmt.Errorf("wrong value for match_client passed %s \n ", matchClient) - } - } - updateFixedAddr := NewFixedAddress( - "", name, "", "", - macOrDuid, matchClient, eas, fixedAddrRef, isIPv6, comment) - - if ipAddr == "" { - if cidr != "" { - ipAddress, _, err := net.ParseCIDR(cidr) - if err != nil { - return nil, fmt.Errorf("cannot parse CIDR value: %s", err.Error()) - } - if netview == "" { - netview = "default" - } - if isIPv6 { - if ipAddress.To4() != nil || ipAddress.To16() == nil { - return nil, fmt.Errorf("CIDR value must be an IPv6 CIDR, not an IPv4 one") - } - updateFixedAddr.IPv6Address = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netview) - } else { - if ipAddress.To4() == nil { - return nil, fmt.Errorf("CIDR value must be an IPv4 CIDR, not an IPv6 one") - } - updateFixedAddr.IPv4Address = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netview) - } - } - } else { - ipAddress := net.ParseIP(ipAddr) - if ipAddress == nil { - return nil, fmt.Errorf("IP address for the record is not valid") - } - if isIPv6 { - if ipAddress.To4() != nil || ipAddress.To16() == nil { - return nil, fmt.Errorf("IP address must be an IPv6 address, not an IPv4 one") - } - updateFixedAddr.IPv6Address = ipAddr - } else { - if ipAddress.To4() == nil { - return nil, fmt.Errorf("IP address must be an IPv4 address, not an IPv6 one") - } - updateFixedAddr.IPv4Address = ipAddr - } - } - refResp, err := objMgr.connector.UpdateObject(updateFixedAddr, fixedAddrRef) - - updateFixedAddr, err = objMgr.GetFixedAddressByRef(refResp) - if err != nil { - return nil, err - } - return updateFixedAddr, nil -} - -func (objMgr *ObjectManager) ReleaseIP(netview string, cidr string, ipAddr string, isIpv6 bool, macOrDuid string) (string, error) { - fixAddress, _ := objMgr.GetFixedAddress(netview, cidr, ipAddr, isIpv6, macOrDuid) - if fixAddress == nil { - return "", nil - } - return objMgr.connector.DeleteObject(fixAddress.Ref) -} - -func (objMgr *ObjectManager) DeleteNetworkContainer(ref string) (string, error) { - ncRegExp := regexp.MustCompile("^(ipv6)?networkcontainer\\/.+") - if !ncRegExp.MatchString(ref) { - return "", fmt.Errorf("'ref' does not reference a network container") - } - - return objMgr.connector.DeleteObject(ref) -} - -func (objMgr *ObjectManager) DeleteNetwork(ref string) (string, error) { - return objMgr.connector.DeleteObject(ref) -} - -func (objMgr *ObjectManager) DeleteNetworkView(ref string) (string, error) { - return objMgr.connector.DeleteObject(ref) -} - -func (objMgr *ObjectManager) GetEADefinition(name string) (*EADefinition, error) { - var res []EADefinition - - eadef := NewEADefinition(EADefinition{Name: name}) - - sf := map[string]string{ - "name": name, - } - queryParams := NewQueryParams(false, sf) - err := objMgr.connector.GetObject(eadef, "", queryParams, &res) - - if err != nil || res == nil || len(res) == 0 { - return nil, err - } - - return &res[0], nil -} - -func (objMgr *ObjectManager) CreateEADefinition(eadef EADefinition) (*EADefinition, error) { - newEadef := NewEADefinition(eadef) - - ref, err := objMgr.connector.CreateObject(newEadef) - newEadef.Ref = ref - - return newEadef, err -} - -func BuildIPv6NetworkFromRef(ref string) (*Network, error) { - // ipv6network/ZG5zLm5ldHdvcmskODkuMC4wLjAvMjQvMjU:2001%3Adb8%3Aabcd%3A0012%3A%3A0/64/global_view - r := regexp.MustCompile(`ipv6network/[^:]+:(([^\/]+)\/\d+)\/(.+)`) - m := r.FindStringSubmatch(ref) - - if m == nil { - return nil, fmt.Errorf("CIDR format not matched") - } - - cidr, err := url.QueryUnescape(m[1]) - if err != nil { - return nil, fmt.Errorf( - "cannot extract network CIDR information from the reference '%s': %s", - ref, err.Error()) - } - - if _, _, err = net.ParseCIDR(cidr); err != nil { - return nil, fmt.Errorf("CIDR format not matched") - } - - newNet := NewNetwork(m[3], cidr, true, "", nil) - newNet.Ref = ref - - return newNet, nil -} - -func (objMgr *ObjectManager) CreateHostRecord( - enabledns bool, - enabledhcp bool, - recordName string, - netview string, - dnsview string, - ipv4cidr string, - ipv6cidr string, - ipv4Addr string, - ipv6Addr string, - macAddr string, - duid string, - useTtl bool, - ttl uint32, - comment string, - eas EA, - aliases []string) (*HostRecord, error) { - - if ipv4Addr == "" && ipv4cidr != "" { - if netview == "" { - netview = "default" - } - ipv4Addr = fmt.Sprintf("func:nextavailableip:%s,%s", ipv4cidr, netview) - } - if ipv6Addr == "" && ipv6cidr != "" { - if netview == "" { - netview = "default" - } - ipv6Addr = fmt.Sprintf("func:nextavailableip:%s,%s", ipv6cidr, netview) - } - recordHost := NewEmptyHostRecord() - recordHostIpv6AddrSlice := []HostRecordIpv6Addr{} - recordHostIpv4AddrSlice := []HostRecordIpv4Addr{} - if ipv6Addr != "" { - recordHostIpv6Addr := NewHostRecordIpv6Addr(ipv6Addr, duid, enabledhcp, "") - recordHostIpv6AddrSlice = []HostRecordIpv6Addr{*recordHostIpv6Addr} - } - if ipv4Addr != "" { - recordHostIpAddr := NewHostRecordIpv4Addr(ipv4Addr, macAddr, enabledhcp, "") - recordHostIpv4AddrSlice = []HostRecordIpv4Addr{*recordHostIpAddr} - } - recordHost = NewHostRecord( - netview, recordName, "", "", recordHostIpv4AddrSlice, recordHostIpv6AddrSlice, - eas, enabledns, dnsview, "", "", useTtl, ttl, comment, aliases) - ref, err := objMgr.connector.CreateObject(recordHost) - if err != nil { - return nil, err - } - recordHost.Ref = ref - err = objMgr.connector.GetObject( - recordHost, ref, NewQueryParams(false, nil), &recordHost) - return recordHost, err -} - -func (objMgr *ObjectManager) GetHostRecordByRef(ref string) (*HostRecord, error) { - recordHost := NewEmptyHostRecord() - err := objMgr.connector.GetObject( - recordHost, ref, NewQueryParams(false, nil), &recordHost) - return recordHost, err -} - -func (objMgr *ObjectManager) GetHostRecord(netview string, dnsview string, recordName string, ipv4addr string, ipv6addr string) (*HostRecord, error) { - var res []HostRecord - - recordHost := NewEmptyHostRecord() - - sf := map[string]string{ - "name": recordName, - } - if netview != "" { - sf["network_view"] = netview - } - if dnsview != "" { - sf["view"] = dnsview - } - if ipv4addr != "" { - sf["ipv4addr"] = ipv4addr - } - if ipv6addr != "" { - sf["ipv6addr"] = ipv6addr - } - queryParams := NewQueryParams(false, sf) - err := objMgr.connector.GetObject(recordHost, "", queryParams, &res) - - if err != nil || res == nil || len(res) == 0 { - return nil, err - } - return &res[0], err - -} - -func (objMgr *ObjectManager) GetIpAddressFromHostRecord(host HostRecord) (string, error) { - err := objMgr.connector.GetObject( - &host, host.Ref, NewQueryParams(false, nil), &host) - return host.Ipv4Addrs[0].Ipv4Addr, err -} - -func (objMgr *ObjectManager) UpdateHostRecord( - hostRref string, - enabledns bool, - enabledhcp bool, - name string, - netView string, - ipv4cidr string, - ipv6cidr string, - ipv4Addr string, - ipv6Addr string, - macAddress string, - duid string, - useTtl bool, - ttl uint32, - comment string, - eas EA, - aliases []string) (*HostRecord, error) { - - recordHostIpv4AddrSlice := []HostRecordIpv4Addr{} - recordHostIpv6AddrSlice := []HostRecordIpv6Addr{} - if ipv4Addr == "" { - if ipv4cidr != "" { - ip, _, err := net.ParseCIDR(ipv4cidr) - if err != nil { - return nil, fmt.Errorf("cannot parse CIDR value: %s", err.Error()) - } - if ip.To4() == nil { - return nil, fmt.Errorf("CIDR value must be an IPv4 CIDR, not an IPv6 one") - } - if netView == "" { - netView = "default" - } - newIpAddr := fmt.Sprintf("func:nextavailableip:%s,%s", ipv4cidr, netView) - recordHostIpAddr := NewHostRecordIpv4Addr(newIpAddr, macAddress, enabledhcp, "") - recordHostIpv4AddrSlice = []HostRecordIpv4Addr{*recordHostIpAddr} - } - } else { - ip := net.ParseIP(ipv4Addr) - if ip == nil { - return nil, fmt.Errorf("'IP address for the record is not valid") - } - if ip.To4() == nil { - return nil, fmt.Errorf("IP address must be an IPv4 address, not an IPv6 one") - } - recordHostIpAddr := NewHostRecordIpv4Addr(ipv4Addr, macAddress, enabledhcp, "") - recordHostIpv4AddrSlice = []HostRecordIpv4Addr{*recordHostIpAddr} - } - if ipv6Addr == "" { - if ipv6cidr != "" { - ip, _, err := net.ParseCIDR(ipv6cidr) - if err != nil { - return nil, fmt.Errorf("cannot parse CIDR value: %s", err.Error()) - } - if ip.To4() != nil || ip.To16() == nil { - return nil, fmt.Errorf("CIDR value must be an IPv6 CIDR, not an IPv4 one") - } - if netView == "" { - netView = "default" - } - newIpAddr := fmt.Sprintf("func:nextavailableip:%s,%s", ipv6cidr, netView) - recordHostIpAddr := NewHostRecordIpv6Addr(newIpAddr, duid, enabledhcp, "") - recordHostIpv6AddrSlice = []HostRecordIpv6Addr{*recordHostIpAddr} - } - } else { - ip := net.ParseIP(ipv6Addr) - if ip == nil { - return nil, fmt.Errorf("IP address for the record is not valid") - } - if ip.To4() != nil || ip.To16() == nil { - return nil, fmt.Errorf("IP address must be an IPv6 address, not an IPv4 one") - } - recordHostIpAddr := NewHostRecordIpv6Addr(ipv6Addr, duid, enabledhcp, "") - recordHostIpv6AddrSlice = []HostRecordIpv6Addr{*recordHostIpAddr} - } - updateHostRecord := NewHostRecord( - "", name, "", "", recordHostIpv4AddrSlice, recordHostIpv6AddrSlice, - eas, enabledns, "", "", hostRref, useTtl, ttl, comment, aliases) - ref, err := objMgr.connector.UpdateObject(updateHostRecord, hostRref) - - updateHostRecord, err = objMgr.GetHostRecordByRef(ref) - if err != nil { - return nil, err - } - return updateHostRecord, nil -} - -func (objMgr *ObjectManager) DeleteHostRecord(ref string) (string, error) { - return objMgr.connector.DeleteObject(ref) -} - -// UpdateNetwork updates comment and EA parameters. -// EAs which exist will be updated, -// those which do exist but not in setEas map, will be deleted, -// EAs which do not exist will be created as new. -func (objMgr *ObjectManager) UpdateNetwork( - ref string, - setEas EA, - comment string) (*Network, error) { - - r := regexp.MustCompile("^ipv6network\\/.+") - isIPv6 := r.MatchString(ref) - - nw := NewNetwork("", "", isIPv6, "", nil) - err := objMgr.connector.GetObject( - nw, ref, NewQueryParams(false, nil), nw) - - if err != nil { - return nil, err - } - - nw.Ea = setEas - nw.Comment = comment - - newRef, err := objMgr.connector.UpdateObject(nw, ref) - if err != nil { - return nil, err - } - - nw.Ref = newRef - return nw, nil -} - -func (objMgr *ObjectManager) UpdateNetworkContainer( - ref string, - setEas EA, - comment string) (*NetworkContainer, error) { - - nc := &NetworkContainer{} - nc.returnFields = []string{"extattrs", "comment"} - - err := objMgr.connector.GetObject( - nc, ref, NewQueryParams(false, nil), nc) - if err != nil { - return nil, err - } - - nc.Ea = setEas - nc.Comment = comment - - reference, err := objMgr.connector.UpdateObject(nc, ref) - if err != nil { - return nil, err - } - - nc.Ref = reference - return nc, nil -} - -func (objMgr *ObjectManager) CreateARecord( - netView string, - dnsView string, - name string, - cidr string, - ipAddr string, - ttl uint32, - useTTL bool, - comment string, - eas EA) (*RecordA, error) { - - cleanName := strings.TrimSpace(name) - if cleanName == "" || cleanName != name { - return nil, fmt.Errorf( - "'name' argument is expected to be non-empty and it must NOT contain leading/trailing spaces") - } - - recordA := NewRecordA(dnsView, "", name, "", ttl, useTTL, comment, eas, "") - - if ipAddr == "" { - if cidr == "" { - return nil, fmt.Errorf("CIDR must not be empty") - } - ip, _, err := net.ParseCIDR(cidr) - if err != nil { - return nil, fmt.Errorf("cannot parse CIDR value: %s", err.Error()) - } - if ip.To4() == nil { - return nil, fmt.Errorf("CIDR value must be an IPv4 CIDR, not an IPv6 one") - } - if netView == "" { - recordA.Ipv4Addr = fmt.Sprintf("func:nextavailableip:%s", cidr) - } else { - recordA.Ipv4Addr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netView) - } - } else { - ip := net.ParseIP(ipAddr) - if ip == nil { - return nil, fmt.Errorf("'IP address for the record is not valid") - } - if ip.To4() == nil { - return nil, fmt.Errorf("IP address must be an IPv4 address, not an IPv6 one") - } - recordA.Ipv4Addr = ipAddr - } - - ref, err := objMgr.connector.CreateObject(recordA) - if err != nil { - return nil, err - } - - newRec, err := objMgr.GetARecordByRef(ref) - if err != nil { - return nil, err - } - - return newRec, nil -} - -func (objMgr *ObjectManager) UpdateARecord( - ref string, - name string, - ipAddr string, - cidr string, - netView string, - ttl uint32, - useTTL bool, - comment string, - eas EA) (*RecordA, error) { - - cleanName := strings.ToLower(strings.TrimSpace(name)) - if cleanName == "" || cleanName != name { - return nil, fmt.Errorf( - "'name' argument is expected to be non-empty and it must NOT contain leading/trailing spaces") - } - - rec, err := objMgr.GetARecordByRef(ref) - if err != nil { - return nil, err - } - newIpAddr := rec.Ipv4Addr - if ipAddr == "" { - if cidr != "" { - ip, _, err := net.ParseCIDR(cidr) - if err != nil { - return nil, fmt.Errorf("cannot parse CIDR value: %s", err.Error()) - } - if ip.To4() == nil { - return nil, fmt.Errorf("CIDR value must be an IPv4 CIDR, not an IPv6 one") - } - if netView == "" { - newIpAddr = fmt.Sprintf("func:nextavailableip:%s", cidr) - } else { - newIpAddr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netView) - } - } - // else: leaving ipv4addr field untouched - } else { - ip := net.ParseIP(ipAddr) - if ip == nil { - return nil, fmt.Errorf("'IP address for the record is not valid") - } - if ip.To4() == nil { - return nil, fmt.Errorf("IP address must be an IPv4 address, not an IPv6 one") - } - newIpAddr = ipAddr - } - rec = NewRecordA( - "", "", name, newIpAddr, ttl, useTTL, comment, eas, ref) - ref, err = objMgr.connector.UpdateObject(rec, ref) - if err != nil { - return nil, err - } - rec.Ref = ref - - rec, err = objMgr.GetARecordByRef(ref) - if err != nil { - return nil, err - } - - return rec, nil -} - -func (objMgr *ObjectManager) GetARecord(dnsview string, recordName string, ipAddr string) (*RecordA, error) { - var res []RecordA - recordA := NewEmptyRecordA() - if dnsview == "" || recordName == "" || ipAddr == "" { - return nil, fmt.Errorf("DNS view, IPv4 address and record name of the record are required to retreive a unique A record") - } - sf := map[string]string{ - "view": dnsview, - "name": recordName, - "ipv4addr": ipAddr, - } - queryParams := NewQueryParams(false, sf) - err := objMgr.connector.GetObject(recordA, "", queryParams, &res) - - if err != nil { - return nil, err - } else if res == nil || len(res) == 0 { - return nil, NewNotFoundError( - fmt.Sprintf( - "A record with name '%s' and IPv4 address '%s' in DNS view '%s' is not found", - recordName, ipAddr, dnsview)) - } - return &res[0], nil -} - -func (objMgr *ObjectManager) GetARecordByRef(ref string) (*RecordA, error) { - recordA := NewEmptyRecordA() - err := objMgr.connector.GetObject( - recordA, ref, NewQueryParams(false, nil), &recordA) - return recordA, err -} - -func (objMgr *ObjectManager) DeleteARecord(ref string) (string, error) { - return objMgr.connector.DeleteObject(ref) -} - -func (objMgr *ObjectManager) CreateAAAARecord( - netView string, - dnsView string, - recordName string, - cidr string, - ipAddr string, - useTtl bool, - ttl uint32, - comment string, - eas EA) (*RecordAAAA, error) { - - cleanName := strings.ToLower(strings.TrimSpace(recordName)) - if cleanName == "" || cleanName != recordName { - return nil, fmt.Errorf( - "'name' argument is expected to be non-empty and it must NOT contain leading/trailing spaces") - } - recordAAAA := NewRecordAAAA(dnsView, recordName, "", useTtl, ttl, comment, eas, "") - - if ipAddr == "" { - if cidr == "" { - return nil, fmt.Errorf("CIDR must not be empty") - } - ipAddress, _, err := net.ParseCIDR(cidr) - if err != nil { - return nil, fmt.Errorf("cannot parse CIDR value: %s", err.Error()) - } - if ipAddress.To4() != nil || ipAddress.To16() == nil { - return nil, fmt.Errorf("CIDR value must be an IPv6 CIDR, not an IPv4 one") - } - if netView == "" { - netView = "default" - } - recordAAAA.Ipv6Addr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netView) - } else { - ipAddress := net.ParseIP(ipAddr) - if ipAddress == nil { - return nil, fmt.Errorf("IP address for the record is not valid") - } - if ipAddress.To4() != nil || ipAddress.To16() == nil { - return nil, fmt.Errorf("IP address must be an IPv6 address, not an IPv4 one") - } - recordAAAA.Ipv6Addr = ipAddr - } - ref, err := objMgr.connector.CreateObject(recordAAAA) - if err != nil { - return nil, err - } - recordAAAA, err = objMgr.GetAAAARecordByRef(ref) - if err != nil { - return nil, err - } - return recordAAAA, nil -} - -func (objMgr *ObjectManager) GetAAAARecord(dnsview string, recordName string, ipAddr string) (*RecordAAAA, error) { - var res []RecordAAAA - recordAAAA := NewEmptyRecordAAAA() - if dnsview == "" || recordName == "" || ipAddr == "" { - return nil, fmt.Errorf("DNS view, IPv6 address and record name of the record are required to retreive a unique AAAA record") - } - sf := map[string]string{ - "view": dnsview, - "name": recordName, - "ipv6addr": ipAddr, - } - queryParams := NewQueryParams(false, sf) - err := objMgr.connector.GetObject(recordAAAA, "", queryParams, &res) - - if err != nil { - return nil, err - } else if res == nil || len(res) == 0 { - return nil, NewNotFoundError( - fmt.Sprintf( - "AAAA record with name '%s' and IPv6 address '%s' in DNS view '%s' is not found", - recordName, ipAddr, dnsview)) - } - return &res[0], nil -} - -func (objMgr *ObjectManager) GetAAAARecordByRef(ref string) (*RecordAAAA, error) { - recordAAAA := NewEmptyRecordAAAA() - err := objMgr.connector.GetObject( - recordAAAA, ref, NewQueryParams(false, nil), &recordAAAA) - return recordAAAA, err -} - -func (objMgr *ObjectManager) DeleteAAAARecord(ref string) (string, error) { - return objMgr.connector.DeleteObject(ref) -} - -func (objMgr *ObjectManager) UpdateAAAARecord( - ref string, - netView string, - recordName string, - ipAddr string, - cidr string, - useTtl bool, - ttl uint32, - comment string, - setEas EA) (*RecordAAAA, error) { - - cleanName := strings.ToLower(strings.TrimSpace(recordName)) - if cleanName == "" || cleanName != recordName { - return nil, fmt.Errorf( - "'name' argument is expected to be non-empty and it must NOT contain leading/trailing spaces") - } - - rec, err := objMgr.GetAAAARecordByRef(ref) - if err != nil { - return nil, err - } - newIpAddr := rec.Ipv6Addr - if ipAddr == "" { - if cidr != "" { - ipAddress, _, err := net.ParseCIDR(cidr) - if err != nil { - return nil, fmt.Errorf("cannot parse CIDR value: %s", err.Error()) - } - if ipAddress.To4() != nil || ipAddress.To16() == nil { - return nil, fmt.Errorf("CIDR value must be an IPv6 CIDR, not an IPv4 one") - } - if netView == "" { - netView = "default" - } - newIpAddr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netView) - } - } else { - ipAddress := net.ParseIP(ipAddr) - if ipAddress == nil { - return nil, fmt.Errorf("IP address for the record is not valid") - } - if ipAddress.To4() != nil || ipAddress.To16() == nil { - return nil, fmt.Errorf("IP address must be an IPv6 address, not an IPv4 one") - } - newIpAddr = ipAddr - } - recordAAAA := NewRecordAAAA("", recordName, newIpAddr, useTtl, ttl, comment, setEas, ref) - reference, err := objMgr.connector.UpdateObject(recordAAAA, ref) - if err != nil { - return nil, err - } - - recordAAAA, err = objMgr.GetAAAARecordByRef(reference) - if err != nil { - return nil, err - } - return recordAAAA, nil -} - -func (objMgr *ObjectManager) CreateCNAMERecord( - dnsview string, - canonical string, - recordname string, - useTtl bool, - ttl uint32, - comment string, - eas EA) (*RecordCNAME, error) { - - if canonical == "" || recordname == "" { - return nil, fmt.Errorf("canonical name and record name fields are required to create a CNAME record") - } - recordCNAME := NewRecordCNAME(dnsview, canonical, recordname, useTtl, ttl, comment, eas, "") - - ref, err := objMgr.connector.CreateObject(recordCNAME) - recordCNAME, err = objMgr.GetCNAMERecordByRef(ref) - return recordCNAME, err -} - -func (objMgr *ObjectManager) GetCNAMERecord(dnsview string, canonical string, recordName string) (*RecordCNAME, error) { - var res []RecordCNAME - recordCNAME := NewEmptyRecordCNAME() - if dnsview == "" || canonical == "" || recordName == "" { - return nil, fmt.Errorf("DNS view, canonical name and record name of the record are required to retreive a unique CNAME record") - } - sf := map[string]string{ - "view": dnsview, - "canonical": canonical, - "name": recordName, - } - - queryParams := NewQueryParams(false, sf) - err := objMgr.connector.GetObject(recordCNAME, "", queryParams, &res) - - if err != nil { - return nil, err - } else if res == nil || len(res) == 0 { - return nil, NewNotFoundError( - fmt.Sprintf( - "CNAME record with name '%s' and canonical name '%s' in DNS view '%s' is not found", - recordName, canonical, dnsview)) - } - return &res[0], nil -} - -func (objMgr *ObjectManager) GetCNAMERecordByRef(ref string) (*RecordCNAME, error) { - recordCNAME := NewEmptyRecordCNAME() - err := objMgr.connector.GetObject( - recordCNAME, ref, NewQueryParams(false, nil), &recordCNAME) - return recordCNAME, err -} - -func (objMgr *ObjectManager) DeleteCNAMERecord(ref string) (string, error) { - return objMgr.connector.DeleteObject(ref) -} - -func (objMgr *ObjectManager) UpdateCNAMERecord( - ref string, - canonical string, - recordName string, - useTtl bool, - ttl uint32, - comment string, - setEas EA) (*RecordCNAME, error) { - - recordCNAME := NewRecordCNAME("", canonical, recordName, useTtl, ttl, comment, setEas, ref) - updatedRef, err := objMgr.connector.UpdateObject(recordCNAME, ref) - if err != nil { - return nil, err - } - - recordCNAME, err = objMgr.GetCNAMERecordByRef(updatedRef) - return recordCNAME, err -} - -// Creates TXT Record. Use TTL of 0 to inherit TTL from the Zone -func (objMgr *ObjectManager) CreateTXTRecord(recordname string, text string, ttl uint, dnsview string) (*RecordTXT, error) { - - recordTXT := NewRecordTXT(RecordTXT{ - View: dnsview, - Name: recordname, - Text: text, - Ttl: ttl, - }) - - ref, err := objMgr.connector.CreateObject(recordTXT) - recordTXT.Ref = ref - return recordTXT, err -} - -func (objMgr *ObjectManager) GetTXTRecordByRef(ref string) (*RecordTXT, error) { - recordTXT := NewRecordTXT(RecordTXT{}) - err := objMgr.connector.GetObject( - recordTXT, ref, NewQueryParams(false, nil), &recordTXT) - return recordTXT, err -} - -func (objMgr *ObjectManager) GetTXTRecord(name string) (*RecordTXT, error) { - if name == "" { - return nil, fmt.Errorf("name can not be empty") - } - var res []RecordTXT - - recordTXT := NewRecordTXT(RecordTXT{}) - - sf := map[string]string{ - "name": name, - } - queryParams := NewQueryParams(false, sf) - err := objMgr.connector.GetObject(recordTXT, "", queryParams, &res) - - if err != nil || res == nil || len(res) == 0 { - return nil, err - } - - return &res[0], nil -} - -func (objMgr *ObjectManager) UpdateTXTRecord(recordname string, text string) (*RecordTXT, error) { - var res []RecordTXT - - recordTXT := NewRecordTXT(RecordTXT{Name: recordname}) - - sf := map[string]string{ - "name": recordname, - } - queryParams := NewQueryParams(false, sf) - err := objMgr.connector.GetObject(recordTXT, "", queryParams, &res) - - if len(res) == 0 { - return nil, nil - } - - res[0].Text = text - - res[0].Zone = "" // set the Zone value to "" as its a non writable field - - _, err = objMgr.connector.UpdateObject(&res[0], res[0].Ref) - - if err != nil || res == nil || len(res) == 0 { - return nil, err - } - - return &res[0], nil -} - -func (objMgr *ObjectManager) DeleteTXTRecord(ref string) (string, error) { - return objMgr.connector.DeleteObject(ref) -} - -// TODO check if the respective zone exists before creation of the record -func (objMgr *ObjectManager) CreatePTRRecord( - networkView string, - dnsView string, - ptrdname string, - recordName string, - cidr string, - ipAddr string, - useTtl bool, - ttl uint32, - comment string, - eas EA) (*RecordPTR, error) { - - if ptrdname == "" { - return nil, fmt.Errorf("ptrdname is a required field to create a PTR record") - } - recordPTR := NewRecordPTR(dnsView, ptrdname, useTtl, ttl, comment, eas) - - if ipAddr == "" && cidr != "" { - if networkView == "" { - networkView = "default" - } - ipAddress, net, err := net.ParseCIDR(cidr) - if err != nil { - return nil, err - } - if ipAddress.To4() != nil { - if net.String() != cidr { - return nil, fmt.Errorf("%s is an invalid CIDR. Note: leading zeros should be removed if exists", cidr) - } - recordPTR.Ipv4Addr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, networkView) - } else { - recordPTR.Ipv6Addr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, networkView) - } - } else if ipAddr != "" { - ipAddress := net.ParseIP(ipAddr) - if ipAddress == nil { - return nil, fmt.Errorf("%s is an invalid IP address", ipAddr) - } - if ipAddress.To4() != nil { - recordPTR.Ipv4Addr = ipAddr - } else { - recordPTR.Ipv6Addr = ipAddr - } - } else if recordName != "" { - recordPTR.Name = recordName - } else { - return nil, fmt.Errorf("CIDR and network view are required to allocate a next available IP address\n" + - "IP address is required to create PTR record in reverse mapping zone\n" + - "record name is required to create a record in forwarrd mapping zone") - } - ref, err := objMgr.connector.CreateObject(recordPTR) - if err != nil { - return nil, err - } - recordPTR, err = objMgr.GetPTRRecordByRef(ref) - return recordPTR, err -} - -func (objMgr *ObjectManager) GetPTRRecord(dnsview string, ptrdname string, recordName string, ipAddr string) (*RecordPTR, error) { - var res []RecordPTR - recordPtr := NewEmptyRecordPTR() - sf := map[string]string{ - "view": dnsview, - "ptrdname": ptrdname, - } - cleanName := strings.TrimSpace(recordName) - if ipAddr != "" { - ipAddress := net.ParseIP(ipAddr) - if ipAddress == nil { - return nil, fmt.Errorf("%s is an invalid IP address", ipAddr) - } - if ipAddress.To4() != nil { - sf["ipv4addr"] = ipAddr - } else { - sf["ipv6addr"] = ipAddr - } - } else if cleanName != "" { - sf["name"] = cleanName - } else { - return nil, fmt.Errorf("record name or IP Address of the record has to be passed to get a unique record") - } - queryParams := NewQueryParams(false, sf) - err := objMgr.connector.GetObject(recordPtr, "", queryParams, &res) - - if err != nil { - return nil, err - } else if res == nil || len(res) == 0 { - return nil, NewNotFoundError( - fmt.Sprintf( - "PTR record with name/IP '%v' and ptrdname '%s' in DNS view '%s' is not found", - []string{recordName, ipAddr}, ptrdname, dnsview)) - } - return &res[0], nil -} - -func (objMgr *ObjectManager) GetPTRRecordByRef(ref string) (*RecordPTR, error) { - recordPTR := NewEmptyRecordPTR() - err := objMgr.connector.GetObject( - recordPTR, ref, NewQueryParams(false, nil), &recordPTR) - return recordPTR, err -} - -func (objMgr *ObjectManager) DeletePTRRecord(ref string) (string, error) { - return objMgr.connector.DeleteObject(ref) -} - -func (objMgr *ObjectManager) UpdatePTRRecord( - ref string, - netview string, - ptrdname string, - name string, - cidr string, - ipAddr string, - useTtl bool, - ttl uint32, - comment string, - setEas EA) (*RecordPTR, error) { - - recordPTR := NewRecordPTR("", ptrdname, useTtl, ttl, comment, setEas) - recordPTR.Ref = ref - recordPTR.Name = name - isIPv6, _ := regexp.MatchString(`^record:ptr/.+.ip6.arpa/.+`, ref) - - if ipAddr == "" { - if cidr != "" { - ipAddress, _, err := net.ParseCIDR(cidr) - if err != nil { - return nil, fmt.Errorf("cannot parse CIDR value: %s", err.Error()) - } - if netview == "" { - netview = "default" - } - if isIPv6 { - if ipAddress.To4() != nil || ipAddress.To16() == nil { - return nil, fmt.Errorf("CIDR value must be an IPv6 CIDR, not an IPv4 one") - } - recordPTR.Ipv6Addr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netview) - } else { - if ipAddress.To4() == nil { - return nil, fmt.Errorf("CIDR value must be an IPv4 CIDR, not an IPv6 one") - } - recordPTR.Ipv4Addr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netview) - } - } - } else { - ipAddress := net.ParseIP(ipAddr) - if ipAddress == nil { - return nil, fmt.Errorf("IP address for the record is not valid") - } - if isIPv6 { - if ipAddress.To4() != nil || ipAddress.To16() == nil { - return nil, fmt.Errorf("IP address must be an IPv6 address, not an IPv4 one") - } - recordPTR.Ipv6Addr = ipAddr - } else { - if ipAddress.To4() == nil { - return nil, fmt.Errorf("IP address must be an IPv4 address, not an IPv6 one") - } - recordPTR.Ipv4Addr = ipAddr - } - } - reference, err := objMgr.connector.UpdateObject(recordPTR, ref) - if err != nil { - return nil, err - } - - recordPTR, err = objMgr.GetPTRRecordByRef(reference) - return recordPTR, err -} - // CreateMultiObject unmarshals the result into slice of maps func (objMgr *ObjectManager) CreateMultiObject(req *MultiRequest) ([]map[string]interface{}, error) { diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_a-record.go b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_a-record.go new file mode 100644 index 000000000..c62f831c2 --- /dev/null +++ b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_a-record.go @@ -0,0 +1,166 @@ +package ibclient + +import ( + "fmt" + "net" + "strings" +) + +func (objMgr *ObjectManager) CreateARecord( + netView string, + dnsView string, + name string, + cidr string, + ipAddr string, + ttl uint32, + useTTL bool, + comment string, + eas EA) (*RecordA, error) { + + cleanName := strings.TrimSpace(name) + if cleanName == "" || cleanName != name { + return nil, fmt.Errorf( + "'name' argument is expected to be non-empty and it must NOT contain leading/trailing spaces") + } + + recordA := NewRecordA(dnsView, "", name, "", ttl, useTTL, comment, eas, "") + + if ipAddr == "" { + if cidr == "" { + return nil, fmt.Errorf("CIDR must not be empty") + } + ip, _, err := net.ParseCIDR(cidr) + if err != nil { + return nil, fmt.Errorf("cannot parse CIDR value: %s", err.Error()) + } + if ip.To4() == nil { + return nil, fmt.Errorf("CIDR value must be an IPv4 CIDR, not an IPv6 one") + } + if netView == "" { + recordA.Ipv4Addr = fmt.Sprintf("func:nextavailableip:%s", cidr) + } else { + recordA.Ipv4Addr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netView) + } + } else { + ip := net.ParseIP(ipAddr) + if ip == nil { + return nil, fmt.Errorf("'IP address for the record is not valid") + } + if ip.To4() == nil { + return nil, fmt.Errorf("IP address must be an IPv4 address, not an IPv6 one") + } + recordA.Ipv4Addr = ipAddr + } + + ref, err := objMgr.connector.CreateObject(recordA) + if err != nil { + return nil, err + } + + newRec, err := objMgr.GetARecordByRef(ref) + if err != nil { + return nil, err + } + + return newRec, nil +} + +func (objMgr *ObjectManager) UpdateARecord( + ref string, + name string, + ipAddr string, + cidr string, + netView string, + ttl uint32, + useTTL bool, + comment string, + eas EA) (*RecordA, error) { + + cleanName := strings.ToLower(strings.TrimSpace(name)) + if cleanName == "" || cleanName != name { + return nil, fmt.Errorf( + "'name' argument is expected to be non-empty and it must NOT contain leading/trailing spaces") + } + + rec, err := objMgr.GetARecordByRef(ref) + if err != nil { + return nil, err + } + newIpAddr := rec.Ipv4Addr + if ipAddr == "" { + if cidr != "" { + ip, _, err := net.ParseCIDR(cidr) + if err != nil { + return nil, fmt.Errorf("cannot parse CIDR value: %s", err.Error()) + } + if ip.To4() == nil { + return nil, fmt.Errorf("CIDR value must be an IPv4 CIDR, not an IPv6 one") + } + if netView == "" { + newIpAddr = fmt.Sprintf("func:nextavailableip:%s", cidr) + } else { + newIpAddr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netView) + } + } + // else: leaving ipv4addr field untouched + } else { + ip := net.ParseIP(ipAddr) + if ip == nil { + return nil, fmt.Errorf("'IP address for the record is not valid") + } + if ip.To4() == nil { + return nil, fmt.Errorf("IP address must be an IPv4 address, not an IPv6 one") + } + newIpAddr = ipAddr + } + rec = NewRecordA( + "", "", name, newIpAddr, ttl, useTTL, comment, eas, ref) + ref, err = objMgr.connector.UpdateObject(rec, ref) + if err != nil { + return nil, err + } + rec.Ref = ref + + rec, err = objMgr.GetARecordByRef(ref) + if err != nil { + return nil, err + } + + return rec, nil +} + +func (objMgr *ObjectManager) GetARecord(dnsview string, recordName string, ipAddr string) (*RecordA, error) { + var res []RecordA + recordA := NewEmptyRecordA() + if dnsview == "" || recordName == "" || ipAddr == "" { + return nil, fmt.Errorf("DNS view, IPv4 address and record name of the record are required to retreive a unique A record") + } + sf := map[string]string{ + "view": dnsview, + "name": recordName, + "ipv4addr": ipAddr, + } + queryParams := NewQueryParams(false, sf) + err := objMgr.connector.GetObject(recordA, "", queryParams, &res) + + if err != nil { + return nil, err + } else if res == nil || len(res) == 0 { + return nil, NewNotFoundError( + fmt.Sprintf( + "A record with name '%s' and IPv4 address '%s' in DNS view '%s' is not found", + recordName, ipAddr, dnsview)) + } + return &res[0], nil +} + +func (objMgr *ObjectManager) GetARecordByRef(ref string) (*RecordA, error) { + recordA := NewEmptyRecordA() + err := objMgr.connector.GetObject( + recordA, ref, NewQueryParams(false, nil), &recordA) + return recordA, err +} + +func (objMgr *ObjectManager) DeleteARecord(ref string) (string, error) { + return objMgr.connector.DeleteObject(ref) +} diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_aaaa-record.go b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_aaaa-record.go new file mode 100644 index 000000000..4ee7d9036 --- /dev/null +++ b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_aaaa-record.go @@ -0,0 +1,156 @@ +package ibclient + +import ( + "fmt" + "net" + "strings" +) + +func (objMgr *ObjectManager) CreateAAAARecord( + netView string, + dnsView string, + recordName string, + cidr string, + ipAddr string, + useTtl bool, + ttl uint32, + comment string, + eas EA) (*RecordAAAA, error) { + + cleanName := strings.ToLower(strings.TrimSpace(recordName)) + if cleanName == "" || cleanName != recordName { + return nil, fmt.Errorf( + "'name' argument is expected to be non-empty and it must NOT contain leading/trailing spaces") + } + recordAAAA := NewRecordAAAA(dnsView, recordName, "", useTtl, ttl, comment, eas, "") + + if ipAddr == "" { + if cidr == "" { + return nil, fmt.Errorf("CIDR must not be empty") + } + ipAddress, _, err := net.ParseCIDR(cidr) + if err != nil { + return nil, fmt.Errorf("cannot parse CIDR value: %s", err.Error()) + } + if ipAddress.To4() != nil || ipAddress.To16() == nil { + return nil, fmt.Errorf("CIDR value must be an IPv6 CIDR, not an IPv4 one") + } + if netView == "" { + netView = "default" + } + recordAAAA.Ipv6Addr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netView) + } else { + ipAddress := net.ParseIP(ipAddr) + if ipAddress == nil { + return nil, fmt.Errorf("IP address for the record is not valid") + } + if ipAddress.To4() != nil || ipAddress.To16() == nil { + return nil, fmt.Errorf("IP address must be an IPv6 address, not an IPv4 one") + } + recordAAAA.Ipv6Addr = ipAddr + } + ref, err := objMgr.connector.CreateObject(recordAAAA) + if err != nil { + return nil, err + } + recordAAAA, err = objMgr.GetAAAARecordByRef(ref) + if err != nil { + return nil, err + } + return recordAAAA, nil +} + +func (objMgr *ObjectManager) GetAAAARecord(dnsview string, recordName string, ipAddr string) (*RecordAAAA, error) { + var res []RecordAAAA + recordAAAA := NewEmptyRecordAAAA() + if dnsview == "" || recordName == "" || ipAddr == "" { + return nil, fmt.Errorf("DNS view, IPv6 address and record name of the record are required to retreive a unique AAAA record") + } + sf := map[string]string{ + "view": dnsview, + "name": recordName, + "ipv6addr": ipAddr, + } + queryParams := NewQueryParams(false, sf) + err := objMgr.connector.GetObject(recordAAAA, "", queryParams, &res) + + if err != nil { + return nil, err + } else if res == nil || len(res) == 0 { + return nil, NewNotFoundError( + fmt.Sprintf( + "AAAA record with name '%s' and IPv6 address '%s' in DNS view '%s' is not found", + recordName, ipAddr, dnsview)) + } + return &res[0], nil +} + +func (objMgr *ObjectManager) GetAAAARecordByRef(ref string) (*RecordAAAA, error) { + recordAAAA := NewEmptyRecordAAAA() + err := objMgr.connector.GetObject( + recordAAAA, ref, NewQueryParams(false, nil), &recordAAAA) + return recordAAAA, err +} + +func (objMgr *ObjectManager) DeleteAAAARecord(ref string) (string, error) { + return objMgr.connector.DeleteObject(ref) +} + +func (objMgr *ObjectManager) UpdateAAAARecord( + ref string, + netView string, + recordName string, + ipAddr string, + cidr string, + useTtl bool, + ttl uint32, + comment string, + setEas EA) (*RecordAAAA, error) { + + cleanName := strings.ToLower(strings.TrimSpace(recordName)) + if cleanName == "" || cleanName != recordName { + return nil, fmt.Errorf( + "'name' argument is expected to be non-empty and it must NOT contain leading/trailing spaces") + } + + rec, err := objMgr.GetAAAARecordByRef(ref) + if err != nil { + return nil, err + } + newIpAddr := rec.Ipv6Addr + if ipAddr == "" { + if cidr != "" { + ipAddress, _, err := net.ParseCIDR(cidr) + if err != nil { + return nil, fmt.Errorf("cannot parse CIDR value: %s", err.Error()) + } + if ipAddress.To4() != nil || ipAddress.To16() == nil { + return nil, fmt.Errorf("CIDR value must be an IPv6 CIDR, not an IPv4 one") + } + if netView == "" { + netView = "default" + } + newIpAddr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netView) + } + } else { + ipAddress := net.ParseIP(ipAddr) + if ipAddress == nil { + return nil, fmt.Errorf("IP address for the record is not valid") + } + if ipAddress.To4() != nil || ipAddress.To16() == nil { + return nil, fmt.Errorf("IP address must be an IPv6 address, not an IPv4 one") + } + newIpAddr = ipAddr + } + recordAAAA := NewRecordAAAA("", recordName, newIpAddr, useTtl, ttl, comment, setEas, ref) + reference, err := objMgr.connector.UpdateObject(recordAAAA, ref) + if err != nil { + return nil, err + } + + recordAAAA, err = objMgr.GetAAAARecordByRef(reference) + if err != nil { + return nil, err + } + return recordAAAA, nil +} diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_cname-record.go b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_cname-record.go new file mode 100644 index 000000000..7eaf6dacb --- /dev/null +++ b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_cname-record.go @@ -0,0 +1,84 @@ +package ibclient + +import "fmt" + +func (objMgr *ObjectManager) CreateCNAMERecord( + dnsview string, + canonical string, + recordname string, + useTtl bool, + ttl uint32, + comment string, + eas EA) (*RecordCNAME, error) { + + if canonical == "" || recordname == "" { + return nil, fmt.Errorf("canonical name and record name fields are required to create a CNAME record") + } + recordCNAME := NewRecordCNAME(dnsview, canonical, recordname, useTtl, ttl, comment, eas, "") + + ref, err := objMgr.connector.CreateObject(recordCNAME) + if err != nil { + return nil, err + } + recordCNAME, err = objMgr.GetCNAMERecordByRef(ref) + if err != nil { + return nil, err + } + return recordCNAME, err +} + +func (objMgr *ObjectManager) GetCNAMERecord(dnsview string, canonical string, recordName string) (*RecordCNAME, error) { + var res []RecordCNAME + recordCNAME := NewEmptyRecordCNAME() + if dnsview == "" || canonical == "" || recordName == "" { + return nil, fmt.Errorf("DNS view, canonical name and record name of the record are required to retreive a unique CNAME record") + } + sf := map[string]string{ + "view": dnsview, + "canonical": canonical, + "name": recordName, + } + + queryParams := NewQueryParams(false, sf) + err := objMgr.connector.GetObject(recordCNAME, "", queryParams, &res) + + if err != nil { + return nil, err + } else if res == nil || len(res) == 0 { + return nil, NewNotFoundError( + fmt.Sprintf( + "CNAME record with name '%s' and canonical name '%s' in DNS view '%s' is not found", + recordName, canonical, dnsview)) + } + return &res[0], nil +} + +func (objMgr *ObjectManager) GetCNAMERecordByRef(ref string) (*RecordCNAME, error) { + recordCNAME := NewEmptyRecordCNAME() + err := objMgr.connector.GetObject( + recordCNAME, ref, NewQueryParams(false, nil), &recordCNAME) + return recordCNAME, err +} + +func (objMgr *ObjectManager) DeleteCNAMERecord(ref string) (string, error) { + return objMgr.connector.DeleteObject(ref) +} + +func (objMgr *ObjectManager) UpdateCNAMERecord( + ref string, + canonical string, + recordName string, + useTtl bool, + ttl uint32, + comment string, + setEas EA) (*RecordCNAME, error) { + + recordCNAME := NewRecordCNAME("", canonical, recordName, useTtl, ttl, comment, setEas, ref) + updatedRef, err := objMgr.connector.UpdateObject(recordCNAME, ref) + if err != nil { + return nil, err + } + + recordCNAME, err = objMgr.GetCNAMERecordByRef(updatedRef) + return recordCNAME, err +} diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_dnsview.go b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_dnsview.go new file mode 100644 index 000000000..b50611ae9 --- /dev/null +++ b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_dnsview.go @@ -0,0 +1,20 @@ +package ibclient + +import "fmt" + +func (objMgr *ObjectManager) GetDNSView(name string) (*DNSView, error) { + var res []DNSView + if name == "" { + return nil, fmt.Errorf( + "DNS view's name is required to retreive DNS view object") + } + queryParams := NewQueryParams(false, map[string]string{"name": name}) + err := objMgr.connector.GetObject(NewEmptyDNSView(), "", queryParams, &res) + if err != nil { + return nil, err + } else if res == nil || len(res) == 0 { + return nil, NewNotFoundError(fmt.Sprintf("DNS view with name '%s' not found", name)) + } + + return &res[0], nil +} diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_ext_attrs_def.go b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_ext_attrs_def.go new file mode 100644 index 000000000..f30ca722d --- /dev/null +++ b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_ext_attrs_def.go @@ -0,0 +1,28 @@ +package ibclient + +func (objMgr *ObjectManager) CreateEADefinition(eadef EADefinition) (*EADefinition, error) { + newEadef := NewEADefinition(eadef) + + ref, err := objMgr.connector.CreateObject(newEadef) + newEadef.Ref = ref + + return newEadef, err +} + +func (objMgr *ObjectManager) GetEADefinition(name string) (*EADefinition, error) { + var res []EADefinition + + eadef := NewEADefinition(EADefinition{Name: name}) + + sf := map[string]string{ + "name": name, + } + queryParams := NewQueryParams(false, sf) + err := objMgr.connector.GetObject(eadef, "", queryParams, &res) + + if err != nil || res == nil || len(res) == 0 { + return nil, err + } + + return &res[0], nil +} diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_fixed_address.go b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_fixed_address.go new file mode 100644 index 000000000..bbb6094f8 --- /dev/null +++ b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_fixed_address.go @@ -0,0 +1,166 @@ +package ibclient + +import ( + "fmt" + "net" + "regexp" +) + +func (objMgr *ObjectManager) AllocateIP( + netview string, + cidr string, + ipAddr string, + isIPv6 bool, + macOrDuid string, + name string, + comment string, + eas EA) (*FixedAddress, error) { + + if isIPv6 { + if len(macOrDuid) == 0 { + return nil, fmt.Errorf("the DUID field cannot be left empty") + } + } else { + if len(macOrDuid) == 0 { + macOrDuid = MACADDR_ZERO + } + } + if ipAddr == "" && cidr != "" { + if netview == "" { + netview = "default" + } + ipAddr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netview) + } + fixedAddr := NewFixedAddress( + netview, name, ipAddr, cidr, macOrDuid, "", eas, "", isIPv6, comment) + ref, err := objMgr.connector.CreateObject(fixedAddr) + if err != nil { + return nil, err + } + + fixedAddr.Ref = ref + fixedAddr, err = objMgr.GetFixedAddressByRef(ref) + + return fixedAddr, err +} + +func (objMgr *ObjectManager) GetFixedAddress(netview string, cidr string, ipAddr string, isIpv6 bool, macOrDuid string) (*FixedAddress, error) { + var res []FixedAddress + + fixedAddr := NewEmptyFixedAddress(isIpv6) + sf := map[string]string{ + "network_view": netview, + "network": cidr, + } + if isIpv6 { + sf["ipv6addr"] = ipAddr + if macOrDuid != "" { + sf["duid"] = macOrDuid + } + } else { + sf["ipv4addr"] = ipAddr + if macOrDuid != "" { + sf["mac"] = macOrDuid + } + } + + queryParams := NewQueryParams(false, sf) + err := objMgr.connector.GetObject(fixedAddr, "", queryParams, &res) + + if err != nil || res == nil || len(res) == 0 { + return nil, err + } + + return &res[0], nil +} + +func (objMgr *ObjectManager) GetFixedAddressByRef(ref string) (*FixedAddress, error) { + r := regexp.MustCompile("^ipv6fixedaddress/.+") + isIPv6 := r.MatchString(ref) + + fixedAddr := NewEmptyFixedAddress(isIPv6) + err := objMgr.connector.GetObject( + fixedAddr, ref, NewQueryParams(false, nil), &fixedAddr) + return fixedAddr, err +} + +func (objMgr *ObjectManager) UpdateFixedAddress( + fixedAddrRef string, + netview string, + name string, + cidr string, + ipAddr string, + matchClient string, + macOrDuid string, + comment string, + eas EA) (*FixedAddress, error) { + + r := regexp.MustCompile("^ipv6fixedaddress/.+") + isIPv6 := r.MatchString(fixedAddrRef) + if !isIPv6 { + if !validateMatchClient(matchClient) { + return nil, fmt.Errorf("wrong value for match_client passed %s \n ", matchClient) + } + } + updateFixedAddr := NewFixedAddress( + "", name, "", "", + macOrDuid, matchClient, eas, fixedAddrRef, isIPv6, comment) + + if ipAddr == "" { + if cidr != "" { + ipAddress, _, err := net.ParseCIDR(cidr) + if err != nil { + return nil, fmt.Errorf("cannot parse CIDR value: %s", err.Error()) + } + if netview == "" { + netview = "default" + } + if isIPv6 { + if ipAddress.To4() != nil || ipAddress.To16() == nil { + return nil, fmt.Errorf("CIDR value must be an IPv6 CIDR, not an IPv4 one") + } + updateFixedAddr.IPv6Address = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netview) + } else { + if ipAddress.To4() == nil { + return nil, fmt.Errorf("CIDR value must be an IPv4 CIDR, not an IPv6 one") + } + updateFixedAddr.IPv4Address = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netview) + } + } + } else { + ipAddress := net.ParseIP(ipAddr) + if ipAddress == nil { + return nil, fmt.Errorf("IP address for the record is not valid") + } + if isIPv6 { + if ipAddress.To4() != nil || ipAddress.To16() == nil { + return nil, fmt.Errorf("IP address must be an IPv6 address, not an IPv4 one") + } + updateFixedAddr.IPv6Address = ipAddr + } else { + if ipAddress.To4() == nil { + return nil, fmt.Errorf("IP address must be an IPv4 address, not an IPv6 one") + } + updateFixedAddr.IPv4Address = ipAddr + } + } + refResp, err := objMgr.connector.UpdateObject(updateFixedAddr, fixedAddrRef) + + updateFixedAddr, err = objMgr.GetFixedAddressByRef(refResp) + if err != nil { + return nil, err + } + return updateFixedAddr, nil +} + +func (objMgr *ObjectManager) ReleaseIP(netview string, cidr string, ipAddr string, isIpv6 bool, macOrDuid string) (string, error) { + fixAddress, _ := objMgr.GetFixedAddress(netview, cidr, ipAddr, isIpv6, macOrDuid) + if fixAddress == nil { + return "", nil + } + return objMgr.connector.DeleteObject(fixAddress.Ref) +} + +func (objMgr *ObjectManager) DeleteFixedAddress(ref string) (string, error) { + return objMgr.connector.DeleteObject(ref) +} diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_host_record.go b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_host_record.go new file mode 100644 index 000000000..876ae7960 --- /dev/null +++ b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_host_record.go @@ -0,0 +1,261 @@ +package ibclient + +import ( + "fmt" + "net" +) + +func (objMgr *ObjectManager) CreateHostRecord( + enabledns bool, + enableDhcp bool, + recordName string, + netview string, + dnsview string, + ipv4cidr string, + ipv6cidr string, + ipv4Addr string, + ipv6Addr string, + macAddr string, + duid string, + useTtl bool, + ttl uint32, + comment string, + eas EA, + aliases []string) (*HostRecord, error) { + + if ipv4Addr == "" && ipv4cidr != "" { + if netview == "" { + netview = "default" + } + ipv4Addr = fmt.Sprintf("func:nextavailableip:%s,%s", ipv4cidr, netview) + } + if ipv6Addr == "" && ipv6cidr != "" { + if netview == "" { + netview = "default" + } + ipv6Addr = fmt.Sprintf("func:nextavailableip:%s,%s", ipv6cidr, netview) + } + recordHost := NewEmptyHostRecord() + recordHostIpv6AddrSlice := []HostRecordIpv6Addr{} + recordHostIpv4AddrSlice := []HostRecordIpv4Addr{} + if ipv6Addr != "" { + enableDhcpv6 := false + if enableDhcp && duid != "" { + enableDhcpv6 = true + } + recordHostIpv6Addr := NewHostRecordIpv6Addr(ipv6Addr, duid, enableDhcpv6, "") + recordHostIpv6AddrSlice = []HostRecordIpv6Addr{*recordHostIpv6Addr} + } + if ipv4Addr != "" { + enableDhcpv4 := false + if enableDhcp && macAddr != "" && macAddr != MACADDR_ZERO { + enableDhcpv4 = true + } + recordHostIpAddr := NewHostRecordIpv4Addr(ipv4Addr, macAddr, enableDhcpv4, "") + recordHostIpv4AddrSlice = []HostRecordIpv4Addr{*recordHostIpAddr} + } + recordHost = NewHostRecord( + netview, recordName, "", "", recordHostIpv4AddrSlice, recordHostIpv6AddrSlice, + eas, enabledns, dnsview, "", "", useTtl, ttl, comment, aliases) + ref, err := objMgr.connector.CreateObject(recordHost) + if err != nil { + return nil, err + } + recordHost.Ref = ref + err = objMgr.connector.GetObject( + recordHost, ref, NewQueryParams(false, nil), &recordHost) + return recordHost, err +} + +func (objMgr *ObjectManager) GetHostRecordByRef(ref string) (*HostRecord, error) { + recordHost := NewEmptyHostRecord() + err := objMgr.connector.GetObject( + recordHost, ref, NewQueryParams(false, nil), &recordHost) + + return recordHost, err +} + +func (objMgr *ObjectManager) SearchHostRecordByAltId( + internalId string, ref string, eaNameForInternalId string) (*HostRecord, error) { + + if internalId == "" { + return nil, fmt.Errorf("internal ID must not be empty") + } + + recordHost := NewEmptyHostRecord() + if ref != "" { + if err := objMgr.connector.GetObject(recordHost, ref, NewQueryParams(false, nil), &recordHost); err != nil { + if _, ok := err.(*NotFoundError); !ok { + return nil, err + } + } + } + if recordHost.Ref != "" { + return recordHost, nil + } + sf := map[string]string{ + fmt.Sprintf("*%s", eaNameForInternalId): internalId, + } + + res := make([]HostRecord, 0) + err := objMgr.connector.GetObject(recordHost, "", NewQueryParams(false, sf), &res) + + if err != nil { + return nil, err + } + + if res == nil || len(res) == 0 { + return nil, NewNotFoundError("host record not found") + } + + result := res[0] + + return &result, nil +} + +func (objMgr *ObjectManager) GetHostRecord(netview string, dnsview string, recordName string, ipv4addr string, ipv6addr string) (*HostRecord, error) { + var res []HostRecord + + recordHost := NewEmptyHostRecord() + + sf := map[string]string{ + "name": recordName, + } + if netview != "" { + sf["network_view"] = netview + } + if dnsview != "" { + sf["view"] = dnsview + } + if ipv4addr != "" { + sf["ipv4addr"] = ipv4addr + } + if ipv6addr != "" { + sf["ipv6addr"] = ipv6addr + } + queryParams := NewQueryParams(false, sf) + err := objMgr.connector.GetObject(recordHost, "", queryParams, &res) + + if err != nil || res == nil || len(res) == 0 { + return nil, err + } + return &res[0], err + +} + +func (objMgr *ObjectManager) GetIpAddressFromHostRecord(host HostRecord) (string, error) { + err := objMgr.connector.GetObject( + &host, host.Ref, NewQueryParams(false, nil), &host) + return host.Ipv4Addrs[0].Ipv4Addr, err +} + +func (objMgr *ObjectManager) UpdateHostRecord( + hostRref string, + enabledns bool, + enableDhcp bool, + name string, + netView string, + dnsView string, + ipv4cidr string, + ipv6cidr string, + ipv4Addr string, + ipv6Addr string, + macAddr string, + duid string, + useTtl bool, + ttl uint32, + comment string, + eas EA, + aliases []string) (*HostRecord, error) { + + recordHostIpv4AddrSlice := []HostRecordIpv4Addr{} + recordHostIpv6AddrSlice := []HostRecordIpv6Addr{} + + enableDhcpv4 := false + enableDhcpv6 := false + if ipv6Addr != "" { + if enableDhcp && duid != "" { + enableDhcpv6 = true + } + } + if ipv4Addr != "" { + if enableDhcp && macAddr != "" && macAddr != MACADDR_ZERO { + enableDhcpv4 = true + } + } + + if ipv4Addr == "" { + if ipv4cidr != "" { + ip, _, err := net.ParseCIDR(ipv4cidr) + if err != nil { + return nil, fmt.Errorf("cannot parse CIDR value: %s", err.Error()) + } + if ip.To4() == nil { + return nil, fmt.Errorf("CIDR value must be an IPv4 CIDR, not an IPv6 one") + } + if netView == "" { + netView = "default" + } + newIpAddr := fmt.Sprintf("func:nextavailableip:%s,%s", ipv4cidr, netView) + recordHostIpAddr := NewHostRecordIpv4Addr(newIpAddr, macAddr, enableDhcpv4, "") + recordHostIpv4AddrSlice = []HostRecordIpv4Addr{*recordHostIpAddr} + } + } else { + ip := net.ParseIP(ipv4Addr) + if ip == nil { + return nil, fmt.Errorf("'IP address for the record is not valid") + } + if ip.To4() == nil { + return nil, fmt.Errorf("IP address must be an IPv4 address, not an IPv6 one") + } + recordHostIpAddr := NewHostRecordIpv4Addr(ipv4Addr, macAddr, enableDhcpv4, "") + recordHostIpv4AddrSlice = []HostRecordIpv4Addr{*recordHostIpAddr} + } + if ipv6Addr == "" { + if ipv6cidr != "" { + ip, _, err := net.ParseCIDR(ipv6cidr) + if err != nil { + return nil, fmt.Errorf("cannot parse CIDR value: %s", err.Error()) + } + if ip.To4() != nil || ip.To16() == nil { + return nil, fmt.Errorf("CIDR value must be an IPv6 CIDR, not an IPv4 one") + } + if netView == "" { + netView = "default" + } + newIpAddr := fmt.Sprintf("func:nextavailableip:%s,%s", ipv6cidr, netView) + recordHostIpAddr := NewHostRecordIpv6Addr(newIpAddr, duid, enableDhcpv6, "") + recordHostIpv6AddrSlice = []HostRecordIpv6Addr{*recordHostIpAddr} + } + } else { + ip := net.ParseIP(ipv6Addr) + if ip == nil { + return nil, fmt.Errorf("IP address for the record is not valid") + } + if ip.To4() != nil || ip.To16() == nil { + return nil, fmt.Errorf("IP address must be an IPv6 address, not an IPv4 one") + } + recordHostIpAddr := NewHostRecordIpv6Addr(ipv6Addr, duid, enableDhcpv6, "") + recordHostIpv6AddrSlice = []HostRecordIpv6Addr{*recordHostIpAddr} + } + if !enabledns { + dnsView = "" + } + updateHostRecord := NewHostRecord( + "", name, "", "", recordHostIpv4AddrSlice, recordHostIpv6AddrSlice, + eas, enabledns, dnsView, "", hostRref, useTtl, ttl, comment, aliases) + ref, err := objMgr.connector.UpdateObject(updateHostRecord, hostRref) + if err != nil { + return nil, err + } + + updateHostRecord, err = objMgr.GetHostRecordByRef(ref) + if err != nil { + return nil, err + } + return updateHostRecord, nil +} + +func (objMgr *ObjectManager) DeleteHostRecord(ref string) (string, error) { + return objMgr.connector.DeleteObject(ref) +} diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_netview.go b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_netview.go new file mode 100644 index 000000000..acff5e10f --- /dev/null +++ b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_netview.go @@ -0,0 +1,102 @@ +package ibclient + +import ( + "fmt" + "strings" +) + +func (objMgr *ObjectManager) CreateNetworkView(name string, comment string, setEas EA) (*NetworkView, error) { + networkView := NewNetworkView(name, comment, setEas, "") + + ref, err := objMgr.connector.CreateObject(networkView) + networkView.Ref = ref + + return networkView, err +} + +func (objMgr *ObjectManager) makeNetworkView(netviewName string) (netviewRef string, err error) { + var netviewObj *NetworkView + if netviewObj, err = objMgr.GetNetworkView(netviewName); err != nil { + return + } + if netviewObj == nil { + if netviewObj, err = objMgr.CreateNetworkView(netviewName, "", nil); err != nil { + return + } + } + + netviewRef = netviewObj.Ref + + return +} + +func (objMgr *ObjectManager) CreateDefaultNetviews(globalNetview string, localNetview string) (globalNetviewRef string, localNetviewRef string, err error) { + if globalNetviewRef, err = objMgr.makeNetworkView(globalNetview); err != nil { + return + } + + if localNetviewRef, err = objMgr.makeNetworkView(localNetview); err != nil { + return + } + + return +} + +func (objMgr *ObjectManager) GetNetworkView(name string) (*NetworkView, error) { + var res []NetworkView + + netview := NewEmptyNetworkView() + sf := map[string]string{ + "name": name, + } + queryParams := NewQueryParams(false, sf) + err := objMgr.connector.GetObject(netview, "", queryParams, &res) + + if err != nil { + return nil, err + } + if res == nil || len(res) == 0 { + return nil, fmt.Errorf("network view '%s' not found", name) + } + + return &res[0], nil +} + +func (objMgr *ObjectManager) GetNetworkViewByRef(ref string) (*NetworkView, error) { + res := NewEmptyNetworkView() + queryParams := NewQueryParams(false, nil) + if err := objMgr.connector.GetObject(res, ref, queryParams, &res); err != nil { + return nil, err + } + if res == nil { + return nil, fmt.Errorf("network view not found") + } + + return res, nil +} + +func (objMgr *ObjectManager) UpdateNetworkView(ref string, name string, comment string, setEas EA) (*NetworkView, error) { + + nv := NewEmptyNetworkView() + + err := objMgr.connector.GetObject( + nv, ref, NewQueryParams(false, nil), nv) + if err != nil { + return nil, err + } + cleanName := strings.TrimSpace(name) + if cleanName != "" { + nv.Name = cleanName + } + nv.Comment = comment + nv.Ea = setEas + + updatedRef, err := objMgr.connector.UpdateObject(nv, ref) + nv.Ref = updatedRef + + return nv, err +} + +func (objMgr *ObjectManager) DeleteNetworkView(ref string) (string, error) { + return objMgr.connector.DeleteObject(ref) +} diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_network.go b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_network.go new file mode 100644 index 000000000..c381e6a34 --- /dev/null +++ b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_network.go @@ -0,0 +1,129 @@ +package ibclient + +import ( + "fmt" + "regexp" +) + +func (objMgr *ObjectManager) CreateNetwork(netview string, cidr string, isIPv6 bool, comment string, eas EA) (*Network, error) { + network := NewNetwork(netview, cidr, isIPv6, comment, eas) + + ref, err := objMgr.connector.CreateObject(network) + if err != nil { + return nil, err + } + network.Ref = ref + + return network, err +} + +func (objMgr *ObjectManager) AllocateNetwork( + netview string, + cidr string, + isIPv6 bool, + prefixLen uint, + comment string, + eas EA) (network *Network, err error) { + + network = nil + cidr = fmt.Sprintf("func:nextavailablenetwork:%s,%s,%d", cidr, netview, prefixLen) + networkReq := NewNetwork(netview, cidr, isIPv6, comment, eas) + + ref, err := objMgr.connector.CreateObject(networkReq) + if err == nil { + if isIPv6 { + network, err = BuildIPv6NetworkFromRef(ref) + } else { + network, err = BuildNetworkFromRef(ref) + } + } + + return +} + +func (objMgr *ObjectManager) GetNetwork(netview string, cidr string, isIPv6 bool, ea EA) (*Network, error) { + if netview != "" && cidr != "" { + var res []Network + + network := NewNetwork(netview, cidr, isIPv6, "", ea) + + network.Cidr = cidr + + if ea != nil && len(ea) > 0 { + network.eaSearch = EASearch(ea) + } + + sf := map[string]string{ + "network_view": netview, + "network": cidr, + } + queryParams := NewQueryParams(false, sf) + err := objMgr.connector.GetObject(network, "", queryParams, &res) + + if err != nil { + return nil, err + } else if res == nil || len(res) == 0 { + return nil, NewNotFoundError( + fmt.Sprintf( + "Network with cidr: %s in network view: %s is not found.", + cidr, netview)) + } + + return &res[0], nil + } else { + err := fmt.Errorf("both network view and cidr values are required") + return nil, err + } +} + +func (objMgr *ObjectManager) GetNetworkByRef(ref string) (*Network, error) { + r := regexp.MustCompile("^ipv6network\\/.+") + isIPv6 := r.MatchString(ref) + + network := NewNetwork("", "", isIPv6, "", nil) + err := objMgr.connector.GetObject(network, ref, NewQueryParams(false, nil), network) + return network, err +} + +// UpdateNetwork updates comment and EA parameters. +// EAs which exist will be updated, +// those which do exist but not in setEas map, will be deleted, +// EAs which do not exist will be created as new. +func (objMgr *ObjectManager) UpdateNetwork( + ref string, + setEas EA, + comment string) (*Network, error) { + + r := regexp.MustCompile("^ipv6network\\/.+") + isIPv6 := r.MatchString(ref) + + nw := NewNetwork("", "", isIPv6, "", nil) + err := objMgr.connector.GetObject( + nw, ref, NewQueryParams(false, nil), nw) + + if err != nil { + return nil, err + } + + nw.Ea = setEas + nw.Comment = comment + + // Network view is not allowed to be updated, + // thus making its name empty (will not appear among data which we update). + netViewSaved := nw.NetviewName + nw.NetviewName = "" + + newRef, err := objMgr.connector.UpdateObject(nw, ref) + if err != nil { + return nil, err + } + + nw.Ref = newRef + nw.NetviewName = netViewSaved + + return nw, nil +} + +func (objMgr *ObjectManager) DeleteNetwork(ref string) (string, error) { + return objMgr.connector.DeleteObject(ref) +} diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_network_container.go b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_network_container.go new file mode 100644 index 000000000..07dd0fd41 --- /dev/null +++ b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_network_container.go @@ -0,0 +1,117 @@ +package ibclient + +import ( + "fmt" + "regexp" +) + +func (objMgr *ObjectManager) CreateNetworkContainer(netview string, cidr string, isIPv6 bool, comment string, eas EA) (*NetworkContainer, error) { + container := NewNetworkContainer(netview, cidr, isIPv6, comment, eas) + + ref, err := objMgr.connector.CreateObject(container) + if err != nil { + return nil, err + } + + container.Ref = ref + return container, nil +} + +// TODO normalize IPv4 and IPv6 addresses +func (objMgr *ObjectManager) GetNetworkContainer(netview string, cidr string, isIPv6 bool, eaSearch EA) (*NetworkContainer, error) { + var res []NetworkContainer + + nc := NewNetworkContainer(netview, cidr, isIPv6, "", nil) + nc.eaSearch = EASearch(eaSearch) + sf := map[string]string{ + "network_view": netview, + "network": cidr, + } + queryParams := NewQueryParams(false, sf) + err := objMgr.connector.GetObject(nc, "", queryParams, &res) + if err != nil { + return nil, err + } else if res == nil || len(res) == 0 { + return nil, NewNotFoundError("network container not found") + } + + return &res[0], nil +} + +func (objMgr *ObjectManager) GetNetworkContainerByRef(ref string) (*NetworkContainer, error) { + nc := NewNetworkContainer("", "", false, "", nil) + + err := objMgr.connector.GetObject( + nc, ref, NewQueryParams(false, nil), nc) + if err != nil { + return nil, err + } + + return nc, nil +} + +func (objMgr *ObjectManager) UpdateNetworkContainer( + ref string, + setEas EA, + comment string) (*NetworkContainer, error) { + + nc := &NetworkContainer{} + nc.returnFields = []string{"extattrs", "comment"} + + err := objMgr.connector.GetObject( + nc, ref, NewQueryParams(false, nil), nc) + if err != nil { + return nil, err + } + + nc.Ea = setEas + nc.Comment = comment + + // Network view is not allowed to be updated, + // thus making its name empty (will not appear among data which we update). + netViewSaved := nc.NetviewName + nc.NetviewName = "" + + reference, err := objMgr.connector.UpdateObject(nc, ref) + if err != nil { + return nil, err + } + + nc.Ref = reference + nc.NetviewName = netViewSaved + + return nc, nil +} + +func (objMgr *ObjectManager) AllocateNetworkContainer( + netview string, + cidr string, + isIPv6 bool, + prefixLen uint, + comment string, + eas EA) (*NetworkContainer, error) { + + containerInfo := NewNetworkContainerNextAvailableInfo(netview, cidr, prefixLen, isIPv6) + container := NewNetworkContainerNextAvailable(containerInfo, isIPv6, comment, eas) + + ref, err := objMgr.connector.CreateObject(container) + + if err != nil { + return nil, err + } + + if isIPv6 { + return BuildIPv6NetworkContainerFromRef(ref) + } else { + return BuildNetworkContainerFromRef(ref) + } +} + +func (objMgr *ObjectManager) DeleteNetworkContainer(ref string) (string, error) { + ncRegExp := regexp.MustCompile("^(ipv6)?networkcontainer\\/.+") + if !ncRegExp.MatchString(ref) { + return "", fmt.Errorf("'ref' does not reference a network container") + } + + return objMgr.connector.DeleteObject(ref) +} diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_ptr-record.go b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_ptr-record.go new file mode 100644 index 000000000..7047daae0 --- /dev/null +++ b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_ptr-record.go @@ -0,0 +1,181 @@ +package ibclient + +import ( + "fmt" + "net" + "regexp" + "strings" +) + +// TODO check if the respective zone exists before creation of the record +func (objMgr *ObjectManager) CreatePTRRecord( + networkView string, + dnsView string, + ptrdname string, + recordName string, + cidr string, + ipAddr string, + useTtl bool, + ttl uint32, + comment string, + eas EA) (*RecordPTR, error) { + + if ptrdname == "" { + return nil, fmt.Errorf("ptrdname is a required field to create a PTR record") + } + recordPTR := NewRecordPTR(dnsView, ptrdname, useTtl, ttl, comment, eas) + + if recordName != "" { + recordPTR.Name = recordName + } else if ipAddr == "" && cidr != "" { + if networkView == "" { + networkView = "default" + } + ipAddress, net, err := net.ParseCIDR(cidr) + if err != nil { + return nil, err + } + if ipAddress.To4() != nil { + if net.String() != cidr { + return nil, fmt.Errorf("%s is an invalid CIDR. Note: leading zeros should be removed if exists", cidr) + } + recordPTR.Ipv4Addr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, networkView) + } else { + recordPTR.Ipv6Addr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, networkView) + } + } else if ipAddr != "" { + ipAddress := net.ParseIP(ipAddr) + if ipAddress == nil { + return nil, fmt.Errorf("%s is an invalid IP address", ipAddr) + } + if ipAddress.To4() != nil { + recordPTR.Ipv4Addr = ipAddr + } else { + recordPTR.Ipv6Addr = ipAddr + } + } else { + return nil, fmt.Errorf("CIDR and network view are required to allocate a next available IP address\n" + + "IP address is required to create PTR record in reverse mapping zone\n" + + "record name is required to create a record in forwarrd mapping zone") + } + ref, err := objMgr.connector.CreateObject(recordPTR) + if err != nil { + return nil, err + } + recordPTR, err = objMgr.GetPTRRecordByRef(ref) + return recordPTR, err +} + +func (objMgr *ObjectManager) GetPTRRecord(dnsview string, ptrdname string, recordName string, ipAddr string) (*RecordPTR, error) { + var res []RecordPTR + recordPtr := NewEmptyRecordPTR() + sf := map[string]string{ + "view": dnsview, + "ptrdname": ptrdname, + } + cleanName := strings.TrimSpace(recordName) + if ipAddr != "" { + ipAddress := net.ParseIP(ipAddr) + if ipAddress == nil { + return nil, fmt.Errorf("%s is an invalid IP address", ipAddr) + } + if ipAddress.To4() != nil { + sf["ipv4addr"] = ipAddr + } else { + sf["ipv6addr"] = ipAddr + } + } else if cleanName != "" { + sf["name"] = cleanName + } else { + return nil, fmt.Errorf("record name or IP Address of the record has to be passed to get a unique record") + } + queryParams := NewQueryParams(false, sf) + err := objMgr.connector.GetObject(recordPtr, "", queryParams, &res) + + if err != nil { + return nil, err + } else if res == nil || len(res) == 0 { + return nil, NewNotFoundError( + fmt.Sprintf( + "PTR record with name/IP '%v' and ptrdname '%s' in DNS view '%s' is not found", + []string{recordName, ipAddr}, ptrdname, dnsview)) + } + return &res[0], nil +} + +func (objMgr *ObjectManager) GetPTRRecordByRef(ref string) (*RecordPTR, error) { + recordPTR := NewEmptyRecordPTR() + err := objMgr.connector.GetObject( + recordPTR, ref, NewQueryParams(false, nil), &recordPTR) + return recordPTR, err +} + +func (objMgr *ObjectManager) DeletePTRRecord(ref string) (string, error) { + return objMgr.connector.DeleteObject(ref) +} + +func (objMgr *ObjectManager) UpdatePTRRecord( + ref string, + netview string, + ptrdname string, + name string, + cidr string, + ipAddr string, + useTtl bool, + ttl uint32, + comment string, + setEas EA) (*RecordPTR, error) { + + recordPTR := NewRecordPTR("", ptrdname, useTtl, ttl, comment, setEas) + recordPTR.Ref = ref + recordPTR.Name = name + isIPv6, _ := regexp.MatchString(`^record:ptr/.+.ip6.arpa/.+`, ref) + + if name == "" { + if ipAddr == "" { + if cidr != "" { + ipAddress, _, err := net.ParseCIDR(cidr) + if err != nil { + return nil, fmt.Errorf("cannot parse CIDR value: %s", err.Error()) + } + if netview == "" { + netview = "default" + } + if isIPv6 { + if ipAddress.To4() != nil || ipAddress.To16() == nil { + return nil, fmt.Errorf("CIDR value must be an IPv6 CIDR, not an IPv4 one") + } + recordPTR.Ipv6Addr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netview) + } else { + if ipAddress.To4() == nil { + return nil, fmt.Errorf("CIDR value must be an IPv4 CIDR, not an IPv6 one") + } + recordPTR.Ipv4Addr = fmt.Sprintf("func:nextavailableip:%s,%s", cidr, netview) + } + } + } else { + ipAddress := net.ParseIP(ipAddr) + if ipAddress == nil { + return nil, fmt.Errorf("IP address for the record is not valid") + } + if isIPv6 { + if ipAddress.To4() != nil || ipAddress.To16() == nil { + return nil, fmt.Errorf("IP address must be an IPv6 address, not an IPv4 one") + } + recordPTR.Ipv6Addr = ipAddr + } else { + if ipAddress.To4() == nil { + return nil, fmt.Errorf("IP address must be an IPv4 address, not an IPv6 one") + } + recordPTR.Ipv4Addr = ipAddr + } + } + } + reference, err := objMgr.connector.UpdateObject(recordPTR, ref) + if err != nil { + return nil, err + } + + recordPTR, err = objMgr.GetPTRRecordByRef(reference) + return recordPTR, err +} diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_txt-record.go b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_txt-record.go new file mode 100644 index 000000000..95273b555 --- /dev/null +++ b/vendor/github.com/infobloxopen/infoblox-go-client/v2/object_manager_txt-record.go @@ -0,0 +1,81 @@ +package ibclient + +import "fmt" + +// Creates TXT Record. Use TTL of 0 to inherit TTL from the Zone +func (objMgr *ObjectManager) CreateTXTRecord( + dnsView string, + recordName string, + text string, + ttl uint32, + useTtl bool, + comment string, + eas EA) (*RecordTXT, error) { + + recordTXT := NewRecordTXT(dnsView, "", recordName, text, ttl, useTtl, comment, eas) + + ref, err := objMgr.connector.CreateObject(recordTXT) + if err != nil { + return nil, err + } + recordTXT, err = objMgr.GetTXTRecordByRef(ref) + return recordTXT, err +} + +func (objMgr *ObjectManager) GetTXTRecordByRef(ref string) (*RecordTXT, error) { + recordTXT := NewEmptyRecordTXT() + err := objMgr.connector.GetObject( + recordTXT, ref, NewQueryParams(false, nil), &recordTXT) + return recordTXT, err +} + +func (objMgr *ObjectManager) GetTXTRecord(dnsview string, name string) (*RecordTXT, error) { + if dnsview == "" || name == "" { + return nil, fmt.Errorf("DNS view and name are required to retrieve a unique txt record") + } + var res []RecordTXT + + recordTXT := NewEmptyRecordTXT() + + sf := map[string]string{ + "view": dnsview, + "name": name, + } + queryParams := NewQueryParams(false, sf) + err := objMgr.connector.GetObject(recordTXT, "", queryParams, &res) + + if err != nil { + return nil, err + } else if res == nil || len(res) == 0 { + return nil, NewNotFoundError( + fmt.Sprintf( + "TXT record with name '%s' in DNS view '%s' is not found", + name, dnsview)) + } + return &res[0], nil +} + +func (objMgr *ObjectManager) UpdateTXTRecord( + ref string, + recordName string, + text string, + ttl uint32, + useTtl bool, + comment string, + eas EA) (*RecordTXT, error) { + + recordTXT := NewRecordTXT("", "", recordName, text, ttl, useTtl, comment, eas) + recordTXT.Ref = ref + + reference, err := objMgr.connector.UpdateObject(recordTXT, ref) + if err != nil { + return nil, err + } + + recordTXT, err = objMgr.GetTXTRecordByRef(reference) + return recordTXT, err +} + +func (objMgr *ObjectManager) DeleteTXTRecord(ref string) (string, error) { + return objMgr.connector.DeleteObject(ref) +} diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/v2/objects.go b/vendor/github.com/infobloxopen/infoblox-go-client/v2/objects.go index e63e70437..e9d260731 100644 --- a/vendor/github.com/infobloxopen/infoblox-go-client/v2/objects.go +++ b/vendor/github.com/infobloxopen/infoblox-go-client/v2/objects.go @@ -43,11 +43,11 @@ func (obj *IBBase) EaSearch() EASearch { } type NetworkView struct { - IBBase `json:"-"` - Ref string `json:"_ref,omitempty"` - Name string `json:"name,omitempty"` + IBBase `json:"-"` + Ref string `json:"_ref,omitempty"` + Name string `json:"name,omitempty"` Comment string `json:"comment"` - Ea EA `json:"extattrs"` + Ea EA `json:"extattrs"` } func NewEmptyNetworkView() *NetworkView { @@ -117,7 +117,7 @@ func NewNetwork(netview string, cidr string, isIPv6 bool, comment string, ea EA) } else { res.objectType = "network" } - res.returnFields = []string{"extattrs", "network", "comment"} + res.returnFields = []string{"extattrs", "network", "network_view", "comment"} return &res } @@ -322,6 +322,57 @@ func NewNetworkContainer(netview, cidr string, isIPv6 bool, comment string, ea E return &nc } +type NetworkContainerNextAvailable struct { + IBBase `json:"-"` + Network *NetworkContainerNextAvailableInfo `json:"network"` + Comment string `json:"comment"` + Ea EA `json:"extattrs"` +} + +type NetworkContainerNextAvailableInfo struct { + Function string `json:"_object_function"` + ResultField string `json:"_result_field"` + Object string `json:"_object"` + ObjectParams map[string]string `json:"_object_parameters"` + Params map[string]uint `json:"_parameters"` + NetviewName string `json:"network_view,omitempty"` +} + +func NewNetworkContainerNextAvailableInfo(netview, cidr string, prefixLen uint, isIPv6 bool) *NetworkContainerNextAvailableInfo { + containerInfo := NetworkContainerNextAvailableInfo{ + Function: "next_available_network", + ResultField: "networks", + ObjectParams: map[string]string{"network": cidr}, + Params: map[string]uint{"cidr": prefixLen}, + NetviewName: netview, + } + + if isIPv6 { + containerInfo.Object = "ipv6networkcontainer" + } else { + containerInfo.Object = "networkcontainer" + } + + return &containerInfo +} + +func NewNetworkContainerNextAvailable(ncav *NetworkContainerNextAvailableInfo, isIPv6 bool, comment string, ea EA) *NetworkContainerNextAvailable { + nc := &NetworkContainerNextAvailable{ + Network: ncav, + Ea: ea, + Comment: comment, + } + + if isIPv6 { + nc.objectType = "ipv6networkcontainer" + } else { + nc.objectType = "networkcontainer" + } + nc.returnFields = []string{"extattrs", "network", "network_view", "comment"} + + return nc +} + type FixedAddress struct { IBBase `json:"-"` Ref string `json:"_ref,omitempty"` @@ -431,6 +482,23 @@ func NewUserProfile(userprofile UserProfile) *UserProfile { return &res } +type DNSView struct { + IBBase `json:"-"` + Ref string `json:"_ref"` + Name string `json:"name"` + NetworkView string `json:"network_view"` + Comment string `json:"comment"` + Ea EA `json:"extattrs"` +} + +func NewEmptyDNSView() *DNSView { + res := &DNSView{} + res.objectType = "view" + res.returnFields = []string{"extattrs", "name", "network_view", "comment"} + + return res +} + type RecordA struct { IBBase `json:"-"` Ref string `json:"_ref,omitempty"` @@ -534,13 +602,13 @@ type RecordPTR struct { Ea EA `json:"extattrs"` UseTtl bool `json:"use_ttl"` Ttl uint32 `json:"ttl"` - Comment string `json:"comment,omitempty"` + Comment string `json:"comment"` } func NewEmptyRecordPTR() *RecordPTR { res := RecordPTR{} res.objectType = "record:ptr" - res.returnFields = []string{"extattrs", "ipv4addr", "ipv6addr", "ptrdname", "view", "zone", "comment", "use_ttl", "ttl"} + res.returnFields = []string{"extattrs", "ipv4addr", "ipv6addr", "name", "ptrdname", "view", "zone", "comment", "use_ttl", "ttl"} return &res } @@ -574,6 +642,7 @@ func NewEmptyRecordCNAME() *RecordCNAME { res := &RecordCNAME{} res.objectType = "record:cname" res.returnFields = []string{"extattrs", "canonical", "name", "view", "zone", "comment", "ttl", "use_ttl"} + return res } @@ -603,7 +672,7 @@ type HostRecordIpv4Addr struct { IBBase `json:"-"` Ipv4Addr string `json:"ipv4addr,omitempty"` Ref string `json:"_ref,omitempty"` - Mac string `json:"mac,omitempty"` + Mac string `json:"mac"` View string `json:"view,omitempty"` Cidr string `json:"network,omitempty"` EnableDhcp bool `json:"configure_for_dhcp"` @@ -635,7 +704,7 @@ type HostRecordIpv6Addr struct { IBBase `json:"-"` Ipv6Addr string `json:"ipv6addr,omitempty"` Ref string `json:"_ref,omitempty"` - Duid string `json:"duid,omitempty"` + Duid string `json:"duid"` View string `json:"view,omitempty"` Cidr string `json:"network,omitempty"` EnableDhcp bool `json:"configure_for_dhcp"` @@ -667,9 +736,9 @@ type HostRecord struct { IBBase `json:"-"` Ref string `json:"_ref,omitempty"` Ipv4Addr string `json:"ipv4addr,omitempty"` - Ipv4Addrs []HostRecordIpv4Addr `json:"ipv4addrs,omitempty"` + Ipv4Addrs []HostRecordIpv4Addr `json:"ipv4addrs"` Ipv6Addr string `json:"ipv6addr,omitempty"` - Ipv6Addrs []HostRecordIpv6Addr `json:"ipv6addrs,omitempty"` + Ipv6Addrs []HostRecordIpv6Addr `json:"ipv6addrs"` Name string `json:"name,omitempty"` View string `json:"view,omitempty"` Zone string `json:"zone,omitempty"` @@ -685,7 +754,7 @@ type HostRecord struct { func NewEmptyHostRecord() *HostRecord { res := &HostRecord{} res.objectType = "record:host" - res.returnFields = []string{"extattrs", "ipv4addrs", "ipv6addrs", "name", "view", "zone", "comment", "network_view", "aliases", "use_ttl", "ttl"} + res.returnFields = []string{"extattrs", "ipv4addrs", "ipv6addrs", "name", "view", "zone", "comment", "network_view", "aliases", "use_ttl", "ttl", "configure_for_dns"} return res } @@ -728,25 +797,49 @@ func NewHostRecord( } type RecordTXT struct { - IBBase `json:"-"` - Ref string `json:"_ref,omitempty"` - Name string `json:"name,omitempty"` - Text string `json:"text,omitempty"` - Ttl uint `json:"ttl,omitempty"` - View string `json:"view,omitempty"` - Zone string `json:"zone,omitempty"` - Ea EA `json:"extattrs,omitempty"` - UseTtl bool `json:"use_ttl,omitempty"` + IBBase `json:"-"` + View string `json:"view,omitempty"` + Zone string `json:"zone,omitempty"` + Ref string `json:"_ref,omitempty"` + Name string `json:"name,omitempty"` + Text string `json:"text,omitempty"` + Ttl uint32 `json:"ttl"` + UseTtl bool `json:"use_ttl"` + Comment string `json:"comment"` + Ea EA `json:"extattrs"` } -func NewRecordTXT(rt RecordTXT) *RecordTXT { - res := rt +func NewEmptyRecordTXT() *RecordTXT { + res := RecordTXT{} res.objectType = "record:txt" - res.returnFields = []string{"extattrs", "name", "text", "view", "zone", "ttl", "use_ttl"} + res.returnFields = []string{"view", "zone", "name", "text", "ttl", "use_ttl", "comment", "extattrs"} return &res } +func NewRecordTXT( + dnsview string, + zone string, + recordname string, + text string, + ttl uint32, + useTtl bool, + comment string, + eas EA) *RecordTXT { + + res := NewEmptyRecordTXT() + res.View = dnsview + res.Zone = zone + res.Name = recordname + res.Text = text + res.Ttl = ttl + res.UseTtl = useTtl + res.Comment = comment + res.Ea = eas + + return res +} + type ZoneAuth struct { IBBase `json:"-"` Ref string `json:"_ref,omitempty"` diff --git a/vendor/github.com/infobloxopen/infoblox-go-client/v2/utils.go b/vendor/github.com/infobloxopen/infoblox-go-client/v2/utils.go new file mode 100644 index 000000000..4726a34cb --- /dev/null +++ b/vendor/github.com/infobloxopen/infoblox-go-client/v2/utils.go @@ -0,0 +1,143 @@ +package ibclient + +import ( + "fmt" + "net" + "net/url" + "regexp" +) + +type NotFoundError struct { + msg string +} + +func (e *NotFoundError) Error() string { + return e.msg +} + +func NewNotFoundError(msg string) *NotFoundError { + return &NotFoundError{msg: msg} +} + +func BuildNetworkViewFromRef(ref string) *NetworkView { + // networkview/ZG5zLm5ldHdvcmtfdmlldyQyMw:global_view/false + r := regexp.MustCompile(`networkview/\w+:([^/]+)/\w+`) + m := r.FindStringSubmatch(ref) + + if m == nil { + return nil + } + + return &NetworkView{ + Ref: ref, + Name: m[1], + } +} + +func BuildNetworkFromRef(ref string) (*Network, error) { + // network/ZG5zLm5ldHdvcmskODkuMC4wLjAvMjQvMjU:89.0.0.0/24/global_view + r := regexp.MustCompile(`network/\w+:(\d+\.\d+\.\d+\.\d+/\d+)/(.+)`) + m := r.FindStringSubmatch(ref) + + if m == nil { + return nil, fmt.Errorf("CIDR format not matched") + } + + newNet := NewNetwork(m[2], m[1], false, "", nil) + newNet.Ref = ref + return newNet, nil +} + +func BuildNetworkContainerFromRef(ref string) (*NetworkContainer, error) { + // networkcontainer/ZG5zLm5ldHdvcmskODkuMC4wLjAvMjQvMjU:89.0.0.0/24/global_view + r := regexp.MustCompile(`networkcontainer/\w+:(\d+\.\d+\.\d+\.\d+/\d+)/(.+)`) + m := r.FindStringSubmatch(ref) + + if m == nil { + return nil, fmt.Errorf("CIDR format not matched") + } + + newNet := NewNetworkContainer(m[2], m[1], false, "", nil) + newNet.Ref = ref + return newNet, nil +} + +func BuildIPv6NetworkContainerFromRef(ref string) (*NetworkContainer, error) { + // ipv6networkcontainer/ZG5zLm5ldHdvcmskODkuMC4wLjAvMjQvMjU:2001%3Adb8%3Aabcd%3A0012%3A%3A0/64/global_view + r := regexp.MustCompile(`ipv6networkcontainer/[^:]+:(([^\/]+)\/\d+)\/(.+)`) + m := r.FindStringSubmatch(ref) + + if m == nil { + return nil, fmt.Errorf("CIDR format not matched") + } + + cidr, err := url.QueryUnescape(m[1]) + if err != nil { + return nil, fmt.Errorf( + "cannot extract network CIDR information from the reference '%s': %s", + ref, err.Error()) + } + + if _, _, err = net.ParseCIDR(cidr); err != nil { + return nil, fmt.Errorf("CIDR format not matched") + } + + newNet := NewNetworkContainer(m[3], cidr, true, "", nil) + newNet.Ref = ref + + return newNet, nil +} + +func GetIPAddressFromRef(ref string) string { + // fixedaddress/ZG5zLmJpbmRfY25h:12.0.10.1/external + r := regexp.MustCompile(`fixedaddress/\w+:(\d+\.\d+\.\d+\.\d+)/.+`) + m := r.FindStringSubmatch(ref) + + if m != nil { + return m[1] + } + return "" +} + +// validation for match_client +func validateMatchClient(value string) bool { + matchClientList := [5]string{ + "MAC_ADDRESS", + "CLIENT_ID", + "RESERVED", + "CIRCUIT_ID", + "REMOTE_ID"} + + for _, val := range matchClientList { + if val == value { + return true + } + } + return false +} + +func BuildIPv6NetworkFromRef(ref string) (*Network, error) { + // ipv6network/ZG5zLm5ldHdvcmskODkuMC4wLjAvMjQvMjU:2001%3Adb8%3Aabcd%3A0012%3A%3A0/64/global_view + r := regexp.MustCompile(`ipv6network/[^:]+:(([^\/]+)\/\d+)\/(.+)`) + m := r.FindStringSubmatch(ref) + + if m == nil { + return nil, fmt.Errorf("CIDR format not matched") + } + + cidr, err := url.QueryUnescape(m[1]) + if err != nil { + return nil, fmt.Errorf( + "cannot extract network CIDR information from the reference '%s': %s", + ref, err.Error()) + } + + if _, _, err = net.ParseCIDR(cidr); err != nil { + return nil, fmt.Errorf("CIDR format not matched") + } + + newNet := NewNetwork(m[3], cidr, true, "", nil) + newNet.Ref = ref + + return newNet, nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 471e79375..acc07e1ca 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -318,7 +318,7 @@ github.com/imdario/mergo # github.com/inconshreveable/mousetrap v1.0.0 ## explicit github.com/inconshreveable/mousetrap -# github.com/infobloxopen/infoblox-go-client/v2 v2.0.0 +# github.com/infobloxopen/infoblox-go-client/v2 v2.1.0 => github.com/MartinWeindel/infoblox-go-client/v2 v2.0.0-20221122085954-b7d80ebb106b ## explicit; go 1.15 github.com/infobloxopen/infoblox-go-client/v2 # github.com/jmespath/go-jmespath v0.4.0 @@ -1151,3 +1151,4 @@ sigs.k8s.io/structured-merge-diff/v4/value # sigs.k8s.io/yaml v1.3.0 ## explicit; go 1.12 sigs.k8s.io/yaml +# github.com/infobloxopen/infoblox-go-client/v2 => github.com/MartinWeindel/infoblox-go-client/v2 v2.0.0-20221122085954-b7d80ebb106b