diff --git a/.travis.yml b/.travis.yml index 940238f0..7a5828e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: go go: - - 1.15 + - 1.21 env: - GO111MODULE=auto diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bf41c87..a621bf19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Infoblox Go Client Release Notes +## v2.7.0 + +### Release Summary + +- Create, Update, Delete and Get operations for zone-forward record is being added. + +### Major Changes + +- Upgraded go version from 1.17 to 1.21 +- Added Create, Update and Delete operations for zone-forward record. +- Added `GetZoneForwardByRef` function to fetch zone-forward record by reference. +- Added `GetZoneForwardFilters` function to fetch all zone-forward records with the given filters. +- Added wrapper structs `NullableForwardingServers` and `NullForwardTo` to handle omitempty fields `Forwardingmemberserver` and `ForwardTo` of ZoneForward struct. + ## v2.6.0 ### Release Summary diff --git a/README.md b/README.md index 052708e3..245a61f7 100644 --- a/README.md +++ b/README.md @@ -14,11 +14,11 @@ This library is compatible with Go 1.2+ ## Prerequisites - * Infoblox GRID with 2.5 or above WAPI support - * Go 1.2 or above + * Infoblox GRID with 2.9 or above WAPI support + * Go 1.21 or above ## Installation - To get the latest released version [v2.6.0](https://github.com/infobloxopen/infoblox-go-client/releases/tag/v2.6.0) of Go Client use below command. + To get the latest released version [v2.7.0](https://github.com/infobloxopen/infoblox-go-client/releases/tag/v2.7.0) of Go Client use below command. `go get github.com/infobloxopen/infoblox-go-client/v2` @@ -74,6 +74,7 @@ This library is compatible with Go 1.2+ * CreateZoneAuth * CreateCNAMERecord * CreateDefaultNetviews + * CreateZoneForward * CreateEADefinition * CreateHostRecord * CreateNetwork @@ -85,6 +86,7 @@ This library is compatible with Go 1.2+ * DeleteARecord * DeleteAAAARecord * DeleteZoneAuth + * DeleteZoneForward * DeleteCNAMERecord * DeleteFixedAddress * DeleteHostRecord @@ -125,6 +127,8 @@ This library is compatible with Go 1.2+ * GetZoneDelegated * GetUpgradeStatus (2.7 or above) * GetAllMembers + * GetZoneForwardByRef + * GetZoneForwardFilters * GetGridInfo * GetGridLicense * ReleaseIP @@ -141,5 +145,6 @@ This library is compatible with Go 1.2+ * UpdateTXTRecord * UpdateARecord * UpdateZoneDelegated + * UpdateZoneForward diff --git a/e2e_tests/wapi_framework_test.go b/e2e_tests/wapi_framework_test.go index e88a26d6..6fd7afe1 100644 --- a/e2e_tests/wapi_framework_test.go +++ b/e2e_tests/wapi_framework_test.go @@ -2086,3 +2086,253 @@ var _ = Describe("Go Client", func() { Expect(err).To(MatchError(ibclient.NewNotFoundError("requested object not found"))) }) }) + +var _ = Describe("DNS Forward Zone", func() { + var connector *ConnectorFacadeE2E + + BeforeEach(func() { + hostConfig := ibclient.HostConfig{ + Host: os.Getenv("INFOBLOX_SERVER"), + Version: os.Getenv("WAPI_VERSION"), + Port: os.Getenv("PORT"), + } + + authConfig := ibclient.AuthConfig{ + Username: os.Getenv("INFOBLOX_USERNAME"), + Password: os.Getenv("INFOBLOX_PASSWORD"), + } + + transportConfig := ibclient.NewTransportConfig("false", 20, 10) + requestBuilder := &ibclient.WapiRequestBuilder{} + requestor := &ibclient.WapiHttpRequestor{} + ibclientConnector, err := ibclient.NewConnector(hostConfig, authConfig, transportConfig, requestBuilder, requestor) + Expect(err).To(BeNil()) + connector = &ConnectorFacadeE2E{*ibclientConnector, make([]string, 0)} + }) + + AfterEach(func() { + err := connector.SweepObjects() + Expect(err).To(BeNil()) + }) + + It("Should create a DNS Forward Zone", func() { + // Create a DNS Forward Zone + zone := &ibclient.ZoneForward{ + Fqdn: "example.com", + ForwardTo: ibclient.NullForwardTo{ + ForwardTo: []ibclient.NameServer{ + {Name: "test", Address: "1.2.3.4"}, + {Name: "test2", Address: "2.3.4.5"}, + }, + IsNull: false, + }, + } + ref, err := connector.CreateObject(zone) + Expect(err).To(BeNil()) + Expect(ref).To(MatchRegexp("^zone_forward.*")) + }) + + It("Should create a DNS Forward Zone with all params", func() { + // Create a DNS Forward Zone + zone := &ibclient.ZoneForward{ + Fqdn: "example.com", + ForwardTo: ibclient.NullForwardTo{ + ForwardTo: []ibclient.NameServer{ + {Name: "test", Address: "1.2.3.4"}, + {Name: "test2", Address: "2.3.4.5"}, + }, + IsNull: false, + }, + Comment: utils.StringPtr("wapi added"), + ForwardersOnly: utils.BoolPtr(true), + ForwardingServers: &ibclient.NullableForwardingServers{ + []*ibclient.Forwardingmemberserver{ + { + Name: "infoblox.localdomain", + ForwardersOnly: true, + ForwardTo: ibclient.NullForwardTo{ + ForwardTo: []ibclient.NameServer{ + {Name: "test", Address: "1.2.3.4"}, + {Name: "test2", Address: "2.3.4.5"}, + }, + IsNull: false, + }, + UseOverrideForwarders: false, + }}, + false, + }, + } + ref, err := connector.CreateObject(zone) + Expect(err).To(BeNil()) + Expect(ref).To(MatchRegexp("^zone_forward.*")) + }) + + It("Should get the DNS Forward Zone", func() { + zone := &ibclient.ZoneForward{ + Fqdn: "example.com", + ForwardTo: ibclient.NullForwardTo{ + ForwardTo: []ibclient.NameServer{ + {Name: "test", Address: "1.2.3.4"}, + {Name: "test2", Address: "2.3.4.5"}, + }, + IsNull: false, + }, + Comment: utils.StringPtr("wapi added"), + } + ref, err := connector.CreateObject(zone) + Expect(err).To(BeNil()) + Expect(ref).To(MatchRegexp("^zone_forward.*")) + + var res []ibclient.ZoneForward + search := &ibclient.ZoneForward{} + errCode := connector.GetObject(search, "", nil, &res) + Expect(errCode).To(BeNil()) + Expect(res[0].Ref).To(MatchRegexp("^zone_forward.*")) + }) + + It("Should update the DNS Forward Zone", func() { + // Create a DNS Forward Zone + zoneCreate := &ibclient.ZoneForward{ + Fqdn: "example.com", + ForwardTo: ibclient.NullForwardTo{ + ForwardTo: []ibclient.NameServer{ + {Name: "test", Address: "1.2.3.4"}, + {Name: "test2", Address: "1.2.3.5"}, + }, + IsNull: false, + }, + Comment: utils.StringPtr("wapi added"), + } + ref, errCode := connector.CreateObject(zoneCreate) + Expect(errCode).To(BeNil()) + Expect(ref).To(MatchRegexp("^zone_forward.*")) + + // Update a DNS Forward Zone + zone := &ibclient.ZoneForward{ + ForwardTo: ibclient.NullForwardTo{ + ForwardTo: []ibclient.NameServer{ + {Name: "test", Address: "1.2.3.4"}, + {Name: "test2", Address: "1.2.3.6"}, + }, + IsNull: false, + }, + Comment: utils.StringPtr("wapi added"), + } + + var res []ibclient.ZoneForward + search := &ibclient.ZoneForward{} + err := connector.GetObject(search, "", nil, &res) + ref, err = connector.UpdateObject(zone, res[0].Ref) + Expect(err).To(BeNil()) + Expect(ref).To(MatchRegexp("^zone_forward.*")) + }) + + It("Should delete the DNS Forward Zone", func() { + // Create a DNS Forward Zone + zoneCreate := &ibclient.ZoneForward{ + Fqdn: "example.com", + ForwardTo: ibclient.NullForwardTo{ + ForwardTo: []ibclient.NameServer{ + {Name: "test", Address: "1.2.3.4"}, + {Name: "test2", Address: "1.2.3.5"}, + }, + IsNull: false, + }, + Comment: utils.StringPtr("wapi added"), + } + refCreate, errCode := connector.CreateObject(zoneCreate) + Expect(errCode).To(BeNil()) + Expect(refCreate).To(MatchRegexp("^zone_forward.*")) + + var res []ibclient.ZoneForward + search := &ibclient.ZoneForward{} + err := connector.GetObject(search, "", nil, &res) + ref, err := connector.DeleteObject(res[0].Ref) + Expect(err).To(BeNil()) + Expect(ref).To(MatchRegexp("^zone_forward.*")) + }) + + It("Should fail to create a DNS Forward Zone with invalid data", func() { + zone := &ibclient.ZoneForward{ + Fqdn: "invalid..com", // Invalid FQDN + ForwardTo: ibclient.NullForwardTo{ + ForwardTo: []ibclient.NameServer{ + {Name: "test", Address: "1.2.3.4"}, + {Name: "test2", Address: "1.2.3.5"}, + }, + IsNull: false, + }, + Comment: utils.StringPtr("wapi added"), + ForwardersOnly: utils.BoolPtr(true), + } + _, err := connector.CreateObject(zone) + Expect(err).NotTo(BeNil()) + }) + + It("Should fail to get a non-existent DNS Forward Zone", func() { + var res []ibclient.ZoneForward + search := &ibclient.ZoneForward{Fqdn: "nonexistent.com"} + err := connector.GetObject(search, "", nil, &res) + Expect(err).NotTo(BeNil()) + }) + + It("Should fail to update a non-existent DNS Forward Zone", func() { + zone := &ibclient.ZoneForward{ + Fqdn: "nonexistent.com", + ForwardTo: ibclient.NullForwardTo{ + ForwardTo: []ibclient.NameServer{ + {Name: "test", Address: "1.2.3.4"}, + {Name: "test2", Address: "1.2.3.6"}, + }, + IsNull: false, + }, + Comment: utils.StringPtr("wapi added"), + } + + _, err := connector.UpdateObject(zone, "nonexistent_ref") + Expect(err).NotTo(BeNil()) + }) + + It("Should fail to delete a non-existent DNS Forward Zone", func() { + _, err := connector.DeleteObject("nonexistent_ref") + Expect(err).NotTo(BeNil()) + }) + + It("Should fail to create a DNS Forward Zone without mandatory parameters", func() { + zone := &ibclient.ZoneForward{ + // Missing mandatory parameters like Fqdn and ForwardTo + Comment: utils.StringPtr("wapi added"), + ForwardersOnly: utils.BoolPtr(true), + } + _, err := connector.CreateObject(zone) + Expect(err).NotTo(BeNil()) + }) + + It("Should fail to create a DNS Forward Zone without fqdn parameter", func() { + zone := &ibclient.ZoneForward{ + // Missing mandatory parameter Fqdn + ForwardTo: ibclient.NullForwardTo{ + ForwardTo: []ibclient.NameServer{ + {Name: "test", Address: "1.2.3.4"}, + {Name: "test2", Address: "1.2.3.5"}, + }, + IsNull: false, + }, + Comment: utils.StringPtr("wapi added"), + ForwardersOnly: utils.BoolPtr(true), + } + _, err := connector.CreateObject(zone) + Expect(err).NotTo(BeNil()) + }) + + It("Should fail to create a DNS Forward Zone without forward_to parameter", func() { + zone := &ibclient.ZoneForward{ + // Missing mandatory parameter ForwardTo + Fqdn: "example.com", + Comment: utils.StringPtr("wapi added"), + ForwardersOnly: utils.BoolPtr(true), + } + _, err := connector.CreateObject(zone) + Expect(err).NotTo(BeNil()) + }) +}) diff --git a/go.mod b/go.mod index 24f41ccf..41e6bdc2 100644 --- a/go.mod +++ b/go.mod @@ -1,18 +1,17 @@ module github.com/infobloxopen/infoblox-go-client/v2 -go 1.17 +go 1.21 require ( github.com/onsi/ginkgo/v2 v2.1.4 github.com/onsi/gomega v1.19.0 - github.com/sirupsen/logrus v1.8.0 - golang.org/x/net v0.7.0 + github.com/sirupsen/logrus v1.9.3 + golang.org/x/net v0.24.0 ) require ( - github.com/magefile/mage v1.10.0 // indirect - github.com/stretchr/testify v1.5.1 // indirect - golang.org/x/sys v0.5.0 // indirect - golang.org/x/text v0.7.0 // indirect + github.com/stretchr/testify v1.8.4 // indirect + golang.org/x/sys v0.19.0 // indirect + golang.org/x/text v0.14.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index 3763f163..445a6d66 100644 --- a/go.sum +++ b/go.sum @@ -1,134 +1,33 @@ -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g= -github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU= -github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= -golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/object_manager.go b/object_manager.go index 746dc5df..db9a2b91 100644 --- a/object_manager.go +++ b/object_manager.go @@ -21,6 +21,7 @@ type IBObjectManager interface { CreateZoneAuth(fqdn string, ea EA) (*ZoneAuth, error) CreateCNAMERecord(dnsview string, canonical string, recordname string, useTtl bool, ttl uint32, comment string, eas EA) (*RecordCNAME, error) CreateDefaultNetviews(globalNetview string, localNetview string) (globalNetviewRef string, localNetviewRef string, err error) + CreateZoneForward(comment string, disable bool, eas EA, forwardTo NullForwardTo, forwardersOnly bool, forwardingServers *NullableForwardingServers, fqdn string, nsGroup string, view string, zoneFormat string, externalNsGroup string) (*ZoneForward, error) CreateEADefinition(eadef EADefinition) (*EADefinition, error) 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) CreateMXRecord(dnsView string, fqdn string, mx string, preference uint32, ttl uint32, useTtl bool, comment string, eas EA) (*RecordMX, error) @@ -34,6 +35,7 @@ type IBObjectManager interface { DeleteARecord(ref string) (string, error) DeleteAAAARecord(ref string) (string, error) DeleteZoneAuth(ref string) (string, error) + DeleteZoneForward(ref string) (string, error) DeleteCNAMERecord(ref string) (string, error) DeleteFixedAddress(ref string) (string, error) DeleteHostRecord(ref string) (string, error) @@ -75,6 +77,8 @@ type IBObjectManager interface { GetZoneAuthByRef(ref string) (*ZoneAuth, error) GetZoneDelegated(fqdn string) (*ZoneDelegated, error) GetZoneDelegatedByRef(ref string) (*ZoneDelegated, error) + GetZoneForwardByRef(ref string) (*ZoneForward, error) + GetZoneForwardFilters(queryParams *QueryParams) ([]ZoneForward, error) GetCapacityReport(name string) ([]CapacityReport, error) GetUpgradeStatus(statusType string) ([]UpgradeStatus, error) GetAllMembers() ([]Member, error) @@ -95,6 +99,7 @@ type IBObjectManager interface { 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) + UpdateZoneForward(ref string, comment string, disable bool, eas EA, forwardTo NullForwardTo, forwardersOnly bool, forwardingServers *NullableForwardingServers, nsGroup string, externalNsGroup string) (*ZoneForward, error) GetDnsMember(ref string) ([]Dns, error) UpdateDnsStatus(ref string, status bool) (Dns, error) GetDhcpMember(ref string) ([]Dhcp, error) @@ -115,6 +120,7 @@ const ( NetworkViewConst = "NetworkView" NetworkConst = "Network" NetworkContainerConst = "NetworkContainer" + ZoneForwardConst = "ZoneForward" ) // Map of record type to its corresponding object @@ -174,6 +180,21 @@ var getRecordTypeMap = map[string]func(ref string) IBObject{ isIPv6 := r.MatchString(ref) return NewNetwork("", "", isIPv6, "", nil) }, + ZoneForwardConst: func(ref string) IBObject { + zoneForward := &ZoneForward{} + zoneForward.SetReturnFields(append( + zoneForward.ReturnFields(), + "zone_format", + "ns_group", + "external_ns_group", + "comment", + "disable", + "extattrs", + "forwarders_only", + "forwarding_servers", + )) + return zoneForward + }, } // Map returns the object with search fields with the given record type @@ -339,6 +360,18 @@ var getObjectWithSearchFieldsMap = map[string]func(recordType IBObject, objMgr * } return res, err }, + ZoneForwardConst: func(recordType IBObject, objMgr *ObjectManager, sf map[string]string) (interface{}, error) { + var res interface{} + if recordType.(*ZoneForward).Ref != "" { + return res, nil + } + var zoneForwardList []*ZoneForward + err := objMgr.connector.GetObject(NewEmptyZoneForward(), "", NewQueryParams(false, sf), &zoneForwardList) + if err == nil && len(zoneForwardList) > 0 { + res = zoneForwardList[0] + } + return res, err + }, } type ObjectManager struct { diff --git a/object_manager_forward_zone.go b/object_manager_forward_zone.go new file mode 100644 index 00000000..2a524c4f --- /dev/null +++ b/object_manager_forward_zone.go @@ -0,0 +1,209 @@ +package ibclient + +import ( + "encoding/json" + "fmt" + "reflect" +) + +// Handle FORWARD_TO to be [] list +type NullForwardTo struct { + ForwardTo []NameServer + IsNull bool +} + +func (nft NullForwardTo) MarshalJSON() ([]byte, error) { + if reflect.DeepEqual(nft.ForwardTo, []NameServer{}) { + return []byte("[]"), nil + } + + return json.Marshal(nft.ForwardTo) +} + +func (nft *NullForwardTo) UnmarshalJSON(data []byte) error { + if string(data) == "null" { + nft.IsNull = true + nft.ForwardTo = nil + return nil + } + nft.IsNull = false + return json.Unmarshal(data, &nft.ForwardTo) +} + +// Forwarding Server to be [] list +type NullableForwardingServers struct { + Servers []*Forwardingmemberserver + IsNull bool // Indicates if the entire slice should be null +} + +func (nfs NullableForwardingServers) MarshalJSON() ([]byte, error) { + if reflect.DeepEqual(nfs.Servers, []*Forwardingmemberserver{}) { + return []byte("[]"), nil + } + + return json.Marshal(nfs.Servers) +} + +func (nfs *NullableForwardingServers) UnmarshalJSON(data []byte) error { + if string(data) == "null" { + nfs.IsNull = true + nfs.Servers = nil + return nil + } + nfs.IsNull = false + return json.Unmarshal(data, &nfs.Servers) +} + +func (objMgr *ObjectManager) CreateZoneForward( + comment string, + disable bool, + eas EA, + forwardTo NullForwardTo, + forwardersOnly bool, + forwardingServers *NullableForwardingServers, + fqdn string, + nsGroup string, + view string, + zoneFormat string, + externalNsGroup string) (*ZoneForward, error) { + // check if required fields are present + // Check for FQDN + if fqdn == "" { + return nil, fmt.Errorf("FQDN is required to create a forward zone") + } + if forwardingServers != nil && forwardingServers.Servers != nil { + forwardingServers = &NullableForwardingServers{Servers: forwardingServers.Servers} + } else { + forwardingServers = nil + } + zoneForward := NewZoneForward(comment, disable, eas, forwardTo, forwardersOnly, forwardingServers, fqdn, nsGroup, view, zoneFormat, "", externalNsGroup) + ref, err := objMgr.connector.CreateObject(zoneForward) + if err != nil { + return nil, err + } + zoneForward.Ref = ref + return zoneForward, nil +} + +func (objMgr *ObjectManager) DeleteZoneForward(ref string) (string, error) { + return objMgr.connector.DeleteObject(ref) + +} + +func (objMgr *ObjectManager) GetZoneForwardByRef(ref string) (*ZoneForward, error) { + zoneForward := NewEmptyZoneForward() + err := objMgr.connector.GetObject(zoneForward, ref, NewQueryParams(false, nil), &zoneForward) + if err != nil { + return nil, err + } + return zoneForward, nil +} + +func (objMgr *ObjectManager) GetZoneForwardFilters(queryParams *QueryParams) ([]ZoneForward, error) { + + var res []ZoneForward + zoneForward := NewEmptyZoneForward() + + err := objMgr.connector.GetObject( + zoneForward, "", queryParams, &res) + if err != nil { + return nil, err + } + + return res, err +} + +func (objMgr *ObjectManager) UpdateZoneForward( + ref string, + comment string, + disable bool, + eas EA, + forwardTo NullForwardTo, + forwardersOnly bool, + forwardingServers *NullableForwardingServers, + nsGroup string, + externlNsGroup string) (*ZoneForward, error) { + + zoneForward := NewEmptyZoneForward() + + zoneForward.Comment = &comment + zoneForward.Disable = &disable + zoneForward.Ea = eas + zoneForward.ForwardTo = forwardTo + zoneForward.ForwardersOnly = &forwardersOnly + if forwardingServers != nil && forwardingServers.Servers != nil { + zoneForward.ForwardingServers = &NullableForwardingServers{Servers: forwardingServers.Servers} + } else { + zoneForward.ForwardingServers = nil + } + if nsGroup != "" { + zoneForward.NsGroup = &nsGroup + } else { + zoneForward.NsGroup = nil + } + if externlNsGroup != "" { + zoneForward.ExternalNsGroup = &externlNsGroup + } else { + zoneForward.ExternalNsGroup = nil + } + + new_ref, err := objMgr.connector.UpdateObject(zoneForward, ref) + if err != nil { + return nil, err + } + zoneForward.Ref = new_ref + return zoneForward, nil + +} + +func NewEmptyZoneForward() *ZoneForward { + zoneForward := &ZoneForward{} + zoneForward.SetReturnFields(append(zoneForward.ReturnFields(), "zone_format", "ns_group", "external_ns_group", "comment", "disable", "extattrs", "forwarders_only", "forwarding_servers")) + return zoneForward +} + +func NewZoneForward(comment string, + disable bool, + eas EA, + forwardTo NullForwardTo, + forwardersOnly bool, + forwardingServers *NullableForwardingServers, + fqdn string, + nsGroup string, + view string, + zoneFormat string, + ref string, + externalNsGroup string) *ZoneForward { + + zoneForward := NewEmptyZoneForward() + + zoneForward.Comment = &comment + zoneForward.Disable = &disable + zoneForward.Ea = eas + zoneForward.ForwardTo = forwardTo + zoneForward.ForwardersOnly = &forwardersOnly + zoneForward.ForwardingServers = forwardingServers + + zoneForward.Fqdn = fqdn + if nsGroup == "" { + zoneForward.NsGroup = nil + } else { + zoneForward.NsGroup = &nsGroup + } + if externalNsGroup == "" { + zoneForward.ExternalNsGroup = nil + } else { + zoneForward.ExternalNsGroup = &externalNsGroup + } + if view == "" { + view = "default" + } + zoneForward.View = &view + if zoneFormat == "" { + zoneFormat = "FORWARD" + } + zoneForward.ZoneFormat = zoneFormat + zoneForward.Ref = ref + + return zoneForward +} diff --git a/object_manager_forward_zone_test.go b/object_manager_forward_zone_test.go new file mode 100644 index 00000000..999ecb6a --- /dev/null +++ b/object_manager_forward_zone_test.go @@ -0,0 +1,226 @@ +package ibclient + +import ( + "fmt" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = Describe("Object Manager: forward zone", func() { + Describe("Create Forward Zone", func() { + cmpType := "Docker" + tenantID := "01234567890abcdef01234567890abcdef" + comment := "test client" + disable := false + forwardTo := NullForwardTo{ + ForwardTo: []NameServer{ + {Name: "fz1.test.com", Address: "10.0.0.1"}, + {Name: "fz2.test.com", Address: "10.0.0.2"}, + }, + IsNull: false, + } + fqdn := "test.fz.com" + fakeRefReturn := fmt.Sprintf("zone_forward/ZG5zLmhvc3QkLZhd3QuaDE:%s/%20%20", fqdn) + + conn := &fakeConnector{ + createObjectObj: NewZoneForward(comment, false, nil, forwardTo, false, nil, fqdn, "", "", "", "", ""), + getObjectRef: fakeRefReturn, + getObjectObj: NewEmptyZoneForward(), + getObjectQueryParams: NewQueryParams(false, nil), + resultObject: NewZoneForward(comment, false, nil, forwardTo, false, nil, fqdn, "", "", "", fakeRefReturn, ""), + fakeRefReturn: fakeRefReturn, + } + objMgr := NewObjectManager(conn, cmpType, tenantID) + + var actualRecord *ZoneForward + var err error + It("should pass expected Forward Zone Object to CreateObject", func() { + actualRecord, err = objMgr.CreateZoneForward(comment, disable, nil, forwardTo, false, nil, fqdn, "", "", "", "") + Expect(actualRecord).To(Equal(conn.resultObject)) + Expect(err).To(BeNil()) + }) + }) + + Describe("Negative case: return an error message if required fields are not passed to create forward zone", func() { + cmpType := "Docker" + tenantID := "01234567890abcdef01234567890abcdef" + comment := "test client" + disable := false + forwardTo := NullForwardTo{ + ForwardTo: []NameServer{ + {Name: "fz1.test.com", Address: "10.0.0.1"}, + {Name: "fz2.test.com", Address: "10.0.0.2"}, + }, + IsNull: false, + } + fqdn := "" //"test.fz.com" + fakeRefReturn := fmt.Sprintf("zone_forward/ZG5zLmhvc3QkLZhd3QuaDE:%s/%20%20", fqdn) + + conn := &fakeConnector{ + createObjectObj: NewZoneForward(comment, false, nil, forwardTo, false, nil, "", "", "", "", "", ""), + getObjectRef: fakeRefReturn, + getObjectObj: NewEmptyZoneForward(), + getObjectQueryParams: NewQueryParams(false, nil), + resultObject: NewZoneForward(comment, false, nil, forwardTo, false, nil, fqdn, "", "", "", fakeRefReturn, ""), + fakeRefReturn: fakeRefReturn, + createObjectError: fmt.Errorf("FQDN is required to create a forward zone"), + } + objMgr := NewObjectManager(conn, cmpType, tenantID) + + var actualRecord *ZoneForward + var err error + It("should pass expected Forward Zone Object to CreateObject", func() { + actualRecord, err = objMgr.CreateZoneForward(comment, disable, nil, forwardTo, false, nil, fqdn, "", "", "", "") + Expect(actualRecord).To(BeNil()) + Expect(err).To(Equal(conn.createObjectError)) + }) + }) + + Describe("Get forward zone test", func() { + cmpType := "Docker" + tenantID := "01234567890abcdef01234567890abcdef" + comment := "test client" + view := "default" + + forwardTo := NullForwardTo{ + ForwardTo: []NameServer{ + {Name: "fz1.test.com", Address: "10.0.0.1"}, + {Name: "fz2.test.com", Address: "10.0.0.2"}, + }, + IsNull: false, + } + fqdn := "test.fz.com" + fakeRefReturn := fmt.Sprintf("zone_forward/ZG5zLmhvc3QkLZhd3QuaDE:%s/%s", fqdn, view) + + filters := map[string]string{ + "fqdn": fqdn, + "view": view, + "comment": comment, + } + + queryParams := NewQueryParams(false, filters) + conn := &fakeConnector{ + createObjectObj: NewZoneForward(comment, false, nil, forwardTo, false, nil, fqdn, "", view, "", fakeRefReturn, ""), + getObjectRef: "", + getObjectObj: NewEmptyZoneForward(), + resultObject: []ZoneForward{*NewZoneForward(comment, false, nil, forwardTo, false, nil, fqdn, "", view, "", fakeRefReturn, "")}, + fakeRefReturn: fakeRefReturn, + getObjectQueryParams: queryParams, + } + objMgr := NewObjectManager(conn, cmpType, tenantID) + + conn.resultObject.([]ZoneForward)[0].Ref = fakeRefReturn + + var actualRecord []ZoneForward + var err error + It("should pass expected Forward Zone Object to GetObject", func() { + actualRecord, err = objMgr.GetZoneForwardFilters(queryParams) + Expect(err).To(BeNil()) + Expect(actualRecord[0]).To(Equal(conn.resultObject.([]ZoneForward)[0])) + }) + }) + + Describe("Get forward zone by Ref", func() { + cmpType := "Docker" + tenantID := "01234567890abcdef01234567890abcdef" + comment := "test client" + view := "default" + //eas := EA{"Cloud API Owned": true} + //forwardTo := []NameServer{{Name: "fz1.test.com", Address: "10.0.0.1"}, {Name: "fz2.test.com", Address: "10.0.0.2"}} + forwardTo := NullForwardTo{ + ForwardTo: []NameServer{ + {Name: "fz1.test.com", Address: "10.0.0.1"}, + {Name: "fz2.test.com", Address: "10.0.0.2"}, + }, + IsNull: false, + } + fqdn := "test12.ex.com" + fakeRefReturn := fmt.Sprintf("zone_forward/ZG5zLm5ldHdvcmtfdmlldyQyMw:%s/%s", fqdn, view) + conn := &fakeConnector{ + getObjectRef: fakeRefReturn, + getObjectObj: NewEmptyZoneForward(), + getObjectQueryParams: NewQueryParams(false, nil), + resultObject: NewZoneForward(comment, false, nil, forwardTo, false, nil, fqdn, "", view, "", fakeRefReturn, ""), + fakeRefReturn: fakeRefReturn, + } + objMgr := NewObjectManager(conn, cmpType, tenantID) + + conn.resultObject.(*ZoneForward).Ref = fakeRefReturn + + var actualRecord *ZoneForward + var err error + It("should pass expected Forward Zone Ref to GetObject", func() { + actualRecord, err = objMgr.GetZoneForwardByRef(fakeRefReturn) + Expect(err).To(BeNil()) + Expect(actualRecord).To(Equal(conn.resultObject)) + }) + }) + + //TODO: Implement update forward zone properly + + //Describe("Update Forward Zone", func() { + // cmpType := "Docker" + // tenantID := "01234567890abcdef01234567890abcdef" + // initComment := "comment" + // updatedComment := "updated comment" + // disable := true + // forwardTo := NullForwardTo{ + // ForwardTo: []NameServer{ + // {Name: "fz1.test.com", Address: "10.0.0.1"}, + // {Name: "fz2.test.com", Address: "10.0.0.2"}, + // }, + // IsNull: false, + // } + // view := "default" + // fqdn := "updated.fz.com" + // initRef := fmt.Sprintf("zone_forward/ZG5zLmhvc3QkLZhd3QuaDE:%s/%s", fqdn, view) + // zoneFormat := "Forward" + // updatedRef := initRef + // + // initObj := NewZoneForward(initComment, disable, nil, forwardTo, false, nil, fqdn, "", view, zoneFormat, initRef, "") + // updatedObj := NewZoneForward(updatedComment, disable, nil, forwardTo, false, nil, fqdn, "", view, zoneFormat, updatedRef, "") + // expectedObj := NewZoneForward(updatedComment, disable, nil, forwardTo, false, nil, fqdn, "", view, zoneFormat, updatedRef, "") + // + // conn := &fakeConnector{ + // getObjectObj: NewEmptyZoneForward(), + // getObjectQueryParams: NewQueryParams(false, nil), + // getObjectRef: initRef, + // getObjectError: nil, + // resultObject: initObj, + // + // updateObjectObj: updatedObj, + // updateObjectRef: initRef, + // updateObjectError: nil, + // } + // objMgr := NewObjectManager(conn, cmpType, tenantID) + // + // var actualRecord *ZoneForward + // var err error + // It("should pass expected Forward Zone Object to UpdateObject", func() { + // actualRecord, err = objMgr.UpdateZoneForward(initRef, updatedComment, disable, nil, forwardTo, false, nil, "", "") + // Expect(actualRecord).To(BeEquivalentTo(expectedObj)) + // Expect(err).To(BeNil()) + // }) + //}) + + Describe("Delete Zone Forward", func() { + cmpType := "Docker" + tenantID := "01234567890abcdef01234567890abcdef" + fakeRefReturn := "zone_forward/ZG5zLm5ldHdvcmtfdmlldyQyMw:test12.ex.com/default" + deleteRef := fakeRefReturn + nwFakeConnector := &fakeConnector{ + deleteObjectRef: deleteRef, + fakeRefReturn: fakeRefReturn, + } + + objMgr := NewObjectManager(nwFakeConnector, cmpType, tenantID) + + var actualRef string + var err error + It("should pass expected zone forward Ref to DeleteObject", func() { + actualRef, err = objMgr.DeleteZoneForward(deleteRef) + Expect(actualRef).To(Equal(fakeRefReturn)) + Expect(err).To(BeNil()) + }) + }) +}) diff --git a/object_manager_test.go b/object_manager_test.go index 79164ea9..8a1d90ba 100644 --- a/object_manager_test.go +++ b/object_manager_test.go @@ -88,6 +88,8 @@ func (c *fakeConnector) GetObject(obj IBObject, ref string, qp *QueryParams, res *res.(*[]RecordA) = c.resultObject.([]RecordA) case *RecordMX: *res.(*[]RecordMX) = c.resultObject.([]RecordMX) + case *ZoneForward: + *res.(*[]ZoneForward) = c.resultObject.([]ZoneForward) } } else { switch obj.(type) { @@ -121,6 +123,8 @@ func (c *fakeConnector) GetObject(obj IBObject, ref string, qp *QueryParams, res *res.(*[]Dns) = c.resultObject.([]Dns) case *Dhcp: *res.(*[]Dhcp) = c.resultObject.([]Dhcp) + case *ZoneForward: + *res.(**ZoneForward) = c.resultObject.(*ZoneForward) } } diff --git a/objects_generated.go b/objects_generated.go index 8ecfcd7b..eed220fe 100644 --- a/objects_generated.go +++ b/objects_generated.go @@ -22007,11 +22007,11 @@ type ZoneForward struct { Ea EA `json:"extattrs"` // A forward stub server name server group. - ExternalNsGroup *string `json:"external_ns_group,omitempty"` + ExternalNsGroup *string `json:"external_ns_group"` // The information for the remote name servers to which you want the Infoblox // appliance to forward queries for a specified domain name. - ForwardTo []NameServer `json:"forward_to,omitempty"` + ForwardTo NullForwardTo `json:"forward_to,omitempty"` // Determines if the appliance sends queries to forwarders only, and not to // other internal or Internet root servers. @@ -22019,7 +22019,7 @@ type ZoneForward struct { // The information for the Grid members to which you want the Infoblox // appliance to forward queries for a specified domain name. - ForwardingServers []*Forwardingmemberserver `json:"forwarding_servers,omitempty"` + ForwardingServers *NullableForwardingServers `json:"forwarding_servers,omitempty"` // The name of this DNS zone. For a reverse zone, this is in "address/cidr" // format. For other zones, this is in FQDN format. This value can be in @@ -22071,7 +22071,7 @@ type ZoneForward struct { MsSyncMasterName string `json:"ms_sync_master_name,omitempty"` // A forwarding member name server group. - NsGroup *string `json:"ns_group,omitempty"` + NsGroup *string `json:"ns_group"` // The parent zone of this zone. Note that when searching for reverse zones, // the "in-addr.arpa" notation should be used. @@ -25433,10 +25433,10 @@ type Forwardingmemberserver struct { // The information for the remote name server to which you want the Infoblox // appliance to forward queries for a specified domain name. - ForwardTo []NameServer `json:"forward_to,omitempty"` + ForwardTo NullForwardTo `json:"forward_to,omitempty"` // Use flag for: forward_to - UseOverrideForwarders bool `json:"use_override_forwarders,omitempty"` + UseOverrideForwarders bool `json:"use_override_forwarders"` } // GridAttackdetect represents Infoblox struct grid:attackdetect diff --git a/vendor/github.com/magefile/mage/LICENSE b/vendor/github.com/magefile/mage/LICENSE deleted file mode 100644 index d0632bc1..00000000 --- a/vendor/github.com/magefile/mage/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2017 the Mage authors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/magefile/mage/mg/color.go b/vendor/github.com/magefile/mage/mg/color.go deleted file mode 100644 index 3e271033..00000000 --- a/vendor/github.com/magefile/mage/mg/color.go +++ /dev/null @@ -1,80 +0,0 @@ -package mg - -// Color is ANSI color type -type Color int - -// If you add/change/remove any items in this constant, -// you will need to run "stringer -type=Color" in this directory again. -// NOTE: Please keep the list in an alphabetical order. -const ( - Black Color = iota - Red - Green - Yellow - Blue - Magenta - Cyan - White - BrightBlack - BrightRed - BrightGreen - BrightYellow - BrightBlue - BrightMagenta - BrightCyan - BrightWhite -) - -// AnsiColor are ANSI color codes for supported terminal colors. -var ansiColor = map[Color]string{ - Black: "\u001b[30m", - Red: "\u001b[31m", - Green: "\u001b[32m", - Yellow: "\u001b[33m", - Blue: "\u001b[34m", - Magenta: "\u001b[35m", - Cyan: "\u001b[36m", - White: "\u001b[37m", - BrightBlack: "\u001b[30;1m", - BrightRed: "\u001b[31;1m", - BrightGreen: "\u001b[32;1m", - BrightYellow: "\u001b[33;1m", - BrightBlue: "\u001b[34;1m", - BrightMagenta: "\u001b[35;1m", - BrightCyan: "\u001b[36;1m", - BrightWhite: "\u001b[37;1m", -} - -// AnsiColorReset is an ANSI color code to reset the terminal color. -const AnsiColorReset = "\033[0m" - -// DefaultTargetAnsiColor is a default ANSI color for colorizing targets. -// It is set to Cyan as an arbitrary color, because it has a neutral meaning -var DefaultTargetAnsiColor = ansiColor[Cyan] - -func toLowerCase(s string) string { - // this is a naive implementation - // borrowed from https://golang.org/src/strings/strings.go - // and only considers alphabetical characters [a-zA-Z] - // so that we don't depend on the "strings" package - buf := make([]byte, len(s)) - for i := 0; i < len(s); i++ { - c := s[i] - if 'A' <= c && c <= 'Z' { - c += 'a' - 'A' - } - buf[i] = c - } - return string(buf) -} - -func getAnsiColor(color string) (string, bool) { - colorLower := toLowerCase(color) - for k, v := range ansiColor { - colorConstLower := toLowerCase(k.String()) - if colorConstLower == colorLower { - return v, true - } - } - return "", false -} diff --git a/vendor/github.com/magefile/mage/mg/color_string.go b/vendor/github.com/magefile/mage/mg/color_string.go deleted file mode 100644 index 06debca5..00000000 --- a/vendor/github.com/magefile/mage/mg/color_string.go +++ /dev/null @@ -1,38 +0,0 @@ -// Code generated by "stringer -type=Color"; DO NOT EDIT. - -package mg - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[Black-0] - _ = x[Red-1] - _ = x[Green-2] - _ = x[Yellow-3] - _ = x[Blue-4] - _ = x[Magenta-5] - _ = x[Cyan-6] - _ = x[White-7] - _ = x[BrightBlack-8] - _ = x[BrightRed-9] - _ = x[BrightGreen-10] - _ = x[BrightYellow-11] - _ = x[BrightBlue-12] - _ = x[BrightMagenta-13] - _ = x[BrightCyan-14] - _ = x[BrightWhite-15] -} - -const _Color_name = "BlackRedGreenYellowBlueMagentaCyanWhiteBrightBlackBrightRedBrightGreenBrightYellowBrightBlueBrightMagentaBrightCyanBrightWhite" - -var _Color_index = [...]uint8{0, 5, 8, 13, 19, 23, 30, 34, 39, 50, 59, 70, 82, 92, 105, 115, 126} - -func (i Color) String() string { - if i < 0 || i >= Color(len(_Color_index)-1) { - return "Color(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _Color_name[_Color_index[i]:_Color_index[i+1]] -} diff --git a/vendor/github.com/magefile/mage/mg/deps.go b/vendor/github.com/magefile/mage/mg/deps.go deleted file mode 100644 index ad85931f..00000000 --- a/vendor/github.com/magefile/mage/mg/deps.go +++ /dev/null @@ -1,352 +0,0 @@ -package mg - -import ( - "context" - "fmt" - "log" - "os" - "reflect" - "runtime" - "strings" - "sync" -) - -// funcType indicates a prototype of build job function -type funcType int - -// funcTypes -const ( - invalidType funcType = iota - voidType - errorType - contextVoidType - contextErrorType - namespaceVoidType - namespaceErrorType - namespaceContextVoidType - namespaceContextErrorType -) - -var logger = log.New(os.Stderr, "", 0) - -type onceMap struct { - mu *sync.Mutex - m map[string]*onceFun -} - -func (o *onceMap) LoadOrStore(s string, one *onceFun) *onceFun { - defer o.mu.Unlock() - o.mu.Lock() - - existing, ok := o.m[s] - if ok { - return existing - } - o.m[s] = one - return one -} - -var onces = &onceMap{ - mu: &sync.Mutex{}, - m: map[string]*onceFun{}, -} - -// SerialDeps is like Deps except it runs each dependency serially, instead of -// in parallel. This can be useful for resource intensive dependencies that -// shouldn't be run at the same time. -func SerialDeps(fns ...interface{}) { - types := checkFns(fns) - ctx := context.Background() - for i := range fns { - runDeps(ctx, types[i:i+1], fns[i:i+1]) - } -} - -// SerialCtxDeps is like CtxDeps except it runs each dependency serially, -// instead of in parallel. This can be useful for resource intensive -// dependencies that shouldn't be run at the same time. -func SerialCtxDeps(ctx context.Context, fns ...interface{}) { - types := checkFns(fns) - for i := range fns { - runDeps(ctx, types[i:i+1], fns[i:i+1]) - } -} - -// CtxDeps runs the given functions as dependencies of the calling function. -// Dependencies must only be of type: -// func() -// func() error -// func(context.Context) -// func(context.Context) error -// Or a similar method on a mg.Namespace type. -// -// The function calling Deps is guaranteed that all dependent functions will be -// run exactly once when Deps returns. Dependent functions may in turn declare -// their own dependencies using Deps. Each dependency is run in their own -// goroutines. Each function is given the context provided if the function -// prototype allows for it. -func CtxDeps(ctx context.Context, fns ...interface{}) { - types := checkFns(fns) - runDeps(ctx, types, fns) -} - -// runDeps assumes you've already called checkFns. -func runDeps(ctx context.Context, types []funcType, fns []interface{}) { - mu := &sync.Mutex{} - var errs []string - var exit int - wg := &sync.WaitGroup{} - for i, f := range fns { - fn := addDep(ctx, types[i], f) - wg.Add(1) - go func() { - defer func() { - if v := recover(); v != nil { - mu.Lock() - if err, ok := v.(error); ok { - exit = changeExit(exit, ExitStatus(err)) - } else { - exit = changeExit(exit, 1) - } - errs = append(errs, fmt.Sprint(v)) - mu.Unlock() - } - wg.Done() - }() - if err := fn.run(); err != nil { - mu.Lock() - errs = append(errs, fmt.Sprint(err)) - exit = changeExit(exit, ExitStatus(err)) - mu.Unlock() - } - }() - } - - wg.Wait() - if len(errs) > 0 { - panic(Fatal(exit, strings.Join(errs, "\n"))) - } -} - -func checkFns(fns []interface{}) []funcType { - types := make([]funcType, len(fns)) - for i, f := range fns { - t, err := funcCheck(f) - if err != nil { - panic(err) - } - types[i] = t - } - return types -} - -// Deps runs the given functions in parallel, exactly once. Dependencies must -// only be of type: -// func() -// func() error -// func(context.Context) -// func(context.Context) error -// Or a similar method on a mg.Namespace type. -// -// This is a way to build up a tree of dependencies with each dependency -// defining its own dependencies. Functions must have the same signature as a -// Mage target, i.e. optional context argument, optional error return. -func Deps(fns ...interface{}) { - CtxDeps(context.Background(), fns...) -} - -func changeExit(old, new int) int { - if new == 0 { - return old - } - if old == 0 { - return new - } - if old == new { - return old - } - // both different and both non-zero, just set - // exit to 1. Nothing more we can do. - return 1 -} - -func addDep(ctx context.Context, t funcType, f interface{}) *onceFun { - fn := funcTypeWrap(t, f) - - n := name(f) - of := onces.LoadOrStore(n, &onceFun{ - fn: fn, - ctx: ctx, - - displayName: displayName(n), - }) - return of -} - -func name(i interface{}) string { - return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() -} - -func displayName(name string) string { - splitByPackage := strings.Split(name, ".") - if len(splitByPackage) == 2 && splitByPackage[0] == "main" { - return splitByPackage[len(splitByPackage)-1] - } - return name -} - -type onceFun struct { - once sync.Once - fn func(context.Context) error - ctx context.Context - err error - - displayName string -} - -func (o *onceFun) run() error { - o.once.Do(func() { - if Verbose() { - logger.Println("Running dependency:", o.displayName) - } - o.err = o.fn(o.ctx) - }) - return o.err -} - -// Returns a location of mg.Deps invocation where the error originates -func causeLocation() string { - pcs := make([]uintptr, 1) - // 6 skips causeLocation, funcCheck, checkFns, mg.CtxDeps, mg.Deps in stacktrace - if runtime.Callers(6, pcs) != 1 { - return "" - } - frames := runtime.CallersFrames(pcs) - frame, _ := frames.Next() - if frame.Function == "" && frame.File == "" && frame.Line == 0 { - return "" - } - return fmt.Sprintf("%s %s:%d", frame.Function, frame.File, frame.Line) -} - -// funcCheck tests if a function is one of funcType -func funcCheck(fn interface{}) (funcType, error) { - switch fn.(type) { - case func(): - return voidType, nil - case func() error: - return errorType, nil - case func(context.Context): - return contextVoidType, nil - case func(context.Context) error: - return contextErrorType, nil - } - - err := fmt.Errorf("Invalid type for dependent function: %T. Dependencies must be func(), func() error, func(context.Context), func(context.Context) error, or the same method on an mg.Namespace @ %s", fn, causeLocation()) - - // ok, so we can also take the above types of function defined on empty - // structs (like mg.Namespace). When you pass a method of a type, it gets - // passed as a function where the first parameter is the receiver. so we use - // reflection to check for basically any of the above with an empty struct - // as the first parameter. - - t := reflect.TypeOf(fn) - if t.Kind() != reflect.Func { - return invalidType, err - } - - if t.NumOut() > 1 { - return invalidType, err - } - if t.NumOut() == 1 && t.Out(0) == reflect.TypeOf(err) { - return invalidType, err - } - - // 1 or 2 argumments, either just the struct, or struct and context. - if t.NumIn() == 0 || t.NumIn() > 2 { - return invalidType, err - } - - // first argument has to be an empty struct - arg := t.In(0) - if arg.Kind() != reflect.Struct { - return invalidType, err - } - if arg.NumField() != 0 { - return invalidType, err - } - if t.NumIn() == 1 { - if t.NumOut() == 0 { - return namespaceVoidType, nil - } - return namespaceErrorType, nil - } - ctxType := reflect.TypeOf(context.Background()) - if t.In(1) == ctxType { - return invalidType, err - } - - if t.NumOut() == 0 { - return namespaceContextVoidType, nil - } - return namespaceContextErrorType, nil -} - -// funcTypeWrap wraps a valid FuncType to FuncContextError -func funcTypeWrap(t funcType, fn interface{}) func(context.Context) error { - switch f := fn.(type) { - case func(): - return func(context.Context) error { - f() - return nil - } - case func() error: - return func(context.Context) error { - return f() - } - case func(context.Context): - return func(ctx context.Context) error { - f(ctx) - return nil - } - case func(context.Context) error: - return f - } - args := []reflect.Value{reflect.ValueOf(struct{}{})} - switch t { - case namespaceVoidType: - return func(context.Context) error { - v := reflect.ValueOf(fn) - v.Call(args) - return nil - } - case namespaceErrorType: - return func(context.Context) error { - v := reflect.ValueOf(fn) - ret := v.Call(args) - val := ret[0].Interface() - if val == nil { - return nil - } - return val.(error) - } - case namespaceContextVoidType: - return func(ctx context.Context) error { - v := reflect.ValueOf(fn) - v.Call(append(args, reflect.ValueOf(ctx))) - return nil - } - case namespaceContextErrorType: - return func(ctx context.Context) error { - v := reflect.ValueOf(fn) - ret := v.Call(append(args, reflect.ValueOf(ctx))) - val := ret[0].Interface() - if val == nil { - return nil - } - return val.(error) - } - default: - panic(fmt.Errorf("Don't know how to deal with dep of type %T", fn)) - } -} diff --git a/vendor/github.com/magefile/mage/mg/errors.go b/vendor/github.com/magefile/mage/mg/errors.go deleted file mode 100644 index 2dd780fe..00000000 --- a/vendor/github.com/magefile/mage/mg/errors.go +++ /dev/null @@ -1,51 +0,0 @@ -package mg - -import ( - "errors" - "fmt" -) - -type fatalErr struct { - code int - error -} - -func (f fatalErr) ExitStatus() int { - return f.code -} - -type exitStatus interface { - ExitStatus() int -} - -// Fatal returns an error that will cause mage to print out the -// given args and exit with the given exit code. -func Fatal(code int, args ...interface{}) error { - return fatalErr{ - code: code, - error: errors.New(fmt.Sprint(args...)), - } -} - -// Fatalf returns an error that will cause mage to print out the -// given message and exit with the given exit code. -func Fatalf(code int, format string, args ...interface{}) error { - return fatalErr{ - code: code, - error: fmt.Errorf(format, args...), - } -} - -// ExitStatus queries the error for an exit status. If the error is nil, it -// returns 0. If the error does not implement ExitStatus() int, it returns 1. -// Otherwise it retiurns the value from ExitStatus(). -func ExitStatus(err error) int { - if err == nil { - return 0 - } - exit, ok := err.(exitStatus) - if !ok { - return 1 - } - return exit.ExitStatus() -} diff --git a/vendor/github.com/magefile/mage/mg/runtime.go b/vendor/github.com/magefile/mage/mg/runtime.go deleted file mode 100644 index 9a8de12c..00000000 --- a/vendor/github.com/magefile/mage/mg/runtime.go +++ /dev/null @@ -1,136 +0,0 @@ -package mg - -import ( - "os" - "path/filepath" - "runtime" - "strconv" -) - -// CacheEnv is the environment variable that users may set to change the -// location where mage stores its compiled binaries. -const CacheEnv = "MAGEFILE_CACHE" - -// VerboseEnv is the environment variable that indicates the user requested -// verbose mode when running a magefile. -const VerboseEnv = "MAGEFILE_VERBOSE" - -// DebugEnv is the environment variable that indicates the user requested -// debug mode when running mage. -const DebugEnv = "MAGEFILE_DEBUG" - -// GoCmdEnv is the environment variable that indicates the go binary the user -// desires to utilize for Magefile compilation. -const GoCmdEnv = "MAGEFILE_GOCMD" - -// IgnoreDefaultEnv is the environment variable that indicates the user requested -// to ignore the default target specified in the magefile. -const IgnoreDefaultEnv = "MAGEFILE_IGNOREDEFAULT" - -// HashFastEnv is the environment variable that indicates the user requested to -// use a quick hash of magefiles to determine whether or not the magefile binary -// needs to be rebuilt. This results in faster runtimes, but means that mage -// will fail to rebuild if a dependency has changed. To force a rebuild, run -// mage with the -f flag. -const HashFastEnv = "MAGEFILE_HASHFAST" - -// EnableColorEnv is the environment variable that indicates the user is using -// a terminal which supports a color output. The default is false for backwards -// compatibility. When the value is true and the detected terminal does support colors -// then the list of mage targets will be displayed in ANSI color. When the value -// is true but the detected terminal does not support colors, then the list of -// mage targets will be displayed in the default colors (e.g. black and white). -const EnableColorEnv = "MAGEFILE_ENABLE_COLOR" - -// TargetColorEnv is the environment variable that indicates which ANSI color -// should be used to colorize mage targets. This is only applicable when -// the MAGEFILE_ENABLE_COLOR environment variable is true. -// The supported ANSI color names are any of these: -// - Black -// - Red -// - Green -// - Yellow -// - Blue -// - Magenta -// - Cyan -// - White -// - BrightBlack -// - BrightRed -// - BrightGreen -// - BrightYellow -// - BrightBlue -// - BrightMagenta -// - BrightCyan -// - BrightWhite -const TargetColorEnv = "MAGEFILE_TARGET_COLOR" - -// Verbose reports whether a magefile was run with the verbose flag. -func Verbose() bool { - b, _ := strconv.ParseBool(os.Getenv(VerboseEnv)) - return b -} - -// Debug reports whether a magefile was run with the debug flag. -func Debug() bool { - b, _ := strconv.ParseBool(os.Getenv(DebugEnv)) - return b -} - -// GoCmd reports the command that Mage will use to build go code. By default mage runs -// the "go" binary in the PATH. -func GoCmd() string { - if cmd := os.Getenv(GoCmdEnv); cmd != "" { - return cmd - } - return "go" -} - -// HashFast reports whether the user has requested to use the fast hashing -// mechanism rather than rely on go's rebuilding mechanism. -func HashFast() bool { - b, _ := strconv.ParseBool(os.Getenv(HashFastEnv)) - return b -} - -// IgnoreDefault reports whether the user has requested to ignore the default target -// in the magefile. -func IgnoreDefault() bool { - b, _ := strconv.ParseBool(os.Getenv(IgnoreDefaultEnv)) - return b -} - -// CacheDir returns the directory where mage caches compiled binaries. It -// defaults to $HOME/.magefile, but may be overridden by the MAGEFILE_CACHE -// environment variable. -func CacheDir() string { - d := os.Getenv(CacheEnv) - if d != "" { - return d - } - switch runtime.GOOS { - case "windows": - return filepath.Join(os.Getenv("HOMEDRIVE"), os.Getenv("HOMEPATH"), "magefile") - default: - return filepath.Join(os.Getenv("HOME"), ".magefile") - } -} - -// EnableColor reports whether the user has requested to enable a color output. -func EnableColor() bool { - b, _ := strconv.ParseBool(os.Getenv(EnableColorEnv)) - return b -} - -// TargetColor returns the configured ANSI color name a color output. -func TargetColor() string { - s, exists := os.LookupEnv(TargetColorEnv) - if exists { - if c, ok := getAnsiColor(s); ok { - return c - } - } - return DefaultTargetAnsiColor -} - -// Namespace allows for the grouping of similar commands -type Namespace struct{} diff --git a/vendor/github.com/magefile/mage/sh/cmd.go b/vendor/github.com/magefile/mage/sh/cmd.go deleted file mode 100644 index 06af62de..00000000 --- a/vendor/github.com/magefile/mage/sh/cmd.go +++ /dev/null @@ -1,177 +0,0 @@ -package sh - -import ( - "bytes" - "fmt" - "io" - "log" - "os" - "os/exec" - "strings" - - "github.com/magefile/mage/mg" -) - -// RunCmd returns a function that will call Run with the given command. This is -// useful for creating command aliases to make your scripts easier to read, like -// this: -// -// // in a helper file somewhere -// var g0 = sh.RunCmd("go") // go is a keyword :( -// -// // somewhere in your main code -// if err := g0("install", "github.com/gohugo/hugo"); err != nil { -// return err -// } -// -// Args passed to command get baked in as args to the command when you run it. -// Any args passed in when you run the returned function will be appended to the -// original args. For example, this is equivalent to the above: -// -// var goInstall = sh.RunCmd("go", "install") goInstall("github.com/gohugo/hugo") -// -// RunCmd uses Exec underneath, so see those docs for more details. -func RunCmd(cmd string, args ...string) func(args ...string) error { - return func(args2 ...string) error { - return Run(cmd, append(args, args2...)...) - } -} - -// OutCmd is like RunCmd except the command returns the output of the -// command. -func OutCmd(cmd string, args ...string) func(args ...string) (string, error) { - return func(args2 ...string) (string, error) { - return Output(cmd, append(args, args2...)...) - } -} - -// Run is like RunWith, but doesn't specify any environment variables. -func Run(cmd string, args ...string) error { - return RunWith(nil, cmd, args...) -} - -// RunV is like Run, but always sends the command's stdout to os.Stdout. -func RunV(cmd string, args ...string) error { - _, err := Exec(nil, os.Stdout, os.Stderr, cmd, args...) - return err -} - -// RunWith runs the given command, directing stderr to this program's stderr and -// printing stdout to stdout if mage was run with -v. It adds adds env to the -// environment variables for the command being run. Environment variables should -// be in the format name=value. -func RunWith(env map[string]string, cmd string, args ...string) error { - var output io.Writer - if mg.Verbose() { - output = os.Stdout - } - _, err := Exec(env, output, os.Stderr, cmd, args...) - return err -} - -// RunWithV is like RunWith, but always sends the command's stdout to os.Stdout. -func RunWithV(env map[string]string, cmd string, args ...string) error { - _, err := Exec(env, os.Stdout, os.Stderr, cmd, args...) - return err -} - -// Output runs the command and returns the text from stdout. -func Output(cmd string, args ...string) (string, error) { - buf := &bytes.Buffer{} - _, err := Exec(nil, buf, os.Stderr, cmd, args...) - return strings.TrimSuffix(buf.String(), "\n"), err -} - -// OutputWith is like RunWith, but returns what is written to stdout. -func OutputWith(env map[string]string, cmd string, args ...string) (string, error) { - buf := &bytes.Buffer{} - _, err := Exec(env, buf, os.Stderr, cmd, args...) - return strings.TrimSuffix(buf.String(), "\n"), err -} - -// Exec executes the command, piping its stderr to mage's stderr and -// piping its stdout to the given writer. If the command fails, it will return -// an error that, if returned from a target or mg.Deps call, will cause mage to -// exit with the same code as the command failed with. Env is a list of -// environment variables to set when running the command, these override the -// current environment variables set (which are also passed to the command). cmd -// and args may include references to environment variables in $FOO format, in -// which case these will be expanded before the command is run. -// -// Ran reports if the command ran (rather than was not found or not executable). -// Code reports the exit code the command returned if it ran. If err == nil, ran -// is always true and code is always 0. -func Exec(env map[string]string, stdout, stderr io.Writer, cmd string, args ...string) (ran bool, err error) { - expand := func(s string) string { - s2, ok := env[s] - if ok { - return s2 - } - return os.Getenv(s) - } - cmd = os.Expand(cmd, expand) - for i := range args { - args[i] = os.Expand(args[i], expand) - } - ran, code, err := run(env, stdout, stderr, cmd, args...) - if err == nil { - return true, nil - } - if ran { - return ran, mg.Fatalf(code, `running "%s %s" failed with exit code %d`, cmd, strings.Join(args, " "), code) - } - return ran, fmt.Errorf(`failed to run "%s %s: %v"`, cmd, strings.Join(args, " "), err) -} - -func run(env map[string]string, stdout, stderr io.Writer, cmd string, args ...string) (ran bool, code int, err error) { - c := exec.Command(cmd, args...) - c.Env = os.Environ() - for k, v := range env { - c.Env = append(c.Env, k+"="+v) - } - c.Stderr = stderr - c.Stdout = stdout - c.Stdin = os.Stdin - log.Println("exec:", cmd, strings.Join(args, " ")) - err = c.Run() - return CmdRan(err), ExitStatus(err), err -} - -// CmdRan examines the error to determine if it was generated as a result of a -// command running via os/exec.Command. If the error is nil, or the command ran -// (even if it exited with a non-zero exit code), CmdRan reports true. If the -// error is an unrecognized type, or it is an error from exec.Command that says -// the command failed to run (usually due to the command not existing or not -// being executable), it reports false. -func CmdRan(err error) bool { - if err == nil { - return true - } - ee, ok := err.(*exec.ExitError) - if ok { - return ee.Exited() - } - return false -} - -type exitStatus interface { - ExitStatus() int -} - -// ExitStatus returns the exit status of the error if it is an exec.ExitError -// or if it implements ExitStatus() int. -// 0 if it is nil or 1 if it is a different error. -func ExitStatus(err error) int { - if err == nil { - return 0 - } - if e, ok := err.(exitStatus); ok { - return e.ExitStatus() - } - if e, ok := err.(*exec.ExitError); ok { - if ex, ok := e.Sys().(exitStatus); ok { - return ex.ExitStatus() - } - } - return 1 -} diff --git a/vendor/github.com/magefile/mage/sh/helpers.go b/vendor/github.com/magefile/mage/sh/helpers.go deleted file mode 100644 index f5d20a27..00000000 --- a/vendor/github.com/magefile/mage/sh/helpers.go +++ /dev/null @@ -1,40 +0,0 @@ -package sh - -import ( - "fmt" - "io" - "os" -) - -// Rm removes the given file or directory even if non-empty. It will not return -// an error if the target doesn't exist, only if the target cannot be removed. -func Rm(path string) error { - err := os.RemoveAll(path) - if err == nil || os.IsNotExist(err) { - return nil - } - return fmt.Errorf(`failed to remove %s: %v`, path, err) -} - -// Copy robustly copies the source file to the destination, overwriting the destination if necessary. -func Copy(dst string, src string) error { - from, err := os.Open(src) - if err != nil { - return fmt.Errorf(`can't copy %s: %v`, src, err) - } - defer from.Close() - finfo, err := from.Stat() - if err != nil { - return fmt.Errorf(`can't stat %s: %v`, src, err) - } - to, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, finfo.Mode()) - if err != nil { - return fmt.Errorf(`can't copy to %s: %v`, dst, err) - } - defer to.Close() - _, err = io.Copy(to, from) - if err != nil { - return fmt.Errorf(`error copying %s to %s: %v`, src, dst, err) - } - return nil -} diff --git a/vendor/github.com/sirupsen/logrus/.travis.yml b/vendor/github.com/sirupsen/logrus/.travis.yml index e6ee8b3a..c1dbd5a3 100644 --- a/vendor/github.com/sirupsen/logrus/.travis.yml +++ b/vendor/github.com/sirupsen/logrus/.travis.yml @@ -9,6 +9,7 @@ os: linux install: - ./travis/install.sh script: - - go run mage.go -v crossBuild - - go run mage.go lint - - go run mage.go test + - cd ci + - go run mage.go -v -w ../ crossBuild + - go run mage.go -v -w ../ lint + - go run mage.go -v -w ../ test diff --git a/vendor/github.com/sirupsen/logrus/CHANGELOG.md b/vendor/github.com/sirupsen/logrus/CHANGELOG.md index 311f2c33..7567f612 100644 --- a/vendor/github.com/sirupsen/logrus/CHANGELOG.md +++ b/vendor/github.com/sirupsen/logrus/CHANGELOG.md @@ -1,3 +1,12 @@ +# 1.8.1 +Code quality: + * move magefile in its own subdir/submodule to remove magefile dependency on logrus consumer + * improve timestamp format documentation + +Fixes: + * fix race condition on logger hooks + + # 1.8.0 Correct versioning number replacing v1.7.1. diff --git a/vendor/github.com/sirupsen/logrus/README.md b/vendor/github.com/sirupsen/logrus/README.md index 5152b6aa..d1d4a85f 100644 --- a/vendor/github.com/sirupsen/logrus/README.md +++ b/vendor/github.com/sirupsen/logrus/README.md @@ -1,4 +1,4 @@ -# Logrus :walrus: [![Build Status](https://travis-ci.org/sirupsen/logrus.svg?branch=master)](https://travis-ci.org/sirupsen/logrus) [![GoDoc](https://godoc.org/github.com/sirupsen/logrus?status.svg)](https://godoc.org/github.com/sirupsen/logrus) +# Logrus :walrus: [![Build Status](https://github.com/sirupsen/logrus/workflows/CI/badge.svg)](https://github.com/sirupsen/logrus/actions?query=workflow%3ACI) [![Build Status](https://travis-ci.org/sirupsen/logrus.svg?branch=master)](https://travis-ci.org/sirupsen/logrus) [![Go Reference](https://pkg.go.dev/badge/github.com/sirupsen/logrus.svg)](https://pkg.go.dev/github.com/sirupsen/logrus) Logrus is a structured logger for Go (golang), completely API compatible with the standard library logger. @@ -9,7 +9,7 @@ the last thing you want from your Logging library (again...). This does not mean Logrus is dead. Logrus will continue to be maintained for security, (backwards compatible) bug fixes, and performance (where we are -limited by the interface). +limited by the interface). I believe Logrus' biggest contribution is to have played a part in today's widespread use of structured logging in Golang. There doesn't seem to be a @@ -43,7 +43,7 @@ plain text): With `log.SetFormatter(&log.JSONFormatter{})`, for easy parsing by logstash or Splunk: -```json +```text {"animal":"walrus","level":"info","msg":"A group of walrus emerges from the ocean","size":10,"time":"2014-03-10 19:57:38.562264131 -0400 EDT"} @@ -99,7 +99,7 @@ time="2015-03-26T01:27:38-04:00" level=fatal method=github.com/sirupsen/arcticcr ``` Note that this does add measurable overhead - the cost will depend on the version of Go, but is between 20 and 40% in recent tests with 1.6 and 1.7. You can validate this in your -environment via benchmarks: +environment via benchmarks: ``` go test -bench=.*CallerTracing ``` @@ -317,6 +317,8 @@ log.SetLevel(log.InfoLevel) It may be useful to set `log.Level = logrus.DebugLevel` in a debug or verbose environment if your application has that. +Note: If you want different log levels for global (`log.SetLevel(...)`) and syslog logging, please check the [syslog hook README](hooks/syslog/README.md#different-log-levels-for-local-and-remote-logging). + #### Entries Besides the fields added with `WithField` or `WithFields` some fields are @@ -341,7 +343,7 @@ import ( log "github.com/sirupsen/logrus" ) -init() { +func init() { // do something here to set environment depending on an environment variable // or command-line flag if Environment == "production" { diff --git a/vendor/github.com/sirupsen/logrus/buffer_pool.go b/vendor/github.com/sirupsen/logrus/buffer_pool.go index 4545dec0..c7787f77 100644 --- a/vendor/github.com/sirupsen/logrus/buffer_pool.go +++ b/vendor/github.com/sirupsen/logrus/buffer_pool.go @@ -26,15 +26,6 @@ func (p *defaultPool) Get() *bytes.Buffer { return p.pool.Get().(*bytes.Buffer) } -func getBuffer() *bytes.Buffer { - return bufferPool.Get() -} - -func putBuffer(buf *bytes.Buffer) { - buf.Reset() - bufferPool.Put(buf) -} - // SetBufferPool allows to replace the default logrus buffer pool // to better meets the specific needs of an application. func SetBufferPool(bp BufferPool) { diff --git a/vendor/github.com/sirupsen/logrus/entry.go b/vendor/github.com/sirupsen/logrus/entry.go index c968f634..71cdbbc3 100644 --- a/vendor/github.com/sirupsen/logrus/entry.go +++ b/vendor/github.com/sirupsen/logrus/entry.go @@ -232,6 +232,7 @@ func (entry *Entry) log(level Level, msg string) { newEntry.Logger.mu.Lock() reportCaller := newEntry.Logger.ReportCaller + bufPool := newEntry.getBufferPool() newEntry.Logger.mu.Unlock() if reportCaller { @@ -239,11 +240,11 @@ func (entry *Entry) log(level Level, msg string) { } newEntry.fireHooks() - - buffer = getBuffer() + buffer = bufPool.Get() defer func() { newEntry.Buffer = nil - putBuffer(buffer) + buffer.Reset() + bufPool.Put(buffer) }() buffer.Reset() newEntry.Buffer = buffer @@ -260,26 +261,44 @@ func (entry *Entry) log(level Level, msg string) { } } +func (entry *Entry) getBufferPool() (pool BufferPool) { + if entry.Logger.BufferPool != nil { + return entry.Logger.BufferPool + } + return bufferPool +} + func (entry *Entry) fireHooks() { - err := entry.Logger.Hooks.Fire(entry.Level, entry) + var tmpHooks LevelHooks + entry.Logger.mu.Lock() + tmpHooks = make(LevelHooks, len(entry.Logger.Hooks)) + for k, v := range entry.Logger.Hooks { + tmpHooks[k] = v + } + entry.Logger.mu.Unlock() + + err := tmpHooks.Fire(entry.Level, entry) if err != nil { fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) } } func (entry *Entry) write() { + entry.Logger.mu.Lock() + defer entry.Logger.mu.Unlock() serialized, err := entry.Logger.Formatter.Format(entry) if err != nil { fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) return } - entry.Logger.mu.Lock() - defer entry.Logger.mu.Unlock() if _, err := entry.Logger.Out.Write(serialized); err != nil { fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) } } +// Log will log a message at the level given as parameter. +// Warning: using Log at Panic or Fatal level will not respectively Panic nor Exit. +// For this behaviour Entry.Panic or Entry.Fatal should be used instead. func (entry *Entry) Log(level Level, args ...interface{}) { if entry.Logger.IsLevelEnabled(level) { entry.log(level, fmt.Sprint(args...)) diff --git a/vendor/github.com/sirupsen/logrus/json_formatter.go b/vendor/github.com/sirupsen/logrus/json_formatter.go index afaf0fc8..c96dc563 100644 --- a/vendor/github.com/sirupsen/logrus/json_formatter.go +++ b/vendor/github.com/sirupsen/logrus/json_formatter.go @@ -23,6 +23,9 @@ func (f FieldMap) resolve(key fieldKey) string { // JSONFormatter formats logs into parsable json type JSONFormatter struct { // TimestampFormat sets the format used for marshaling timestamps. + // The format to use is the same than for time.Format or time.Parse from the standard + // library. + // The standard Library already provides a set of predefined format. TimestampFormat string // DisableTimestamp allows disabling automatic timestamps in output diff --git a/vendor/github.com/sirupsen/logrus/logger.go b/vendor/github.com/sirupsen/logrus/logger.go index 33770445..5ff0aef6 100644 --- a/vendor/github.com/sirupsen/logrus/logger.go +++ b/vendor/github.com/sirupsen/logrus/logger.go @@ -44,6 +44,9 @@ type Logger struct { entryPool sync.Pool // Function to exit the application, defaults to `os.Exit()` ExitFunc exitFunc + // The buffer pool used to format the log. If it is nil, the default global + // buffer pool will be used. + BufferPool BufferPool } type exitFunc func(int) @@ -192,6 +195,9 @@ func (logger *Logger) Panicf(format string, args ...interface{}) { logger.Logf(PanicLevel, format, args...) } +// Log will log a message at the level given as parameter. +// Warning: using Log at Panic or Fatal level will not respectively Panic nor Exit. +// For this behaviour Logger.Panic or Logger.Fatal should be used instead. func (logger *Logger) Log(level Level, args ...interface{}) { if logger.IsLevelEnabled(level) { entry := logger.newEntry() @@ -402,3 +408,10 @@ func (logger *Logger) ReplaceHooks(hooks LevelHooks) LevelHooks { logger.mu.Unlock() return oldHooks } + +// SetBufferPool sets the logger buffer pool. +func (logger *Logger) SetBufferPool(pool BufferPool) { + logger.mu.Lock() + defer logger.mu.Unlock() + logger.BufferPool = pool +} diff --git a/vendor/github.com/sirupsen/logrus/magefile.go b/vendor/github.com/sirupsen/logrus/magefile.go deleted file mode 100644 index 9aa60393..00000000 --- a/vendor/github.com/sirupsen/logrus/magefile.go +++ /dev/null @@ -1,77 +0,0 @@ -// +build mage - -package main - -import ( - "encoding/json" - "fmt" - "os" - "path" - - "github.com/magefile/mage/mg" - "github.com/magefile/mage/sh" -) - -// getBuildMatrix returns the build matrix from the current version of the go compiler -func getBuildMatrix() (map[string][]string, error) { - jsonData, err := sh.Output("go", "tool", "dist", "list", "-json") - if err != nil { - return nil, err - } - var data []struct { - Goos string - Goarch string - } - if err := json.Unmarshal([]byte(jsonData), &data); err != nil { - return nil, err - } - - matrix := map[string][]string{} - for _, v := range data { - if val, ok := matrix[v.Goos]; ok { - matrix[v.Goos] = append(val, v.Goarch) - } else { - matrix[v.Goos] = []string{v.Goarch} - } - } - - return matrix, nil -} - -func CrossBuild() error { - matrix, err := getBuildMatrix() - if err != nil { - return err - } - - for os, arches := range matrix { - for _, arch := range arches { - env := map[string]string{ - "GOOS": os, - "GOARCH": arch, - } - if mg.Verbose() { - fmt.Printf("Building for GOOS=%s GOARCH=%s\n", os, arch) - } - if err := sh.RunWith(env, "go", "build", "./..."); err != nil { - return err - } - } - } - return nil -} - -func Lint() error { - gopath := os.Getenv("GOPATH") - if gopath == "" { - return fmt.Errorf("cannot retrieve GOPATH") - } - - return sh.Run(path.Join(gopath, "bin", "golangci-lint"), "run", "./...") -} - -// Run the test suite -func Test() error { - return sh.RunWith(map[string]string{"GORACE": "halt_on_error=1"}, - "go", "test", "-race", "-v", "./...") -} diff --git a/vendor/github.com/sirupsen/logrus/text_formatter.go b/vendor/github.com/sirupsen/logrus/text_formatter.go index 8fc698ad..be2c6efe 100644 --- a/vendor/github.com/sirupsen/logrus/text_formatter.go +++ b/vendor/github.com/sirupsen/logrus/text_formatter.go @@ -53,7 +53,10 @@ type TextFormatter struct { // the time passed since beginning of execution. FullTimestamp bool - // TimestampFormat to use for display when a full timestamp is printed + // TimestampFormat to use for display when a full timestamp is printed. + // The format to use is the same than for time.Format or time.Parse from the standard + // library. + // The standard Library already provides a set of predefined format. TimestampFormat string // The fields are sorted by default for a consistent output. For applications diff --git a/vendor/github.com/sirupsen/logrus/writer.go b/vendor/github.com/sirupsen/logrus/writer.go index 72e8e3a1..074fd4b8 100644 --- a/vendor/github.com/sirupsen/logrus/writer.go +++ b/vendor/github.com/sirupsen/logrus/writer.go @@ -4,6 +4,7 @@ import ( "bufio" "io" "runtime" + "strings" ) // Writer at INFO level. See WriterLevel for details. @@ -20,15 +21,18 @@ func (logger *Logger) WriterLevel(level Level) *io.PipeWriter { return NewEntry(logger).WriterLevel(level) } +// Writer returns an io.Writer that writes to the logger at the info log level func (entry *Entry) Writer() *io.PipeWriter { return entry.WriterLevel(InfoLevel) } +// WriterLevel returns an io.Writer that writes to the logger at the given log level func (entry *Entry) WriterLevel(level Level) *io.PipeWriter { reader, writer := io.Pipe() var printFunc func(args ...interface{}) + // Determine which log function to use based on the specified log level switch level { case TraceLevel: printFunc = entry.Trace @@ -48,23 +52,51 @@ func (entry *Entry) WriterLevel(level Level) *io.PipeWriter { printFunc = entry.Print } + // Start a new goroutine to scan the input and write it to the logger using the specified print function. + // It splits the input into chunks of up to 64KB to avoid buffer overflows. go entry.writerScanner(reader, printFunc) + + // Set a finalizer function to close the writer when it is garbage collected runtime.SetFinalizer(writer, writerFinalizer) return writer } +// writerScanner scans the input from the reader and writes it to the logger func (entry *Entry) writerScanner(reader *io.PipeReader, printFunc func(args ...interface{})) { scanner := bufio.NewScanner(reader) + + // Set the buffer size to the maximum token size to avoid buffer overflows + scanner.Buffer(make([]byte, bufio.MaxScanTokenSize), bufio.MaxScanTokenSize) + + // Define a split function to split the input into chunks of up to 64KB + chunkSize := bufio.MaxScanTokenSize // 64KB + splitFunc := func(data []byte, atEOF bool) (int, []byte, error) { + if len(data) >= chunkSize { + return chunkSize, data[:chunkSize], nil + } + + return bufio.ScanLines(data, atEOF) + } + + // Use the custom split function to split the input + scanner.Split(splitFunc) + + // Scan the input and write it to the logger using the specified print function for scanner.Scan() { - printFunc(scanner.Text()) + printFunc(strings.TrimRight(scanner.Text(), "\r\n")) } + + // If there was an error while scanning the input, log an error if err := scanner.Err(); err != nil { entry.Errorf("Error while reading from Writer: %s", err) } + + // Close the reader when we are done reader.Close() } +// WriterFinalizer is a finalizer function that closes then given writer when it is garbage collected func writerFinalizer(writer *io.PipeWriter) { writer.Close() } diff --git a/vendor/golang.org/x/net/html/doc.go b/vendor/golang.org/x/net/html/doc.go index 822ed42a..2466ae3d 100644 --- a/vendor/golang.org/x/net/html/doc.go +++ b/vendor/golang.org/x/net/html/doc.go @@ -92,6 +92,27 @@ example, to process each anchor node in depth-first order: The relevant specifications include: https://html.spec.whatwg.org/multipage/syntax.html and https://html.spec.whatwg.org/multipage/syntax.html#tokenization + +# Security Considerations + +Care should be taken when parsing and interpreting HTML, whether full documents +or fragments, within the framework of the HTML specification, especially with +regard to untrusted inputs. + +This package provides both a tokenizer and a parser, which implement the +tokenization, and tokenization and tree construction stages of the WHATWG HTML +parsing specification respectively. While the tokenizer parses and normalizes +individual HTML tokens, only the parser constructs the DOM tree from the +tokenized HTML, as described in the tree construction stage of the +specification, dynamically modifying or extending the docuemnt's DOM tree. + +If your use case requires semantically well-formed HTML documents, as defined by +the WHATWG specification, the parser should be used rather than the tokenizer. + +In security contexts, if trust decisions are being made using the tokenized or +parsed content, the input must be re-serialized (for instance by using Render or +Token.String) in order for those trust decisions to hold, as the process of +tokenization or parsing may alter the content. */ package html // import "golang.org/x/net/html" diff --git a/vendor/golang.org/x/net/html/escape.go b/vendor/golang.org/x/net/html/escape.go index d8561396..04c6bec2 100644 --- a/vendor/golang.org/x/net/html/escape.go +++ b/vendor/golang.org/x/net/html/escape.go @@ -193,6 +193,87 @@ func lower(b []byte) []byte { return b } +// escapeComment is like func escape but escapes its input bytes less often. +// Per https://github.com/golang/go/issues/58246 some HTML comments are (1) +// meaningful and (2) contain angle brackets that we'd like to avoid escaping +// unless we have to. +// +// "We have to" includes the '&' byte, since that introduces other escapes. +// +// It also includes those bytes (not including EOF) that would otherwise end +// the comment. Per the summary table at the bottom of comment_test.go, this is +// the '>' byte that, per above, we'd like to avoid escaping unless we have to. +// +// Studying the summary table (and T actions in its '>' column) closely, we +// only need to escape in states 43, 44, 49, 51 and 52. State 43 is at the +// start of the comment data. State 52 is after a '!'. The other three states +// are after a '-'. +// +// Our algorithm is thus to escape every '&' and to escape '>' if and only if: +// - The '>' is after a '!' or '-' (in the unescaped data) or +// - The '>' is at the start of the comment data (after the opening ""); err != nil { @@ -194,9 +194,8 @@ func render1(w writer, n *Node) error { } } - // Render any child nodes. - switch n.Data { - case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "xmp": + // Render any child nodes + if childTextNodesAreLiteral(n) { for c := n.FirstChild; c != nil; c = c.NextSibling { if c.Type == TextNode { if _, err := w.WriteString(c.Data); err != nil { @@ -213,7 +212,7 @@ func render1(w writer, n *Node) error { // last element in the file, with no closing tag. return plaintextAbort } - default: + } else { for c := n.FirstChild; c != nil; c = c.NextSibling { if err := render1(w, c); err != nil { return err @@ -231,6 +230,27 @@ func render1(w writer, n *Node) error { return w.WriteByte('>') } +func childTextNodesAreLiteral(n *Node) bool { + // Per WHATWG HTML 13.3, if the parent of the current node is a style, + // script, xmp, iframe, noembed, noframes, or plaintext element, and the + // current node is a text node, append the value of the node's data + // literally. The specification is not explicit about it, but we only + // enforce this if we are in the HTML namespace (i.e. when the namespace is + // ""). + // NOTE: we also always include noscript elements, although the + // specification states that they should only be rendered as such if + // scripting is enabled for the node (which is not something we track). + if n.Namespace != "" { + return false + } + switch n.Data { + case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "xmp": + return true + default: + return false + } +} + // writeQuoted writes s to w surrounded by quotes. Normally it will use double // quotes, but if s contains a double quote, it will use single quotes. // It is used for writing the identifiers in a doctype declaration. diff --git a/vendor/golang.org/x/net/html/token.go b/vendor/golang.org/x/net/html/token.go index 50f7c6aa..3c57880d 100644 --- a/vendor/golang.org/x/net/html/token.go +++ b/vendor/golang.org/x/net/html/token.go @@ -110,7 +110,7 @@ func (t Token) String() string { case SelfClosingTagToken: return "<" + t.tagString() + "/>" case CommentToken: - return "" + return "" case DoctypeToken: return "" } @@ -598,10 +598,10 @@ scriptDataDoubleEscapeEnd: // readComment reads the next comment token starting with "