diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ede864d8..16c07e86 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -17,8 +17,8 @@ env: VAULT_ADDR: https://vault.eng.aserto.com/ PRE_RELEASE: ${{ github.ref == 'refs/heads/main' && 'main' || '' }} GO_VERSION: "1.24" - GO_RELEASER_VERSION: "v2.3.2" - GO_LANGCI_LINT_VERSION: "v1.64.5" + GO_RELEASER_VERSION: "v2.8.2" + GO_LANGCI_LINT_VERSION: "v2.0.2" GO_TESTSUM_VERSION: "1.11.0" jobs: @@ -60,7 +60,7 @@ jobs: go-version: ${{ env.GO_VERSION }} - name: Lint package ${{ matrix.package }} - uses: golangci/golangci-lint-action@v6 + uses: golangci/golangci-lint-action@v7 with: version: ${{ env.GO_LANGCI_LINT_VERSION }} install-mode: binary diff --git a/.golangci.yaml b/.golangci.yaml index fc2d8608..febc267a 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -1,120 +1,83 @@ --- # golangci.com configuration # https://github.com/golangci/golangci/wiki/Configuration - -linters-settings: - dupl: - threshold: 100 - funlen: - lines: 100 - statements: 80 - goconst: - min-len: 2 - min-occurrences: 2 - gocritic: - enabled-tags: - - diagnostic - - experimental - - opinionated - - performance - - style - disabled-checks: - - dupImport # https://github.com/go-critic/go-critic/issues/845 - - ifElseChain - - octalLiteral - - whyNoLint - - wrapperFunc - gocyclo: - min-complexity: 18 - goimports: - local-prefixes: github.com/golangci/golangci-lint - govet: - settings: - printf: - funcs: - - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof - - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf - - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf - - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf - misspell: - locale: US - nolintlint: - allow-unused: false # report any unused nolint directives - require-explanation: false # don't require an explanation for nolint directives - require-specific: false # don't require nolint directives to be specific about which linter is being skipped +version: "2" linters: - # please, do not use `enable-all`: it's deprecated and will be removed soon. - # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint - disable-all: true - enable: - - asciicheck - - bodyclose - - dogsled + default: all + + # explicitly disabled linters + disable: + - containedctx + - contextcheck + - cyclop + - depguard - errcheck - - copyloopvar + - exhaustruct - exhaustive - - funlen - - gochecknoinits - - goconst - - gocritic - - gocyclo - - godot - - err113 - - gofmt - - goimports - - goprintffuncname - - gosec - - gosimple - - govet - - ineffassign - - misspell - - nakedret - - noctx - - rowserrcheck - - staticcheck - - stylecheck - - testpackage - - typecheck - - unconvert - - unparam - - unused + - forbidigo + - gomodguard # no go.mod at root level + - gochecknoglobals # no configuration options + - nilnil + - nlreturn # redundant with wsl + - paralleltest + - revive + - tagalign + - thelper + - varnamelen + - wrapcheck + + settings: + cyclop: + max-complexity: 12 + + errcheck: + exclude-functions: + - fmt.Fprint + - fmt.Fprintf + - fmt.Fprintln + - os.Close + + funlen: + lines: 80 + statements: 60 + ignore-comments: true + + gomoddirectives: + replace-local: true - # don't enable: - # - depguard - # - dupl - # - gochecknoglobals - # - gocognit - # - godox - # - gomnd - # - lll - # - nestif - # - nolintlint # conflict with 1.19 gofmt changes - # - prealloc - # - revive - # - wsl - # - whitespace + gosec: + excludes: + - G104 # Errors unhandled + - G304 # Potential file inclusion via variable (see https://github.com/golang/go/issues/67002) -issues: - # List of regexps of issue texts to exclude, empty list by default. - # But independently from this option we use default exclude patterns, - # it can be disabled by `exclude-use-default: false`. To list all - # excluded by default patterns execute `golangci-lint run --help` - exclude: - - declaration of "(err|ctx)" shadows declaration at - - shadow of imported from 'github.com/stretchr/testify/assert' package 'assert' - # Excluding configuration per-path, per-linter, per-text and per-source - exclude-rules: - - path: _test\.go - linters: - - gomnd - # https://github.com/go-critic/go-critic/issues/926 - - text: "unnecessaryDefer:" - linters: - - gocritic - - text: "unnamedResult:" - linters: - - gocritic - - text: "G404" - linters: - - gosec \ No newline at end of file + ireturn: + allow: + - error + - empty + - stdlib + - generic + - proto.Message + - v3.ImporterClient + + lll: + line-length: 150 + + recvcheck: + exclusions: + - "*.Map" + + tagliatelle: + case: + rules: + json: snake + yaml: snake + + exclusions: + generated: lax + +formatters: + enable: + - gofmt + - gofumpt + - goimports \ No newline at end of file diff --git a/.goreleaser.yml b/.goreleaser.yml index ae4b7170..949f7adf 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -271,7 +271,8 @@ builds: archives: # https://goreleaser.com/customization/archive/ - - format: zip + - formats: + - zip files: - LICENSE - README.md diff --git a/cli/cmd/ds-load/main.go b/cli/cmd/ds-load/main.go index d976d1cd..f05a6f52 100644 --- a/cli/cmd/ds-load/main.go +++ b/cli/cmd/ds-load/main.go @@ -1,6 +1,7 @@ package main import ( + "fmt" "os" "strings" @@ -18,13 +19,13 @@ func main() { pluginFinder, err := plugin.NewHomeDirFinder(true) if err != nil { - os.Stderr.WriteString(err.Error()) + _, _ = fmt.Fprint(os.Stderr, err) os.Exit(1) } plugins, err := pluginFinder.Find() if err != nil { - os.Stderr.WriteString(err.Error()) + _, _ = fmt.Fprint(os.Stderr, err) os.Exit(1) } diff --git a/cli/go.mod b/cli/go.mod index 15262906..3de2940f 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -7,24 +7,24 @@ toolchain go1.24.1 replace github.com/aserto-dev/ds-load/sdk => ../sdk require ( - github.com/alecthomas/kong v1.8.1 - github.com/aserto-dev/ds-load/sdk v0.0.0-00010101000000-000000000000 - github.com/aserto-dev/go-aserto v0.33.7 - github.com/aserto-dev/go-directory v0.33.7 - github.com/fullstorydev/grpcurl v1.9.2 + github.com/alecthomas/kong v1.10.0 + github.com/aserto-dev/ds-load/sdk v0.0.0-20250408143332-e8965667fcc0 + github.com/aserto-dev/go-aserto v0.33.8 + github.com/aserto-dev/go-directory v0.33.10 + github.com/fullstorydev/grpcurl v1.9.3 github.com/pkg/errors v0.9.1 - github.com/rs/zerolog v1.33.0 + github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.10.0 - golang.org/x/sync v0.12.0 - google.golang.org/grpc v1.71.0 + golang.org/x/sync v0.13.0 + google.golang.org/grpc v1.71.1 ) require ( - github.com/aserto-dev/errors v0.0.15 // indirect - github.com/aserto-dev/header v0.0.10 // indirect - github.com/aserto-dev/logger v0.0.7 // indirect - github.com/bufbuild/protocompile v0.10.0 // indirect - github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 // indirect + github.com/aserto-dev/errors v0.0.17 // indirect + github.com/aserto-dev/header v0.0.11 // indirect + github.com/aserto-dev/logger v0.0.9 // indirect + github.com/bufbuild/protocompile v0.14.1 // indirect + github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/envoyproxy/go-control-plane/envoy v1.32.4 // indirect github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect @@ -35,17 +35,17 @@ require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/jhump/protoreflect v1.16.0 // indirect + github.com/jhump/protoreflect v1.17.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/samber/lo v1.49.1 // indirect - golang.org/x/net v0.37.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/protobuf v1.36.5 // indirect + golang.org/x/net v0.39.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/cli/go.sum b/cli/go.sum index 0d0984fc..6b1886ba 100644 --- a/cli/go.sum +++ b/cli/go.sum @@ -4,26 +4,42 @@ github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8v github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/kong v1.8.1 h1:6aamvWBE/REnR/BCq10EcozmcpUPc5aGI1lPAWdB0EE= github.com/alecthomas/kong v1.8.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= +github.com/alecthomas/kong v1.10.0 h1:8K4rGDpT7Iu+jEXCIJUeKqvpwZHbsFRoebLbnzlmrpw= +github.com/alecthomas/kong v1.10.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/aserto-dev/errors v0.0.15 h1:Mx/k7HITit+Istq8YLatiydEIbff39RXf3fW/PlKSwo= github.com/aserto-dev/errors v0.0.15/go.mod h1:WntQkFRb4j41tp4ObRXTdhu/VZKIzIRTReLHjLLMWyc= +github.com/aserto-dev/errors v0.0.17 h1:Jlb38zvMAEOhbl8SSt8pz0p4/r3wgRMNcnBtnhzhD2g= +github.com/aserto-dev/errors v0.0.17/go.mod h1:42SHPNyCVOYYLgmz5KPvoc9GESAUuff0lN4S/hXLrz4= github.com/aserto-dev/go-aserto v0.33.7 h1:oLAj2nu4YKJ7q6pUFpABOQuY/70YfF5B89T0RkKSV8k= github.com/aserto-dev/go-aserto v0.33.7/go.mod h1:R4Bo3Tgn2KnyvmeyW+gID7pBqaRcnqnib36DiLjcjiw= +github.com/aserto-dev/go-aserto v0.33.8 h1:WFk0AFHoLZEH6W6az5ktg7aQ+4gS34/UmWNw2UOW70I= +github.com/aserto-dev/go-aserto v0.33.8/go.mod h1:fCDpKpXHVEf7pzaIA+oqIq1NKLywVz4GLdE3WUm+D/k= github.com/aserto-dev/go-directory v0.33.7 h1:jldr2cGQp5EYM4l3IKSNyuK3Rr30taQ7MejbIHt+rGQ= github.com/aserto-dev/go-directory v0.33.7/go.mod h1:mY53j91JUnGRk9lsfw3yxgQXO41SCnt2bSP/2PamxCo= +github.com/aserto-dev/go-directory v0.33.10 h1:PLevCAWc9QeLZZv5Wc+yGk4psSd3507y1+9Fps+CzdI= +github.com/aserto-dev/go-directory v0.33.10/go.mod h1:CYRXxtDtf4zSwYYBBkGqW3b7HWJWvoIEBWgah9SGMAM= github.com/aserto-dev/header v0.0.10 h1:H6sz3F4pfv53FuyGNoZlRNHpAcOonTioQMnWRowyigU= github.com/aserto-dev/header v0.0.10/go.mod h1:N3+nmX6nXmM9gI8VsGXOujPW6aW/8aEFa7dSu0FRerY= +github.com/aserto-dev/header v0.0.11 h1:Qx7lWzfq29h0OgaJQ8W9KD+/q9q14yOwKBFmD0viAfQ= +github.com/aserto-dev/header v0.0.11/go.mod h1:yTO0YPKVTlUTcP0ecQ/7qKs6l6RvDS0ac5l+S1BGWBs= github.com/aserto-dev/logger v0.0.7 h1:ORvXxZDMNIcN/E3SYHj8fxmNZnOD7Gf87pOLB2XQavw= github.com/aserto-dev/logger v0.0.7/go.mod h1:66ff7ALo68NT1HcCg5zytOnGh6I5R0HeDpN85cwHcD0= +github.com/aserto-dev/logger v0.0.9 h1:QH11l8937Sw+GAe2yvgpoLg70fqQvPrEufkXAmDUk0g= +github.com/aserto-dev/logger v0.0.9/go.mod h1:mMXq/bhdIKoOVsIZ2zJOqgjcc/jR2x14FhU0St/8AVQ= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/bufbuild/protocompile v0.10.0 h1:+jW/wnLMLxaCEG8AX9lD0bQ5v9h1RUiMKOBOT5ll9dM= github.com/bufbuild/protocompile v0.10.0/go.mod h1:G9qQIQo0xZ6Uyj6CMNz0saGmx2so+KONo8/KrELABiY= +github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= +github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 h1:boJj011Hh+874zpIySeApCX4GeOjPl9qhRF3QuIZq+Q= github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f h1:C5bqEmzEPLsHm9Mv73lSE9e9bKV23aB1vxOsmZrkl3k= +github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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= @@ -31,6 +47,7 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M= github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A= github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= @@ -38,6 +55,8 @@ github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfU github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= github.com/fullstorydev/grpcurl v1.9.2 h1:ObqVQTZW7aFnhuqQoppUrvep2duMBanB0UYK2Mm8euo= github.com/fullstorydev/grpcurl v1.9.2/go.mod h1:jLfcF55HAz6TYIJY9xFFWgsl0D7o2HlxA5Z4lUG0Tdo= +github.com/fullstorydev/grpcurl v1.9.3 h1:PC1Xi3w+JAvEE2Tg2Gf2RfVgPbf9+tbuQr1ZkyVU3jk= +github.com/fullstorydev/grpcurl v1.9.3/go.mod h1:/b4Wxe8bG6ndAjlfSUjwseQReUDUvBJiFEB7UllOlUE= github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a h1:v6zMvHuY9yue4+QkG/HQ/W67wvtQmWJ4SDo9aK/GIno= github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a/go.mod h1:I79BieaU4fxrw4LMXby6q5OS9XnoR9UIKLOzDFjUmuw= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= @@ -74,6 +93,8 @@ github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUq github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/jhump/protoreflect v1.16.0 h1:54fZg+49widqXYQ0b+usAFHbMkBGR4PpXrsHc8+TBDg= github.com/jhump/protoreflect v1.16.0/go.mod h1:oYPd7nPvcBw/5wlDfm/AVmU9zH9BgqGCI469pGxfj/8= +github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= +github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -103,8 +124,11 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/samber/lo v1.49.1 h1:4BIFyVfuQSEpluc7Fua+j1NolZHiEHEpaSEKdsH0tew= github.com/samber/lo v1.49.1/go.mod h1:dO6KHFzUKXgP8LDhU0oI8d2hekjXnGOu0DB8Jecxd6o= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= @@ -154,6 +178,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -162,6 +188,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= +golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/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= @@ -173,10 +201,14 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 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.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -197,8 +229,12 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98 google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a h1:OQ7sHVzkx6L57dQpzUS4ckfWJ51KDH74XHTDe23xWAs= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a/go.mod h1:2R6XrVC8Oc08GlNh8ujEpc7HkLiEZ16QeY7FxIs20ac= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a h1:GIqLhp/cYUkuGuiT+vJk8vhOP86L4+SP5j8yXgeVpvI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= @@ -206,8 +242,12 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= +google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= +google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/cli/pkg/app/cli.go b/cli/pkg/app/cli.go index 486747ee..66b0a7e7 100644 --- a/cli/pkg/app/cli.go +++ b/cli/pkg/app/cli.go @@ -9,6 +9,7 @@ import ( "github.com/aserto-dev/ds-load/cli/pkg/plugin" "github.com/aserto-dev/ds-load/sdk/common/cc" "github.com/aserto-dev/ds-load/sdk/common/version" + "github.com/pkg/errors" ) type CLI struct { @@ -51,7 +52,9 @@ func (listPlugins *ListPluginsCmd) Run(c *cc.CommonCtx) error { } for _, p := range plugins { - os.Stdout.WriteString(p.Name + " " + p.Path + "\n") + if _, err := fmt.Fprint(os.Stdout, p.Name, p.Path); err != nil { + return errors.Wrapf(err, "failed to write plugin info for %q", p.Name) + } } return nil diff --git a/cli/pkg/app/exec.go b/cli/pkg/app/exec.go index 202d8faa..91f48c43 100644 --- a/cli/pkg/app/exec.go +++ b/cli/pkg/app/exec.go @@ -155,7 +155,13 @@ func listenOnStderr(c *cc.CommonCtx, wg *sync.WaitGroup, stderr io.ReadCloser) { for { line, err := scanner.ReadBytes('\n') - os.Stderr.Write(line) + if err != nil { + c.Log.Fatal().Err(err).Send() + } + + if _, err := os.Stderr.Write(line); err != nil { + c.Log.Fatal().Err(err).Send() + } if len(line) > 0 { gotError = true @@ -169,7 +175,7 @@ func listenOnStderr(c *cc.CommonCtx, wg *sync.WaitGroup, stderr io.ReadCloser) { break } else if err != nil { - c.Log.Fatal().Err(err) + c.Log.Fatal().Err(err).Send() } } diff --git a/cli/pkg/publish/publisher_v3.go b/cli/pkg/publish/publisher_v3.go index db9d6fc8..d71a49c3 100644 --- a/cli/pkg/publish/publisher_v3.go +++ b/cli/pkg/publish/publisher_v3.go @@ -49,7 +49,7 @@ func (p *DirectoryPublisher) Publish(ctx context.Context, reader io.Reader) erro var message msg.Transform err := jsonReader.ReadProtoMessage(&message) - if err == io.EOF { + if errors.Is(err, io.EOF) { break } @@ -91,23 +91,23 @@ func (p *DirectoryPublisher) publishMessages(ctx context.Context, message *msg.T errGroup.Go(p.doneHandler(stream.Context())) - opCode := message.OpCode + opCode := message.GetOpCode() if opCode == dsi3.Opcode_OPCODE_UNKNOWN { opCode = dsi3.Opcode_OPCODE_SET } // import objects - for _, object := range message.Objects { + for _, object := range message.GetObjects() { if err := validator.Object(object); err != nil { - fmt.Fprintf(os.Stderr, "validation failed, object: [%s] type [%s]\n", object.Id, object.Type) + fmt.Fprintf(os.Stderr, "validation failed, object: [%s] type [%s]\n", object.GetId(), object.GetType()) continue } - if (opCode == dsi3.Opcode_OPCODE_DELETE || opCode == dsi3.Opcode_OPCODE_DELETE_WITH_RELATIONS) && object.Type == "group" { + if (opCode == dsi3.Opcode_OPCODE_DELETE || opCode == dsi3.Opcode_OPCODE_DELETE_WITH_RELATIONS) && object.GetType() == "group" { continue } - fmt.Fprintf(os.Stdout, "object: [%s] type [%s]\n", object.Id, object.Type) + fmt.Fprintf(os.Stdout, "object: [%s] type [%s]\n", object.GetId(), object.GetType()) sErr := stream.Send(&dsi3.ImportRequest{ Msg: &dsi3.ImportRequest_Object{ Object: object, @@ -119,13 +119,14 @@ func (p *DirectoryPublisher) publishMessages(ctx context.Context, message *msg.T } // import relations - for _, relation := range message.Relations { + for _, relation := range message.GetRelations() { if err := validator.Relation(relation); err != nil { - fmt.Fprintf(os.Stderr, "validation failed, relation: [%s] obj: [%s] subj [%s]\n", relation.Relation, relation.ObjectId, relation.SubjectId) + fmt.Fprintf(os.Stderr, "validation failed, relation: [%s] obj: [%s] subj [%s]\n", + relation.GetRelation(), relation.GetObjectId(), relation.GetSubjectId()) continue } - fmt.Fprintf(os.Stdout, "relation: [%s] obj: [%s] subj [%s]\n", relation.Relation, relation.ObjectId, relation.SubjectId) + fmt.Fprintf(os.Stdout, "relation: [%s] obj: [%s] subj [%s]\n", relation.GetRelation(), relation.GetObjectId(), relation.GetSubjectId()) sErr := stream.Send(&dsi3.ImportRequest{ Msg: &dsi3.ImportRequest_Relation{ Relation: relation, @@ -154,7 +155,7 @@ func (p *DirectoryPublisher) handleStreamError(err error) { return } - p.Log.Err(err) + p.Log.Err(err).Msg("stream error") common.SetExitCode(1) } @@ -162,7 +163,7 @@ func (p *DirectoryPublisher) receiver(stream dsi3.Importer_ImportClient) func() return func() error { for { result, err := stream.Recv() - if err == io.EOF { + if errors.Is(err, io.EOF) { return nil } @@ -171,13 +172,13 @@ func (p *DirectoryPublisher) receiver(stream dsi3.Importer_ImportClient) func() } if result != nil { - switch m := result.Msg.(type) { + switch m := result.GetMsg().(type) { case *dsi3.ImportResponse_Status: p.errs = true printStatus(os.Stderr, m.Status) case *dsi3.ImportResponse_Counter: - switch m.Counter.Type { + switch m.Counter.GetType() { case objectsCounter: p.objCounter = m.Counter case relationsCounter: @@ -206,17 +207,17 @@ func (p *DirectoryPublisher) doneHandler(ctx context.Context) func() error { func printStatus(w io.Writer, status *dsi3.ImportStatus) { fmt.Fprintf(w, "%-9s : %s - %s (%d)\n", "error", - status.Msg, - codes.Code(status.Code).String(), - status.Code) + status.GetMsg(), + codes.Code(status.GetCode()).String(), + status.GetCode()) } func printCounter(w io.Writer, ctr *dsi3.ImportCounter) { fmt.Fprintf(w, "%-9s : %d (set:%d delete:%d error:%d)\n", - ctr.Type, - ctr.Recv, - ctr.Set, - ctr.Delete, - ctr.Error, + ctr.GetType(), + ctr.GetRecv(), + ctr.GetSet(), + ctr.GetDelete(), + ctr.GetError(), ) } diff --git a/makefile b/makefile index 86d02823..cb5fa59f 100644 --- a/makefile +++ b/makefile @@ -12,7 +12,7 @@ GOPRIVATE := "github.com/aserto-dev" DOCKER_BUILDKIT := 1 BIN_DIR := ./bin -EXT_DIR := ./.ext +EXT_DIR := ${PWD}/.ext EXT_BIN_DIR := ${EXT_DIR}/bin EXT_TMP_DIR := ${EXT_DIR}/tmp @@ -20,8 +20,8 @@ GO_VER := 1.24 VAULT_VER := 1.8.12 SVU_VER := 3.1.0 GOTESTSUM_VER := 1.11.0 -GOLANGCI-LINT_VER := 1.64.5 -GORELEASER_VER := 2.3.2 +GOLANGCI-LINT_VER := 2.0.2 +GORELEASER_VER := 2.8.2 BUF_VER := 1.50.0 RELEASE_TAG := $$(${EXT_BIN_DIR}/svu current) @@ -63,7 +63,7 @@ lint: @echo -e "$(ATTN_COLOR)==> $@ $(NO_COLOR)" @${EXT_BIN_DIR}/golangci-lint config path @${EXT_BIN_DIR}/golangci-lint config verify - @go list -f '{{.Dir}}/...' -m | xargs ${EXT_BIN_DIR}/golangci-lint run --config ${PWD}/.golangci.yaml + @go list -f '{{.Dir}}' -m | xargs -I{} bash -c 'cd {} && ${EXT_BIN_DIR}/golangci-lint run --config ${PWD}/.golangci.yaml' PHONY: go-mod-tidy go-mod-tidy: diff --git a/plugins/auth0/go.mod b/plugins/auth0/go.mod index 18055f6b..a05ac8e3 100644 --- a/plugins/auth0/go.mod +++ b/plugins/auth0/go.mod @@ -7,9 +7,9 @@ toolchain go1.24.1 replace github.com/aserto-dev/ds-load/sdk => ../../sdk require ( - github.com/alecthomas/kong v1.8.1 - github.com/aserto-dev/ds-load/sdk v0.0.0-00010101000000-000000000000 - github.com/auth0/go-auth0 v1.17.0 + github.com/alecthomas/kong v1.10.0 + github.com/aserto-dev/ds-load/sdk v0.0.0-20250408143332-e8965667fcc0 + github.com/auth0/go-auth0 v1.19.0 github.com/pkg/errors v0.9.1 github.com/samber/lo v1.49.1 ) @@ -20,8 +20,8 @@ require ( github.com/Masterminds/semver/v3 v3.3.1 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect github.com/PuerkitoBio/rehttp v1.4.0 // indirect - github.com/aserto-dev/go-directory v0.33.7 // indirect - github.com/aserto-dev/logger v0.0.7 // indirect + github.com/aserto-dev/go-directory v0.33.10 // indirect + github.com/aserto-dev/logger v0.0.9 // indirect github.com/dongri/phonenumber v0.1.12 // indirect github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect @@ -31,17 +31,17 @@ require ( github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect - github.com/rs/zerolog v1.33.0 // indirect + github.com/rs/zerolog v1.34.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/spf13/cast v1.7.1 // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/net v0.37.0 // indirect - golang.org/x/oauth2 v0.27.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/grpc v1.71.0 // indirect - google.golang.org/protobuf v1.36.5 // indirect + golang.org/x/crypto v0.37.0 // indirect + golang.org/x/net v0.39.0 // indirect + golang.org/x/oauth2 v0.29.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/grpc v1.71.1 // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/plugins/auth0/go.sum b/plugins/auth0/go.sum index efae40eb..9a19d97d 100644 --- a/plugins/auth0/go.sum +++ b/plugins/auth0/go.sum @@ -12,14 +12,22 @@ github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8v github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/kong v1.8.1 h1:6aamvWBE/REnR/BCq10EcozmcpUPc5aGI1lPAWdB0EE= github.com/alecthomas/kong v1.8.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= +github.com/alecthomas/kong v1.10.0 h1:8K4rGDpT7Iu+jEXCIJUeKqvpwZHbsFRoebLbnzlmrpw= +github.com/alecthomas/kong v1.10.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/aserto-dev/go-directory v0.33.7 h1:jldr2cGQp5EYM4l3IKSNyuK3Rr30taQ7MejbIHt+rGQ= github.com/aserto-dev/go-directory v0.33.7/go.mod h1:mY53j91JUnGRk9lsfw3yxgQXO41SCnt2bSP/2PamxCo= +github.com/aserto-dev/go-directory v0.33.10 h1:PLevCAWc9QeLZZv5Wc+yGk4psSd3507y1+9Fps+CzdI= +github.com/aserto-dev/go-directory v0.33.10/go.mod h1:CYRXxtDtf4zSwYYBBkGqW3b7HWJWvoIEBWgah9SGMAM= github.com/aserto-dev/logger v0.0.7 h1:ORvXxZDMNIcN/E3SYHj8fxmNZnOD7Gf87pOLB2XQavw= github.com/aserto-dev/logger v0.0.7/go.mod h1:66ff7ALo68NT1HcCg5zytOnGh6I5R0HeDpN85cwHcD0= +github.com/aserto-dev/logger v0.0.9 h1:QH11l8937Sw+GAe2yvgpoLg70fqQvPrEufkXAmDUk0g= +github.com/aserto-dev/logger v0.0.9/go.mod h1:mMXq/bhdIKoOVsIZ2zJOqgjcc/jR2x14FhU0St/8AVQ= github.com/auth0/go-auth0 v1.17.0 h1:KPAGX4gpmJAMGL/1Z1iTtxMdxOO5lbpLQyie9u06zY4= github.com/auth0/go-auth0 v1.17.0/go.mod h1:f6wP4Hov4Be5AKK55tVhAHlKNltqXQIIc3QGfBbnvdU= +github.com/auth0/go-auth0 v1.19.0 h1:LZAVZCiZsENm0wX/PvRwN+mLbyCb4PPCfyKww8b7KR4= +github.com/auth0/go-auth0 v1.19.0/go.mod h1:6g0NRYWA+rzTLG5AohwCJ0YCEqbzphKcdjt+PWrgcPk= github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0 h1:0NmehRCgyk5rljDQLKUO+cRJCnduDyn11+zGZIc9Z48= github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0/go.mod h1:6L7zgvqo0idzI7IO8de6ZC051AfXb5ipkIJ7bIA2tGA= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= @@ -75,8 +83,11 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/samber/lo v1.49.1 h1:4BIFyVfuQSEpluc7Fua+j1NolZHiEHEpaSEKdsH0tew= github.com/samber/lo v1.49.1/go.mod h1:dO6KHFzUKXgP8LDhU0oI8d2hekjXnGOu0DB8Jecxd6o= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= @@ -101,11 +112,17 @@ go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98= +golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -113,19 +130,31 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a h1:OQ7sHVzkx6L57dQpzUS4ckfWJ51KDH74XHTDe23xWAs= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a/go.mod h1:2R6XrVC8Oc08GlNh8ujEpc7HkLiEZ16QeY7FxIs20ac= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a h1:GIqLhp/cYUkuGuiT+vJk8vhOP86L4+SP5j8yXgeVpvI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= +google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= +google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/plugins/auth0/pkg/app/constants.go b/plugins/auth0/pkg/app/constants.go index 6d646193..421f2321 100644 --- a/plugins/auth0/pkg/app/constants.go +++ b/plugins/auth0/pkg/app/constants.go @@ -1,6 +1,8 @@ package app -const AppName = "ds-load-auth0" -const AppDescription = "auth0 directory loader" +const ( + AppName = "ds-load-auth0" + AppDescription = "auth0 directory loader" +) const auth0prefix string = "auth0|" diff --git a/plugins/auth0/pkg/app/fetch.go b/plugins/auth0/pkg/app/fetch.go index 19be953e..54de10c7 100644 --- a/plugins/auth0/pkg/app/fetch.go +++ b/plugins/auth0/pkg/app/fetch.go @@ -6,6 +6,7 @@ import ( "github.com/aserto-dev/ds-load/plugins/auth0/pkg/auth0client" "github.com/aserto-dev/ds-load/plugins/auth0/pkg/fetch" + "github.com/aserto-dev/ds-load/sdk/common" "github.com/aserto-dev/ds-load/sdk/common/cc" ) @@ -37,7 +38,13 @@ func (f *FetchCmd) Run(ctx *cc.CommonCtx) error { return err } - fetcher = fetcher.WithUserPID(f.UserPID).WithEmail(f.UserEmail).WithRoles(f.Roles).WithOrgs(f.Orgs).WithSAML(f.SAML).WithConnectionName(f.ConnectionName) + fetcher = fetcher. + WithUserPID(f.UserPID). + WithEmail(f.UserEmail). + WithRoles(f.Roles). + WithOrgs(f.Orgs). + WithSAML(f.SAML). + WithConnectionName(f.ConnectionName) - return fetcher.Fetch(ctx.Context, os.Stdout, os.Stderr) + return fetcher.Fetch(ctx.Context, os.Stdout, common.NewErrorWriter(os.Stderr)) } diff --git a/plugins/auth0/pkg/fetch/fetch.go b/plugins/auth0/pkg/fetch/fetch.go index 20b7f72e..4eae56c4 100644 --- a/plugins/auth0/pkg/fetch/fetch.go +++ b/plugins/auth0/pkg/fetch/fetch.go @@ -26,6 +26,8 @@ type Fetcher struct { client *auth0client.Auth0Client } +const defaultMaxUsers = 100 + func New(ctx context.Context, client *auth0client.Auth0Client) (*Fetcher, error) { return &Fetcher{ client: client, @@ -62,7 +64,7 @@ func (f *Fetcher) WithConnectionName(connectionName string) *Fetcher { return f } -func (f *Fetcher) Fetch(ctx context.Context, outputWriter, errorWriter io.Writer) error { +func (f *Fetcher) Fetch(ctx context.Context, outputWriter io.Writer, errorWriter common.ErrorWriter) error { writer := js.NewJSONArrayWriter(outputWriter) defer writer.Close() @@ -76,7 +78,7 @@ func (f *Fetcher) Fetch(ctx context.Context, outputWriter, errorWriter io.Writer return f.fetchUsers(ctx, writer, errorWriter) } -func (f *Fetcher) fetchUsers(ctx context.Context, outputWriter *js.JSONArrayWriter, errorWriter io.Writer) error { +func (f *Fetcher) fetchUsers(ctx context.Context, outputWriter *js.JSONArrayWriter, errorWriter common.ErrorWriter) error { page := 0 for { @@ -85,46 +87,20 @@ func (f *Fetcher) fetchUsers(ctx context.Context, outputWriter *js.JSONArrayWrit opts = append(opts, management.Query(f.getConnectionQuery())) } - users, more, err := f.getUsers(ctx, opts) + users, more, err := f.fetchUsersList(ctx, opts) if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) + errorWriter.Error(err) return err } for _, user := range users { - res, err := user.MarshalJSON() - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - continue - } + obj, err := f.userToMap(ctx, user) + errorWriter.Error(err) - var obj map[string]interface{} - if err := json.Unmarshal(res, &obj); err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) + if obj == nil { continue } - obj["email_verified"] = user.GetEmailVerified() - obj["object_type"] = "user" - - if f.Roles { - roles, err := f.getUserRoles(ctx, *user.ID) - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - } else { - obj["roles"] = roles - } - } - - if f.Orgs { - orgs, err := f.getOrgs(ctx, *user.ID) - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - } else { - obj["orgs"] = orgs - } - } - err = outputWriter.Write(obj) if err != nil { return err @@ -141,7 +117,44 @@ func (f *Fetcher) fetchUsers(ctx context.Context, outputWriter *js.JSONArrayWrit return nil } -func (f *Fetcher) fetchGroups(ctx context.Context, outputWriter *js.JSONArrayWriter, errorWriter io.Writer) error { +// return a object map to output or a boolean to skip current user. +func (f *Fetcher) userToMap(ctx context.Context, user *management.User) (map[string]any, error) { + var obj map[string]any + + res, err := user.MarshalJSON() + if err != nil { + return nil, err + } + + if err := json.Unmarshal(res, &obj); err != nil { + return nil, err + } + + obj["email_verified"] = user.GetEmailVerified() + obj["object_type"] = "user" + + if f.Roles { + roles, err := f.fetchUserRoles(ctx, *user.ID) + if err != nil { + return nil, err + } else { + obj["roles"] = roles + } + } + + if f.Orgs { + orgs, err := f.fetchOrgs(ctx, *user.ID) + if err != nil { + return nil, err + } else { + obj["orgs"] = orgs + } + } + + return obj, nil +} + +func (f *Fetcher) fetchGroups(ctx context.Context, outputWriter *js.JSONArrayWriter, errorWriter common.ErrorWriter) error { page := 0 for f.Roles { @@ -151,19 +164,19 @@ func (f *Fetcher) fetchGroups(ctx context.Context, outputWriter *js.JSONArrayWri opts = append(opts, management.Query(f.getConnectionQuery())) } - roles, more, err := f.getRoles(ctx, opts) + roles, more, err := f.fetchRoles(ctx, opts) if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) + errorWriter.Error(err) return err } for _, role := range roles { res := role.String() - var obj map[string]interface{} + var obj map[string]any if err := json.Unmarshal([]byte(res), &obj); err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) + errorWriter.Error(err) continue } @@ -183,7 +196,7 @@ func (f *Fetcher) fetchGroups(ctx context.Context, outputWriter *js.JSONArrayWri return nil } -func (f *Fetcher) getUsers(ctx context.Context, opts []management.RequestOption) ([]*management.User, bool, error) { +func (f *Fetcher) fetchUsersList(ctx context.Context, opts []management.RequestOption) ([]*management.User, bool, error) { if f.UserPID != "" && f.UserEmail != "" { return nil, false, errors.New("only one of user-pid or user-email can be specified") } @@ -224,14 +237,14 @@ func (f *Fetcher) getUsers(ctx context.Context, opts []management.RequestOption) // Use special SAML user list, to avoid known unmarshal errors, see notes below. ul := &UserList{} - if err := ListUsers(ctx, f.client.Mgmt, &ul, opts...); err != nil { + if err := FetchUsers(ctx, f.client.Mgmt, &ul, opts...); err != nil { return nil, false, err } return ul.UserList(), ul.HasNext(), nil } -func (f *Fetcher) getRoles(ctx context.Context, opts []management.RequestOption) ([]*management.Role, bool, error) { +func (f *Fetcher) fetchRoles(ctx context.Context, opts []management.RequestOption) ([]*management.Role, bool, error) { roles, err := f.client.Mgmt.Role.List(ctx, opts...) if err != nil { return nil, false, err @@ -244,17 +257,13 @@ func (f *Fetcher) getRoles(ctx context.Context, opts []management.RequestOption) return roles.Roles, roles.HasNext(), nil } -func (f *Fetcher) getUserRoles(ctx context.Context, uID string) ([]map[string]interface{}, error) { +func (f *Fetcher) fetchUserRoles(ctx context.Context, uID string) ([]map[string]any, error) { page := 0 - finished := false + hasNext := true - var results []map[string]interface{} - - for { - if finished { - break - } + var results []map[string]any + for hasNext { reqOpts := management.Page(page) roles, err := f.client.Mgmt.User.Roles(ctx, uID, reqOpts) @@ -268,7 +277,7 @@ func (f *Fetcher) getUserRoles(ctx context.Context, uID string) ([]map[string]in return nil, err } - var obj map[string]interface{} + var obj map[string]any if err := json.Unmarshal(res, &obj); err != nil { return nil, err } @@ -276,9 +285,7 @@ func (f *Fetcher) getUserRoles(ctx context.Context, uID string) ([]map[string]in results = append(results, obj) } - if !roles.HasNext() { - finished = true - } + hasNext = roles.HasNext() page++ } @@ -286,17 +293,13 @@ func (f *Fetcher) getUserRoles(ctx context.Context, uID string) ([]map[string]in return results, nil } -func (f *Fetcher) getOrgs(ctx context.Context, uID string) ([]map[string]interface{}, error) { +func (f *Fetcher) fetchOrgs(ctx context.Context, uID string) ([]map[string]any, error) { page := 0 - finished := false + hasNext := true - var results []map[string]interface{} - - for { - if finished { - break - } + var results []map[string]any + for hasNext { reqOpts := management.Page(page) orgs, err := f.client.Mgmt.User.Organizations(ctx, uID, reqOpts) @@ -305,22 +308,15 @@ func (f *Fetcher) getOrgs(ctx context.Context, uID string) ([]map[string]interfa } for _, org := range orgs.Organizations { - res, err := json.Marshal(org) + obj, err := toJSONMap(org) if err != nil { return nil, err } - var obj map[string]interface{} - if err := json.Unmarshal(res, &obj); err != nil { - return nil, err - } - results = append(results, obj) } - if !orgs.HasNext() { - finished = true - } + hasNext = orgs.HasNext() page++ } @@ -328,6 +324,20 @@ func (f *Fetcher) getOrgs(ctx context.Context, uID string) ([]map[string]interfa return results, nil } +func toJSONMap(org any) (map[string]any, error) { + res, err := json.Marshal(org) + if err != nil { + return nil, err + } + + var obj map[string]any + if err := json.Unmarshal(res, &obj); err != nil { + return nil, err + } + + return obj, nil +} + func (f *Fetcher) getConnectionQuery() string { if f.ConnectionName == "" { return "" @@ -336,7 +346,16 @@ func (f *Fetcher) getConnectionQuery() string { return `identities.connection:"` + f.ConnectionName + `"` } -// Specialized SAML user list function +type User struct { + management.User +} + +type UserList struct { + management.List + Users []*User `json:"users"` +} + +// UserList is a specialized SAML user list function // // The Auth0 golang SDK does not properly handle the unmarshal of the returned payload into a management.UserList. // @@ -345,33 +364,27 @@ func (f *Fetcher) getConnectionQuery() string { // "emailVerified":"true", // "email_verified":"user@domain.com" // -// Which results in an unmarshal error when calling `func (m *UserManager) List(ctx context.Context, opts ...RequestOption) (ul *UserList, err error)` +// Which results in an unmarshal error when calling +// +// func (m *UserManager) List(ctx context.Context, opts ...RequestOption) (ul *UserList, err error) +// // resulting in an error `strconv.ParseBool: parsing "user@domain.com": invalid syntax` // // The implementation below works around the issues by using custom JSON marshaling to map the values into the management.User instances. -type User struct { - management.User -} - -type UserList struct { - management.List - Users []*User `json:"users"` -} - func (ul UserList) UserList() []*management.User { return lo.Map(ul.Users, func(v *User, i int) *management.User { return &v.User }) } func (u *User) UnmarshalJSON(b []byte) error { - var raw map[string]interface{} + var raw map[string]any if err := json.Unmarshal(b, &raw); err != nil { return err } verified := false - if emailVerified, ok := raw["emailVerified"]; ok { - verified, _ = strconv.ParseBool(emailVerified.(string)) + if emailVerified, ok := raw["emailVerified"].(string); ok { + verified, _ = strconv.ParseBool(emailVerified) } delete(raw, "emailVerified") @@ -397,9 +410,9 @@ func (u *User) UnmarshalJSON(b []byte) error { return nil } -func ListUsers(ctx context.Context, m *management.Management, payload interface{}, options ...management.RequestOption) error { +func FetchUsers(ctx context.Context, m *management.Management, payload any, options ...management.RequestOption) error { options = append(options, - management.PerPage(100), + management.PerPage(defaultMaxUsers), management.IncludeTotals(true), ) diff --git a/plugins/auth0/pkg/httpclient/client.go b/plugins/auth0/pkg/httpclient/client.go index 000ed4a4..c3ca439c 100644 --- a/plugins/auth0/pkg/httpclient/client.go +++ b/plugins/auth0/pkg/httpclient/client.go @@ -13,6 +13,11 @@ type RateLimit struct { ResetTime time.Time } +const ( + RateLimitRemaining = "X-Ratelimit-Remaining" + RateLimitReset = "X-Ratelimit-Reset" +) + func (rl RateLimit) Wait() { if rl.Remaining < 1 { if rl.ResetTime.Before(time.Now()) { @@ -58,11 +63,11 @@ func NewTransport(transportWrap http.RoundTripper) http.RoundTripper { func parseRateLimit(resp *http.Response) (*RateLimit, error) { var rl RateLimit - if remaining := resp.Header.Get("X-Ratelimit-Remaining"); remaining != "" { + if remaining := resp.Header.Get(RateLimitRemaining); remaining != "" { rl.Remaining, _ = strconv.Atoi(remaining) } - reset, err := strconv.Atoi(resp.Header.Get("X-Ratelimit-Reset")) + reset, err := strconv.Atoi(resp.Header.Get(RateLimitReset)) if err != nil { return nil, errors.Wrapf(err, "failed to parse X-RateLimit-Reset header") } diff --git a/plugins/azuread/go.mod b/plugins/azuread/go.mod index b77a8f04..3290a5d2 100644 --- a/plugins/azuread/go.mod +++ b/plugins/azuread/go.mod @@ -7,30 +7,30 @@ toolchain go1.24.1 replace github.com/aserto-dev/ds-load/sdk => ../../sdk require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0 - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 - github.com/alecthomas/kong v1.8.1 - github.com/aserto-dev/ds-load/sdk v0.0.0-20241206112725-5d200d771446 + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0 + github.com/alecthomas/kong v1.10.0 + github.com/aserto-dev/ds-load/sdk v0.0.0-20250408143332-e8965667fcc0 github.com/aserto-dev/msgraph-sdk-go v0.0.3 - github.com/microsoft/kiota-abstractions-go v1.8.1 - github.com/microsoft/kiota-authentication-azure-go v1.1.0 - github.com/microsoft/kiota-http-go v1.4.7 - github.com/microsoft/kiota-serialization-json-go v1.0.9 - github.com/microsoftgraph/msgraph-sdk-go-core v1.2.1 + github.com/microsoft/kiota-abstractions-go v1.9.2 + github.com/microsoft/kiota-authentication-azure-go v1.3.0 + github.com/microsoft/kiota-http-go v1.5.3 + github.com/microsoft/kiota-serialization-json-go v1.1.2 + github.com/microsoftgraph/msgraph-sdk-go-core v1.3.2 github.com/pkg/errors v0.9.1 - google.golang.org/grpc v1.71.0 + google.golang.org/grpc v1.71.1 ) require ( dario.cat/mergo v1.0.1 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect - github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.3.1 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect - github.com/aserto-dev/go-directory v0.33.7 // indirect - github.com/aserto-dev/logger v0.0.7 // indirect - github.com/cjlapao/common-go v0.0.41 // indirect + github.com/aserto-dev/go-directory v0.33.10 // indirect + github.com/aserto-dev/logger v0.0.9 // indirect + github.com/cjlapao/common-go v0.0.49 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dongri/phonenumber v0.1.12 // indirect github.com/go-logr/logr v1.4.2 // indirect @@ -42,29 +42,29 @@ require ( github.com/kylelemons/godebug v1.1.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/microsoft/kiota-serialization-form-go v1.0.0 // indirect - github.com/microsoft/kiota-serialization-multipart-go v1.0.0 // indirect - github.com/microsoft/kiota-serialization-text-go v1.0.0 // indirect + github.com/microsoft/kiota-serialization-form-go v1.1.2 // indirect + github.com/microsoft/kiota-serialization-multipart-go v1.1.2 // indirect + github.com/microsoft/kiota-serialization-text-go v1.1.2 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rs/zerolog v1.33.0 // indirect + github.com/rs/zerolog v1.34.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/spf13/cast v1.7.1 // indirect - github.com/std-uritemplate/std-uritemplate/go/v2 v2.0.1 // indirect + github.com/std-uritemplate/std-uritemplate/go/v2 v2.0.3 // indirect github.com/stretchr/testify v1.10.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.34.0 // indirect - go.opentelemetry.io/otel/metric v1.34.0 // indirect - go.opentelemetry.io/otel/trace v1.34.0 // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/net v0.37.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/protobuf v1.36.5 // indirect + go.opentelemetry.io/otel v1.35.0 // indirect + go.opentelemetry.io/otel/metric v1.35.0 // indirect + go.opentelemetry.io/otel/trace v1.35.0 // indirect + golang.org/x/crypto v0.37.0 // indirect + golang.org/x/net v0.39.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/plugins/azuread/go.sum b/plugins/azuread/go.sum index ee8bc9a2..aaaf0728 100644 --- a/plugins/azuread/go.sum +++ b/plugins/azuread/go.sum @@ -2,16 +2,25 @@ dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0 h1:JZg6HRh6W6U4OLl6lk7BZ7BLisIzM9dG1R50zUk9C/M= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0/go.mod h1:YL1xnZ6QejvQHWJrX/AvhFl4WW4rqHVoKspWNVwFk0M= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 h1:Gt0j3wceWMwPmiazCa8MzMA0MfhmPIz0Qp0FJ6qcM0U= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 h1:B/dfvscEQtew9dVuoxqxrUKKv8Ih2f55PydknDamU+g= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0/go.mod h1:fiPSssYvltE08HJchL04dOy+RD4hgrjph0cwGGMntdI= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0 h1:OVoM452qUFBrX+URdH3VpR299ma4kfom0yB0URYky9g= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0/go.mod h1:kUjrAo8bgEwLeZ/CmHqNl3Z/kPm7y6FKfxxK0izYUg4= github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0 h1:+m0M/LFxN43KvULkDNfdXOgrjtg6UYJPFBJyuEcRCAw= github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0/go.mod h1:PwOyop78lveYMRs6oCxjiVyBdyCgIYH6XHIVZO9/SFQ= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 h1:FPKJS1T+clwv+OLGt13a8UjqeRuh0O4SJ3lUriThc+4= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1/go.mod h1:j2chePtV91HrC22tGoRX3sGY42uF13WzmmV80/OdVAA= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2 h1:kYRSnvJju5gYVyhkij+RTJ/VR6QIUaCfWeaFm2ycsjQ= github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs= +github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= @@ -22,18 +31,26 @@ github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8v github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/kong v1.8.1 h1:6aamvWBE/REnR/BCq10EcozmcpUPc5aGI1lPAWdB0EE= github.com/alecthomas/kong v1.8.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= +github.com/alecthomas/kong v1.10.0 h1:8K4rGDpT7Iu+jEXCIJUeKqvpwZHbsFRoebLbnzlmrpw= +github.com/alecthomas/kong v1.10.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/aserto-dev/go-directory v0.33.7 h1:jldr2cGQp5EYM4l3IKSNyuK3Rr30taQ7MejbIHt+rGQ= github.com/aserto-dev/go-directory v0.33.7/go.mod h1:mY53j91JUnGRk9lsfw3yxgQXO41SCnt2bSP/2PamxCo= +github.com/aserto-dev/go-directory v0.33.10 h1:PLevCAWc9QeLZZv5Wc+yGk4psSd3507y1+9Fps+CzdI= +github.com/aserto-dev/go-directory v0.33.10/go.mod h1:CYRXxtDtf4zSwYYBBkGqW3b7HWJWvoIEBWgah9SGMAM= github.com/aserto-dev/logger v0.0.7 h1:ORvXxZDMNIcN/E3SYHj8fxmNZnOD7Gf87pOLB2XQavw= github.com/aserto-dev/logger v0.0.7/go.mod h1:66ff7ALo68NT1HcCg5zytOnGh6I5R0HeDpN85cwHcD0= +github.com/aserto-dev/logger v0.0.9 h1:QH11l8937Sw+GAe2yvgpoLg70fqQvPrEufkXAmDUk0g= +github.com/aserto-dev/logger v0.0.9/go.mod h1:mMXq/bhdIKoOVsIZ2zJOqgjcc/jR2x14FhU0St/8AVQ= github.com/aserto-dev/msgraph-sdk-go v0.0.3 h1:vfDJe1/rlYlWGNOILyg+idYi1EHzRW8USgr7U4mM6uA= github.com/aserto-dev/msgraph-sdk-go v0.0.3/go.mod h1:lXsORtVthvPSKCIk1O73XCWEFq7+3xo/qq/BVbv7Yf0= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cjlapao/common-go v0.0.41 h1:j30UKZJWVWIllJ66x3EOslJvIk/VjkyenrhEcH64dGM= github.com/cjlapao/common-go v0.0.41/go.mod h1:ao5wEp0hYMNehJiHoarSjc5dKK5wi4LvnwjXaC2SxUI= +github.com/cjlapao/common-go v0.0.49 h1:+SPPte2BMQM0hF0A3ceNGfvq0LP+wWBZHjdvk9c/5UQ= +github.com/cjlapao/common-go v0.0.49/go.mod h1:wWif40/s6IIjaT+BO01Bo6VeYzz7IQ23BOj6xi/pAqw= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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= @@ -65,6 +82,7 @@ github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs= github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw= +github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -80,20 +98,36 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/microsoft/kiota-abstractions-go v1.8.1 h1:0gtK3KERmbKYm5AxJLZ8WPlNR9eACUGWuofFIa01PnA= github.com/microsoft/kiota-abstractions-go v1.8.1/go.mod h1:YO2QCJyNM9wzvlgGLepw6s9XrPgNHODOYGVDCqQWdLI= +github.com/microsoft/kiota-abstractions-go v1.9.2 h1:3U5VgN2YGe3lsu1pyuS0t5jxv1llxX2ophwX8ewE6wQ= +github.com/microsoft/kiota-abstractions-go v1.9.2/go.mod h1:f06pl3qSyvUHEfVNkiRpXPkafx7khZqQEb71hN/pmuU= github.com/microsoft/kiota-authentication-azure-go v1.1.0 h1:HudH57Enel9zFQ4TEaJw6lMiyZ5RbBdrRHwdU0NP2RY= github.com/microsoft/kiota-authentication-azure-go v1.1.0/go.mod h1:zfPFOiLdEqM77Hua5B/2vpcXrVaGqSWjHSRzlvAWEgc= +github.com/microsoft/kiota-authentication-azure-go v1.3.0 h1:PWH6PgtzhJjnmvR6N1CFjriwX09Kv7S5K3vL6VbPVrg= +github.com/microsoft/kiota-authentication-azure-go v1.3.0/go.mod h1:l/MPGUVvD7xfQ+MYSdZaFPv0CsLDqgSOp8mXwVgArIs= github.com/microsoft/kiota-http-go v1.4.7 h1:yFmwYLlCCkeYGDZyvBgfoHWAadOwmg4XQyx35CBkwU8= github.com/microsoft/kiota-http-go v1.4.7/go.mod h1:Kup5nMDD3a9sjdgRKHCqZWqtrv3FbprjcPaGjLR6FzM= +github.com/microsoft/kiota-http-go v1.5.3 h1:l5LfdREjYhYWvGUGCqI0kesJqE/v/LzXyJ3//McB3us= +github.com/microsoft/kiota-http-go v1.5.3/go.mod h1:L+5Ri+SzwELnUcNA0cpbFKp/pBbvypLh3Cd1PR6sjx0= github.com/microsoft/kiota-serialization-form-go v1.0.0 h1:UNdrkMnLFqUCccQZerKjblsyVgifS11b3WCx+eFEsAI= github.com/microsoft/kiota-serialization-form-go v1.0.0/go.mod h1:h4mQOO6KVTNciMF6azi1J9QB19ujSw3ULKcSNyXXOMA= +github.com/microsoft/kiota-serialization-form-go v1.1.2 h1:SD6MATqNw+Dc5beILlsb/D87C36HKC/Zw7l+N9+HY2A= +github.com/microsoft/kiota-serialization-form-go v1.1.2/go.mod h1:m4tY2JT42jAZmgbqFwPy3zGDF+NPJACuyzmjNXeuHio= github.com/microsoft/kiota-serialization-json-go v1.0.9 h1:lJivec0G0tI6T8McBTnucyyYXczXytwcu1pt0UjWSBY= github.com/microsoft/kiota-serialization-json-go v1.0.9/go.mod h1:AxrS/Gbmr8y/hIp2pJcpTup/2wCE8ED+VEXkf/9xKb4= +github.com/microsoft/kiota-serialization-json-go v1.1.2 h1:eJrPWeQ665nbjO0gsHWJ0Bw6V/ZHHU1OfFPaYfRG39k= +github.com/microsoft/kiota-serialization-json-go v1.1.2/go.mod h1:deaGt7fjZarywyp7TOTiRsjfYiyWxwJJPQZytXwYQn8= github.com/microsoft/kiota-serialization-multipart-go v1.0.0 h1:3O5sb5Zj+moLBiJympbXNaeV07K0d46IfuEd5v9+pBs= github.com/microsoft/kiota-serialization-multipart-go v1.0.0/go.mod h1:yauLeBTpANk4L03XD985akNysG24SnRJGaveZf+p4so= +github.com/microsoft/kiota-serialization-multipart-go v1.1.2 h1:1pUyA1QgIeKslQwbk7/ox1TehjlCUUT3r1f8cNlkvn4= +github.com/microsoft/kiota-serialization-multipart-go v1.1.2/go.mod h1:j2K7ZyYErloDu7Kuuk993DsvfoP7LPWvAo7rfDpdPio= github.com/microsoft/kiota-serialization-text-go v1.0.0 h1:XOaRhAXy+g8ZVpcq7x7a0jlETWnWrEum0RhmbYrTFnA= github.com/microsoft/kiota-serialization-text-go v1.0.0/go.mod h1:sM1/C6ecnQ7IquQOGUrUldaO5wj+9+v7G2W3sQ3fy6M= +github.com/microsoft/kiota-serialization-text-go v1.1.2 h1:7OfKFlzdjpPygca/+OtqafkEqCWR7+94efUFGC28cLw= +github.com/microsoft/kiota-serialization-text-go v1.1.2/go.mod h1:QNTcswkBPFY3QVBFmzfk00UMNViKQtV0AQKCrRw5ibM= github.com/microsoftgraph/msgraph-sdk-go-core v1.2.1 h1:P1wpmn3xxfPMFJHg+PJPcusErfRkl63h6OdAnpDbkS8= github.com/microsoftgraph/msgraph-sdk-go-core v1.2.1/go.mod h1:vFmWQGWyLlhxCESNLv61vlE4qesBU+eWmEVH7DJSESA= +github.com/microsoftgraph/msgraph-sdk-go-core v1.3.2 h1:5jCUSosTKaINzPPQXsz7wsHWwknyBmJSu8+ZWxx3kdQ= +github.com/microsoftgraph/msgraph-sdk-go-core v1.3.2/go.mod h1:iD75MK3LX8EuwjDYCmh0hkojKXK6VKME33u4daCo3cE= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= @@ -108,51 +142,79 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= +github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/std-uritemplate/std-uritemplate/go/v2 v2.0.1 h1:/m2cTZHpqgofDsrwPqsASI6fSNMNhb+9EmUYtHEV2Uk= github.com/std-uritemplate/std-uritemplate/go/v2 v2.0.1/go.mod h1:Z5KcoM0YLC7INlNhEezeIZ0TZNYf7WSNO0Lvah4DSeQ= +github.com/std-uritemplate/std-uritemplate/go/v2 v2.0.3 h1:7hth9376EoQEd1hH4lAp3vnaLP2UMyxuMMghLKzDHyU= +github.com/std-uritemplate/std-uritemplate/go/v2 v2.0.3/go.mod h1:Z5KcoM0YLC7INlNhEezeIZ0TZNYf7WSNO0Lvah4DSeQ= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a h1:OQ7sHVzkx6L57dQpzUS4ckfWJ51KDH74XHTDe23xWAs= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a/go.mod h1:2R6XrVC8Oc08GlNh8ujEpc7HkLiEZ16QeY7FxIs20ac= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a h1:GIqLhp/cYUkuGuiT+vJk8vhOP86L4+SP5j8yXgeVpvI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= +google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= +google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/plugins/azuread/pkg/app/cli.go b/plugins/azuread/pkg/app/cli.go index 73dc6cb2..125e1e48 100644 --- a/plugins/azuread/pkg/app/cli.go +++ b/plugins/azuread/pkg/app/cli.go @@ -31,7 +31,10 @@ func (cmd *VersionCmd) Run() error { return nil } -func createAzureAdClient(ctx context.Context, tenant, clientID, clientSecret, refreshToken string) (azureClient *azureclient.AzureADClient, err error) { +func createAzureAdClient( + ctx context.Context, + tenant, clientID, clientSecret, refreshToken string, +) (*azureclient.AzureADClient, error) { if refreshToken != "" { return azureclient.NewAzureADClientWithRefreshToken( ctx, diff --git a/plugins/azuread/pkg/app/constants.go b/plugins/azuread/pkg/app/constants.go index dc57e4b3..536a0551 100644 --- a/plugins/azuread/pkg/app/constants.go +++ b/plugins/azuread/pkg/app/constants.go @@ -1,4 +1,6 @@ package app -const AppName = "ds-load-azuread" -const AppDescription = "AzureAD directory loader" +const ( + AppName = "ds-load-azuread" + AppDescription = "AzureAD directory loader" +) diff --git a/plugins/azuread/pkg/app/fetch.go b/plugins/azuread/pkg/app/fetch.go index 22472d92..e9e8c20c 100644 --- a/plugins/azuread/pkg/app/fetch.go +++ b/plugins/azuread/pkg/app/fetch.go @@ -4,9 +4,11 @@ import ( "os" "github.com/aserto-dev/ds-load/plugins/azuread/pkg/fetch" + "github.com/aserto-dev/ds-load/sdk/common" "github.com/aserto-dev/ds-load/sdk/common/cc" ) +//nolint:lll // user and group properties include complex defaults. type FetchCmd struct { Tenant string `short:"a" help:"AzureAD tenant" env:"AZUREAD_TENANT" required:""` ClientID string `short:"i" help:"AzureAD Client ID" env:"AZUREAD_CLIENT_ID" required:""` @@ -28,5 +30,5 @@ func (cmd *FetchCmd) Run(ctx *cc.CommonCtx) error { return err } - return fetcher.WithGroups(cmd.Groups).Fetch(ctx.Context, os.Stdout, os.Stderr) + return fetcher.WithGroups(cmd.Groups).Fetch(ctx.Context, os.Stdout, common.NewErrorWriter(os.Stderr)) } diff --git a/plugins/azuread/pkg/azureclient/credential.go b/plugins/azuread/pkg/azureclient/credential.go index c8e83da2..646a30b0 100644 --- a/plugins/azuread/pkg/azureclient/credential.go +++ b/plugins/azuread/pkg/azureclient/credential.go @@ -22,7 +22,9 @@ type RefreshTokenCredential struct { tenantID string } -func NewRefreshTokenCredential(ctx context.Context, tenantID, clientID, clientSecret, refreshToken string) (*RefreshTokenCredential, error) { +func NewRefreshTokenCredential(ctx context.Context, + tenantID, clientID, clientSecret, refreshToken string, +) (*RefreshTokenCredential, error) { c := &RefreshTokenCredential{ clientID: clientID, clientSecret: clientSecret, @@ -42,12 +44,12 @@ func (c *RefreshTokenCredential) GetToken(ctx context.Context, options policy.To payload := strings.NewReader(data) // create the request and execute it - req, err := http.NewRequestWithContext(ctx, "POST", url, payload) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, payload) if err != nil { return accessToken, err } - req.Header.Add("content-type", "application/x-www-form-urlencoded") + req.Header.Add("Content-Type", "application/x-www-form-urlencoded") res, err := http.DefaultClient.Do(req) if err != nil { @@ -57,7 +59,7 @@ func (c *RefreshTokenCredential) GetToken(ctx context.Context, options policy.To // process the response defer res.Body.Close() - var responseData map[string]interface{} + var responseData map[string]any body, _ := io.ReadAll(res.Body) @@ -68,14 +70,29 @@ func (c *RefreshTokenCredential) GetToken(ctx context.Context, options policy.To // check for error if responseData["error_description"] != nil { - errorMessage := responseData["error_description"].(string) + errorMessage, ok := responseData["error_description"].(string) + if !ok { + return accessToken, status.Error(codes.InvalidArgument, "failed to get error description") + } + return accessToken, status.Error(codes.InvalidArgument, errorMessage) } // retrieve the access token and expiration - accessToken.Token = responseData["access_token"].(string) - expiresIn := int(responseData["expires_in"].(float64)) - accessToken.ExpiresOn = time.Now().Add(time.Second * time.Duration(expiresIn)) + // retrieve the access token and expiration + token, ok := responseData["access_token"].(string) + if !ok { + return accessToken, status.Error(codes.InvalidArgument, "'access_token' must be a string") + } + + accessToken.Token = token + + expiresIn, ok := responseData["expires_in"].(float64) + if !ok { + return accessToken, status.Error(codes.InvalidArgument, "'exprires_in' must be a float") + } + + accessToken.ExpiresOn = time.Now().Add(time.Second * time.Duration(int(expiresIn))) return accessToken, nil } diff --git a/plugins/azuread/pkg/fetch/fetch.go b/plugins/azuread/pkg/fetch/fetch.go index dab97f0e..c8e0b373 100644 --- a/plugins/azuread/pkg/fetch/fetch.go +++ b/plugins/azuread/pkg/fetch/fetch.go @@ -2,12 +2,14 @@ package fetch import ( "context" - "encoding/json" "io" + "iter" "github.com/aserto-dev/ds-load/plugins/azuread/pkg/azureclient" "github.com/aserto-dev/ds-load/sdk/common" "github.com/aserto-dev/ds-load/sdk/common/js" + "github.com/aserto-dev/ds-load/sdk/fetcher" + "github.com/aserto-dev/msgraph-sdk-go/models" kiota "github.com/microsoft/kiota-serialization-json-go" ) @@ -31,77 +33,74 @@ func (f *Fetcher) WithGroups(groups bool) *Fetcher { return f } -func (f *Fetcher) Fetch(ctx context.Context, outputWriter, errorWriter io.Writer) error { +func (f *Fetcher) Fetch(ctx context.Context, outputWriter io.Writer, errorWriter common.ErrorWriter) error { jsonWriter := js.NewJSONArrayWriter(outputWriter) defer jsonWriter.Close() if f.Groups { - aadGroups, err := f.azureClient.ListGroups(ctx, f.groupProps) - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - } - - for _, group := range aadGroups { - writer := kiota.NewJsonSerializationWriter() + for obj, err := range f.fetchGroups(ctx) { + errorWriter.Error(err, common.WithExitCode) - err := group.Serialize(writer) - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - return err - } - - groupBytes, err := writer.GetSerializedContent() - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - return err - } - - groupString := "{" + string(groupBytes) + "}" + err := jsonWriter.Write(obj) + errorWriter.Error(err) + } + } - var obj map[string]interface{} - if err := json.Unmarshal([]byte(groupString), &obj); err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - return err - } + for user, err := range f.fetchUsers(ctx) { + errorWriter.Error(err, common.WithExitCode) - if err := jsonWriter.Write(obj); err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } - } + err := jsonWriter.Write(user) + errorWriter.Error(err) } + return nil +} + +func (f *Fetcher) fetchUsers(ctx context.Context) iter.Seq2[map[string]any, error] { aadUsers, err := f.azureClient.ListUsers(ctx, f.Groups, f.userProps) if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) + return fetcher.YieldError(err) } - for _, user := range aadUsers { + return fetcher.YieldMap(aadUsers, func(user models.Userable) ([]byte, error) { writer := kiota.NewJsonSerializationWriter() err := user.Serialize(writer) if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - return err + return nil, err } - userBytes, err := writer.GetSerializedContent() + objBytes, err := writer.GetSerializedContent() if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - return err + return nil, err } - userString := "{" + string(userBytes) + "}" + objString := "{" + string(objBytes) + "}" - var obj map[string]interface{} - if err := json.Unmarshal([]byte(userString), &obj); err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - return err + return []byte(objString), nil + }) +} + +func (f *Fetcher) fetchGroups(ctx context.Context) iter.Seq2[map[string]any, error] { + aadGroups, err := f.azureClient.ListGroups(ctx, f.groupProps) + if err != nil { + return fetcher.YieldError(err) + } + + return fetcher.YieldMap(aadGroups, func(group models.Groupable) ([]byte, error) { + writer := kiota.NewJsonSerializationWriter() + + if err := group.Serialize(writer); err != nil { + return nil, err } - if err := jsonWriter.Write(obj); err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) + objBytes, err := writer.GetSerializedContent() + if err != nil { + return nil, err } - } - return nil + objString := "{" + string(objBytes) + "}" + + return []byte(objString), nil + }) } diff --git a/plugins/azureadb2c/go.mod b/plugins/azureadb2c/go.mod index 92b65ef9..851d365c 100644 --- a/plugins/azureadb2c/go.mod +++ b/plugins/azureadb2c/go.mod @@ -7,30 +7,30 @@ toolchain go1.24.1 replace github.com/aserto-dev/ds-load/sdk => ../../sdk require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0 - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 - github.com/alecthomas/kong v1.8.1 - github.com/aserto-dev/ds-load/sdk v0.0.0-20241206112725-5d200d771446 + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0 + github.com/alecthomas/kong v1.10.0 + github.com/aserto-dev/ds-load/sdk v0.0.0-20250408143332-e8965667fcc0 github.com/aserto-dev/msgraph-sdk-go v0.0.3 - github.com/microsoft/kiota-abstractions-go v1.8.1 - github.com/microsoft/kiota-authentication-azure-go v1.1.0 - github.com/microsoft/kiota-http-go v1.4.7 - github.com/microsoft/kiota-serialization-json-go v1.0.9 - github.com/microsoftgraph/msgraph-sdk-go-core v1.2.1 + github.com/microsoft/kiota-abstractions-go v1.9.2 + github.com/microsoft/kiota-authentication-azure-go v1.3.0 + github.com/microsoft/kiota-http-go v1.5.3 + github.com/microsoft/kiota-serialization-json-go v1.1.2 + github.com/microsoftgraph/msgraph-sdk-go-core v1.3.2 github.com/pkg/errors v0.9.1 - google.golang.org/grpc v1.71.0 + google.golang.org/grpc v1.71.1 ) require ( dario.cat/mergo v1.0.1 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect - github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.3.1 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect - github.com/aserto-dev/go-directory v0.33.7 // indirect - github.com/aserto-dev/logger v0.0.7 // indirect - github.com/cjlapao/common-go v0.0.41 // indirect + github.com/aserto-dev/go-directory v0.33.10 // indirect + github.com/aserto-dev/logger v0.0.9 // indirect + github.com/cjlapao/common-go v0.0.49 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dongri/phonenumber v0.1.12 // indirect github.com/go-logr/logr v1.4.2 // indirect @@ -42,29 +42,29 @@ require ( github.com/kylelemons/godebug v1.1.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/microsoft/kiota-serialization-form-go v1.0.0 // indirect - github.com/microsoft/kiota-serialization-multipart-go v1.0.0 // indirect - github.com/microsoft/kiota-serialization-text-go v1.0.0 // indirect + github.com/microsoft/kiota-serialization-form-go v1.1.2 // indirect + github.com/microsoft/kiota-serialization-multipart-go v1.1.2 // indirect + github.com/microsoft/kiota-serialization-text-go v1.1.2 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rs/zerolog v1.33.0 // indirect + github.com/rs/zerolog v1.34.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/spf13/cast v1.7.1 // indirect - github.com/std-uritemplate/std-uritemplate/go/v2 v2.0.1 // indirect + github.com/std-uritemplate/std-uritemplate/go/v2 v2.0.3 // indirect github.com/stretchr/testify v1.10.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.34.0 // indirect - go.opentelemetry.io/otel/metric v1.34.0 // indirect - go.opentelemetry.io/otel/trace v1.34.0 // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/net v0.37.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/protobuf v1.36.5 // indirect + go.opentelemetry.io/otel v1.35.0 // indirect + go.opentelemetry.io/otel/metric v1.35.0 // indirect + go.opentelemetry.io/otel/trace v1.35.0 // indirect + golang.org/x/crypto v0.37.0 // indirect + golang.org/x/net v0.39.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/plugins/azureadb2c/go.sum b/plugins/azureadb2c/go.sum index ee8bc9a2..74d8c78c 100644 --- a/plugins/azureadb2c/go.sum +++ b/plugins/azureadb2c/go.sum @@ -2,16 +2,24 @@ dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0 h1:JZg6HRh6W6U4OLl6lk7BZ7BLisIzM9dG1R50zUk9C/M= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0/go.mod h1:YL1xnZ6QejvQHWJrX/AvhFl4WW4rqHVoKspWNVwFk0M= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0 h1:Gt0j3wceWMwPmiazCa8MzMA0MfhmPIz0Qp0FJ6qcM0U= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.0/go.mod h1:Ot/6aikWnKWi4l9QB7qVSwa8iMphQNqkWALMoNT3rzM= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 h1:B/dfvscEQtew9dVuoxqxrUKKv8Ih2f55PydknDamU+g= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0/go.mod h1:fiPSssYvltE08HJchL04dOy+RD4hgrjph0cwGGMntdI= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0 h1:OVoM452qUFBrX+URdH3VpR299ma4kfom0yB0URYky9g= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.9.0/go.mod h1:kUjrAo8bgEwLeZ/CmHqNl3Z/kPm7y6FKfxxK0izYUg4= github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0 h1:+m0M/LFxN43KvULkDNfdXOgrjtg6UYJPFBJyuEcRCAw= github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.0/go.mod h1:PwOyop78lveYMRs6oCxjiVyBdyCgIYH6XHIVZO9/SFQ= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 h1:FPKJS1T+clwv+OLGt13a8UjqeRuh0O4SJ3lUriThc+4= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1/go.mod h1:j2chePtV91HrC22tGoRX3sGY42uF13WzmmV80/OdVAA= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2 h1:kYRSnvJju5gYVyhkij+RTJ/VR6QIUaCfWeaFm2ycsjQ= github.com/AzureAD/microsoft-authentication-library-for-go v1.3.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs= +github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= @@ -22,18 +30,26 @@ github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8v github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/kong v1.8.1 h1:6aamvWBE/REnR/BCq10EcozmcpUPc5aGI1lPAWdB0EE= github.com/alecthomas/kong v1.8.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= +github.com/alecthomas/kong v1.10.0 h1:8K4rGDpT7Iu+jEXCIJUeKqvpwZHbsFRoebLbnzlmrpw= +github.com/alecthomas/kong v1.10.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/aserto-dev/go-directory v0.33.7 h1:jldr2cGQp5EYM4l3IKSNyuK3Rr30taQ7MejbIHt+rGQ= github.com/aserto-dev/go-directory v0.33.7/go.mod h1:mY53j91JUnGRk9lsfw3yxgQXO41SCnt2bSP/2PamxCo= +github.com/aserto-dev/go-directory v0.33.10 h1:PLevCAWc9QeLZZv5Wc+yGk4psSd3507y1+9Fps+CzdI= +github.com/aserto-dev/go-directory v0.33.10/go.mod h1:CYRXxtDtf4zSwYYBBkGqW3b7HWJWvoIEBWgah9SGMAM= github.com/aserto-dev/logger v0.0.7 h1:ORvXxZDMNIcN/E3SYHj8fxmNZnOD7Gf87pOLB2XQavw= github.com/aserto-dev/logger v0.0.7/go.mod h1:66ff7ALo68NT1HcCg5zytOnGh6I5R0HeDpN85cwHcD0= +github.com/aserto-dev/logger v0.0.9 h1:QH11l8937Sw+GAe2yvgpoLg70fqQvPrEufkXAmDUk0g= +github.com/aserto-dev/logger v0.0.9/go.mod h1:mMXq/bhdIKoOVsIZ2zJOqgjcc/jR2x14FhU0St/8AVQ= github.com/aserto-dev/msgraph-sdk-go v0.0.3 h1:vfDJe1/rlYlWGNOILyg+idYi1EHzRW8USgr7U4mM6uA= github.com/aserto-dev/msgraph-sdk-go v0.0.3/go.mod h1:lXsORtVthvPSKCIk1O73XCWEFq7+3xo/qq/BVbv7Yf0= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cjlapao/common-go v0.0.41 h1:j30UKZJWVWIllJ66x3EOslJvIk/VjkyenrhEcH64dGM= github.com/cjlapao/common-go v0.0.41/go.mod h1:ao5wEp0hYMNehJiHoarSjc5dKK5wi4LvnwjXaC2SxUI= +github.com/cjlapao/common-go v0.0.49 h1:+SPPte2BMQM0hF0A3ceNGfvq0LP+wWBZHjdvk9c/5UQ= +github.com/cjlapao/common-go v0.0.49/go.mod h1:wWif40/s6IIjaT+BO01Bo6VeYzz7IQ23BOj6xi/pAqw= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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= @@ -80,20 +96,36 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/microsoft/kiota-abstractions-go v1.8.1 h1:0gtK3KERmbKYm5AxJLZ8WPlNR9eACUGWuofFIa01PnA= github.com/microsoft/kiota-abstractions-go v1.8.1/go.mod h1:YO2QCJyNM9wzvlgGLepw6s9XrPgNHODOYGVDCqQWdLI= +github.com/microsoft/kiota-abstractions-go v1.9.2 h1:3U5VgN2YGe3lsu1pyuS0t5jxv1llxX2ophwX8ewE6wQ= +github.com/microsoft/kiota-abstractions-go v1.9.2/go.mod h1:f06pl3qSyvUHEfVNkiRpXPkafx7khZqQEb71hN/pmuU= github.com/microsoft/kiota-authentication-azure-go v1.1.0 h1:HudH57Enel9zFQ4TEaJw6lMiyZ5RbBdrRHwdU0NP2RY= github.com/microsoft/kiota-authentication-azure-go v1.1.0/go.mod h1:zfPFOiLdEqM77Hua5B/2vpcXrVaGqSWjHSRzlvAWEgc= +github.com/microsoft/kiota-authentication-azure-go v1.3.0 h1:PWH6PgtzhJjnmvR6N1CFjriwX09Kv7S5K3vL6VbPVrg= +github.com/microsoft/kiota-authentication-azure-go v1.3.0/go.mod h1:l/MPGUVvD7xfQ+MYSdZaFPv0CsLDqgSOp8mXwVgArIs= github.com/microsoft/kiota-http-go v1.4.7 h1:yFmwYLlCCkeYGDZyvBgfoHWAadOwmg4XQyx35CBkwU8= github.com/microsoft/kiota-http-go v1.4.7/go.mod h1:Kup5nMDD3a9sjdgRKHCqZWqtrv3FbprjcPaGjLR6FzM= +github.com/microsoft/kiota-http-go v1.5.3 h1:l5LfdREjYhYWvGUGCqI0kesJqE/v/LzXyJ3//McB3us= +github.com/microsoft/kiota-http-go v1.5.3/go.mod h1:L+5Ri+SzwELnUcNA0cpbFKp/pBbvypLh3Cd1PR6sjx0= github.com/microsoft/kiota-serialization-form-go v1.0.0 h1:UNdrkMnLFqUCccQZerKjblsyVgifS11b3WCx+eFEsAI= github.com/microsoft/kiota-serialization-form-go v1.0.0/go.mod h1:h4mQOO6KVTNciMF6azi1J9QB19ujSw3ULKcSNyXXOMA= +github.com/microsoft/kiota-serialization-form-go v1.1.2 h1:SD6MATqNw+Dc5beILlsb/D87C36HKC/Zw7l+N9+HY2A= +github.com/microsoft/kiota-serialization-form-go v1.1.2/go.mod h1:m4tY2JT42jAZmgbqFwPy3zGDF+NPJACuyzmjNXeuHio= github.com/microsoft/kiota-serialization-json-go v1.0.9 h1:lJivec0G0tI6T8McBTnucyyYXczXytwcu1pt0UjWSBY= github.com/microsoft/kiota-serialization-json-go v1.0.9/go.mod h1:AxrS/Gbmr8y/hIp2pJcpTup/2wCE8ED+VEXkf/9xKb4= +github.com/microsoft/kiota-serialization-json-go v1.1.2 h1:eJrPWeQ665nbjO0gsHWJ0Bw6V/ZHHU1OfFPaYfRG39k= +github.com/microsoft/kiota-serialization-json-go v1.1.2/go.mod h1:deaGt7fjZarywyp7TOTiRsjfYiyWxwJJPQZytXwYQn8= github.com/microsoft/kiota-serialization-multipart-go v1.0.0 h1:3O5sb5Zj+moLBiJympbXNaeV07K0d46IfuEd5v9+pBs= github.com/microsoft/kiota-serialization-multipart-go v1.0.0/go.mod h1:yauLeBTpANk4L03XD985akNysG24SnRJGaveZf+p4so= +github.com/microsoft/kiota-serialization-multipart-go v1.1.2 h1:1pUyA1QgIeKslQwbk7/ox1TehjlCUUT3r1f8cNlkvn4= +github.com/microsoft/kiota-serialization-multipart-go v1.1.2/go.mod h1:j2K7ZyYErloDu7Kuuk993DsvfoP7LPWvAo7rfDpdPio= github.com/microsoft/kiota-serialization-text-go v1.0.0 h1:XOaRhAXy+g8ZVpcq7x7a0jlETWnWrEum0RhmbYrTFnA= github.com/microsoft/kiota-serialization-text-go v1.0.0/go.mod h1:sM1/C6ecnQ7IquQOGUrUldaO5wj+9+v7G2W3sQ3fy6M= +github.com/microsoft/kiota-serialization-text-go v1.1.2 h1:7OfKFlzdjpPygca/+OtqafkEqCWR7+94efUFGC28cLw= +github.com/microsoft/kiota-serialization-text-go v1.1.2/go.mod h1:QNTcswkBPFY3QVBFmzfk00UMNViKQtV0AQKCrRw5ibM= github.com/microsoftgraph/msgraph-sdk-go-core v1.2.1 h1:P1wpmn3xxfPMFJHg+PJPcusErfRkl63h6OdAnpDbkS8= github.com/microsoftgraph/msgraph-sdk-go-core v1.2.1/go.mod h1:vFmWQGWyLlhxCESNLv61vlE4qesBU+eWmEVH7DJSESA= +github.com/microsoftgraph/msgraph-sdk-go-core v1.3.2 h1:5jCUSosTKaINzPPQXsz7wsHWwknyBmJSu8+ZWxx3kdQ= +github.com/microsoftgraph/msgraph-sdk-go-core v1.3.2/go.mod h1:iD75MK3LX8EuwjDYCmh0hkojKXK6VKME33u4daCo3cE= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= @@ -111,48 +143,75 @@ github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJ github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/std-uritemplate/std-uritemplate/go/v2 v2.0.1 h1:/m2cTZHpqgofDsrwPqsASI6fSNMNhb+9EmUYtHEV2Uk= github.com/std-uritemplate/std-uritemplate/go/v2 v2.0.1/go.mod h1:Z5KcoM0YLC7INlNhEezeIZ0TZNYf7WSNO0Lvah4DSeQ= +github.com/std-uritemplate/std-uritemplate/go/v2 v2.0.3 h1:7hth9376EoQEd1hH4lAp3vnaLP2UMyxuMMghLKzDHyU= +github.com/std-uritemplate/std-uritemplate/go/v2 v2.0.3/go.mod h1:Z5KcoM0YLC7INlNhEezeIZ0TZNYf7WSNO0Lvah4DSeQ= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a h1:OQ7sHVzkx6L57dQpzUS4ckfWJ51KDH74XHTDe23xWAs= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a/go.mod h1:2R6XrVC8Oc08GlNh8ujEpc7HkLiEZ16QeY7FxIs20ac= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a h1:GIqLhp/cYUkuGuiT+vJk8vhOP86L4+SP5j8yXgeVpvI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= +google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= +google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/plugins/azureadb2c/pkg/app/cli.go b/plugins/azureadb2c/pkg/app/cli.go index 2153cf0f..76547039 100644 --- a/plugins/azureadb2c/pkg/app/cli.go +++ b/plugins/azureadb2c/pkg/app/cli.go @@ -31,7 +31,9 @@ func (cmd *VersionCmd) Run() error { return nil } -func createAzureAdClient(ctx context.Context, tenant, clientID, clientSecret, refreshToken string) (azureClient *azureclient.AzureADClient, err error) { +func createAzureAdClient(ctx context.Context, + tenant, clientID, clientSecret, refreshToken string, +) (*azureclient.AzureADClient, error) { if refreshToken != "" { return azureclient.NewAzureADClientWithRefreshToken( ctx, diff --git a/plugins/azureadb2c/pkg/app/constants.go b/plugins/azureadb2c/pkg/app/constants.go index 58073460..ee5b6d94 100644 --- a/plugins/azureadb2c/pkg/app/constants.go +++ b/plugins/azureadb2c/pkg/app/constants.go @@ -1,4 +1,6 @@ package app -const AppName = "ds-load-azureadb2c" -const AppDescription = "AzureAD B2C directory loader" +const ( + AppName = "ds-load-azureadb2c" + AppDescription = "AzureAD B2C directory loader" +) diff --git a/plugins/azureadb2c/pkg/app/fetch.go b/plugins/azureadb2c/pkg/app/fetch.go index 89c969b6..e03885cf 100644 --- a/plugins/azureadb2c/pkg/app/fetch.go +++ b/plugins/azureadb2c/pkg/app/fetch.go @@ -4,9 +4,11 @@ import ( "os" "github.com/aserto-dev/ds-load/plugins/azureadb2c/pkg/fetch" + "github.com/aserto-dev/ds-load/sdk/common" "github.com/aserto-dev/ds-load/sdk/common/cc" ) +//nolint:lll // user and group properties include complex defaults. type FetchCmd struct { Tenant string `short:"a" help:"AzureAD B2C tenant" env:"AZUREADB2C_TENANT" required:""` ClientID string `short:"i" help:"AzureAD B2C Client ID" env:"AZUREADB2C_CLIENT_ID" required:""` @@ -28,5 +30,5 @@ func (cmd *FetchCmd) Run(ctx *cc.CommonCtx) error { return err } - return fetcher.WithGroups(cmd.Groups).Fetch(ctx.Context, os.Stdout, os.Stderr) + return fetcher.WithGroups(cmd.Groups).Fetch(ctx.Context, os.Stdout, common.NewErrorWriter(os.Stderr)) } diff --git a/plugins/azureadb2c/pkg/azureclient/credential.go b/plugins/azureadb2c/pkg/azureclient/credential.go index c8e83da2..6a3ded90 100644 --- a/plugins/azureadb2c/pkg/azureclient/credential.go +++ b/plugins/azureadb2c/pkg/azureclient/credential.go @@ -22,7 +22,9 @@ type RefreshTokenCredential struct { tenantID string } -func NewRefreshTokenCredential(ctx context.Context, tenantID, clientID, clientSecret, refreshToken string) (*RefreshTokenCredential, error) { +func NewRefreshTokenCredential(ctx context.Context, + tenantID, clientID, clientSecret, refreshToken string, +) (*RefreshTokenCredential, error) { c := &RefreshTokenCredential{ clientID: clientID, clientSecret: clientSecret, @@ -42,12 +44,12 @@ func (c *RefreshTokenCredential) GetToken(ctx context.Context, options policy.To payload := strings.NewReader(data) // create the request and execute it - req, err := http.NewRequestWithContext(ctx, "POST", url, payload) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, payload) if err != nil { return accessToken, err } - req.Header.Add("content-type", "application/x-www-form-urlencoded") + req.Header.Add("Content-Type", "application/x-www-form-urlencoded") res, err := http.DefaultClient.Do(req) if err != nil { @@ -57,7 +59,7 @@ func (c *RefreshTokenCredential) GetToken(ctx context.Context, options policy.To // process the response defer res.Body.Close() - var responseData map[string]interface{} + var responseData map[string]any body, _ := io.ReadAll(res.Body) @@ -68,14 +70,28 @@ func (c *RefreshTokenCredential) GetToken(ctx context.Context, options policy.To // check for error if responseData["error_description"] != nil { - errorMessage := responseData["error_description"].(string) + errorMessage, ok := responseData["error_description"].(string) + if !ok { + return accessToken, status.Error(codes.InvalidArgument, "failed to get error description") + } + return accessToken, status.Error(codes.InvalidArgument, errorMessage) } // retrieve the access token and expiration - accessToken.Token = responseData["access_token"].(string) - expiresIn := int(responseData["expires_in"].(float64)) - accessToken.ExpiresOn = time.Now().Add(time.Second * time.Duration(expiresIn)) + token, ok := responseData["access_token"].(string) + if !ok { + return accessToken, status.Error(codes.InvalidArgument, "'access_token' must be a string") + } + + accessToken.Token = token + + expiresIn, ok := responseData["expires_in"].(float64) + if !ok { + return accessToken, status.Error(codes.InvalidArgument, "'exprires_in' must be a float") + } + + accessToken.ExpiresOn = time.Now().Add(time.Second * time.Duration(int(expiresIn))) return accessToken, nil } diff --git a/plugins/azureadb2c/pkg/fetch/fetch.go b/plugins/azureadb2c/pkg/fetch/fetch.go index f4eeec76..dc63fe65 100644 --- a/plugins/azureadb2c/pkg/fetch/fetch.go +++ b/plugins/azureadb2c/pkg/fetch/fetch.go @@ -2,12 +2,14 @@ package fetch import ( "context" - "encoding/json" "io" + "iter" "github.com/aserto-dev/ds-load/plugins/azureadb2c/pkg/azureclient" "github.com/aserto-dev/ds-load/sdk/common" "github.com/aserto-dev/ds-load/sdk/common/js" + "github.com/aserto-dev/ds-load/sdk/fetcher" + "github.com/aserto-dev/msgraph-sdk-go/models" kiota "github.com/microsoft/kiota-serialization-json-go" ) @@ -31,77 +33,74 @@ func (f *Fetcher) WithGroups(groups bool) *Fetcher { return f } -func (f *Fetcher) Fetch(ctx context.Context, outputWriter, errorWriter io.Writer) error { +func (f *Fetcher) Fetch(ctx context.Context, outputWriter io.Writer, errorWriter common.ErrorWriter) error { jsonWriter := js.NewJSONArrayWriter(outputWriter) defer jsonWriter.Close() if f.Groups { - aadGroups, err := f.azureClient.ListGroups(ctx, f.groupProps) - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - } - - for _, group := range aadGroups { - writer := kiota.NewJsonSerializationWriter() + for obj, err := range f.fetchGroups(ctx) { + errorWriter.Error(err, common.WithExitCode) - err := group.Serialize(writer) - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - return err - } - - groupBytes, err := writer.GetSerializedContent() - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - return err - } - - groupString := "{" + string(groupBytes) + "}" + err := jsonWriter.Write(obj) + errorWriter.Error(err) + } + } - var obj map[string]interface{} - if err := json.Unmarshal([]byte(groupString), &obj); err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - return err - } + for user, err := range f.fetchUsers(ctx) { + errorWriter.Error(err, common.WithExitCode) - if err := jsonWriter.Write(obj); err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } - } + err := jsonWriter.Write(user) + errorWriter.Error(err) } + return nil +} + +func (f *Fetcher) fetchUsers(ctx context.Context) iter.Seq2[map[string]any, error] { aadUsers, err := f.azureClient.ListUsers(ctx, f.Groups, f.userProps) if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) + return fetcher.YieldError(err) } - for _, user := range aadUsers { + return fetcher.YieldMap(aadUsers, func(user models.Userable) ([]byte, error) { writer := kiota.NewJsonSerializationWriter() err := user.Serialize(writer) if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - return err + return nil, err } - userBytes, err := writer.GetSerializedContent() + objBytes, err := writer.GetSerializedContent() if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - return err + return nil, err } - userString := "{" + string(userBytes) + "}" + objString := "{" + string(objBytes) + "}" - var obj map[string]interface{} - if err := json.Unmarshal([]byte(userString), &obj); err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - return err + return []byte(objString), nil + }) +} + +func (f *Fetcher) fetchGroups(ctx context.Context) iter.Seq2[map[string]any, error] { + aadGroups, err := f.azureClient.ListGroups(ctx, f.groupProps) + if err != nil { + return fetcher.YieldError(err) + } + + return fetcher.YieldMap(aadGroups, func(group models.Groupable) ([]byte, error) { + writer := kiota.NewJsonSerializationWriter() + + if err := group.Serialize(writer); err != nil { + return nil, err } - if err := jsonWriter.Write(obj); err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) + objBytes, err := writer.GetSerializedContent() + if err != nil { + return nil, err } - } - return nil + objString := "{" + string(objBytes) + "}" + + return []byte(objString), nil + }) } diff --git a/plugins/cognito/go.mod b/plugins/cognito/go.mod index ea3cfad8..334dd950 100644 --- a/plugins/cognito/go.mod +++ b/plugins/cognito/go.mod @@ -7,9 +7,9 @@ toolchain go1.24.1 replace github.com/aserto-dev/ds-load/sdk => ../../sdk require ( - github.com/alecthomas/kong v1.8.1 - github.com/aserto-dev/ds-load/sdk v0.0.0-20241206112725-5d200d771446 - github.com/aws/aws-sdk-go v1.55.5 + github.com/alecthomas/kong v1.10.0 + github.com/aserto-dev/ds-load/sdk v0.0.0-20250408143332-e8965667fcc0 + github.com/aws/aws-sdk-go v1.55.6 github.com/pkg/errors v0.9.1 ) @@ -18,8 +18,8 @@ require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.3.1 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect - github.com/aserto-dev/go-directory v0.33.7 // indirect - github.com/aserto-dev/logger v0.0.7 // indirect + github.com/aserto-dev/go-directory v0.33.10 // indirect + github.com/aserto-dev/logger v0.0.9 // indirect github.com/dongri/phonenumber v0.1.12 // indirect github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect @@ -30,16 +30,16 @@ require ( github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect - github.com/rs/zerolog v1.33.0 // indirect + github.com/rs/zerolog v1.34.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/spf13/cast v1.7.1 // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/net v0.37.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/grpc v1.71.0 // indirect - google.golang.org/protobuf v1.36.5 // indirect + golang.org/x/crypto v0.37.0 // indirect + golang.org/x/net v0.39.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/grpc v1.71.1 // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/plugins/cognito/go.sum b/plugins/cognito/go.sum index 0ae5bdaa..c1b4f99a 100644 --- a/plugins/cognito/go.sum +++ b/plugins/cognito/go.sum @@ -10,14 +10,22 @@ github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8v github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/kong v1.8.1 h1:6aamvWBE/REnR/BCq10EcozmcpUPc5aGI1lPAWdB0EE= github.com/alecthomas/kong v1.8.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= +github.com/alecthomas/kong v1.10.0 h1:8K4rGDpT7Iu+jEXCIJUeKqvpwZHbsFRoebLbnzlmrpw= +github.com/alecthomas/kong v1.10.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/aserto-dev/go-directory v0.33.7 h1:jldr2cGQp5EYM4l3IKSNyuK3Rr30taQ7MejbIHt+rGQ= github.com/aserto-dev/go-directory v0.33.7/go.mod h1:mY53j91JUnGRk9lsfw3yxgQXO41SCnt2bSP/2PamxCo= +github.com/aserto-dev/go-directory v0.33.10 h1:PLevCAWc9QeLZZv5Wc+yGk4psSd3507y1+9Fps+CzdI= +github.com/aserto-dev/go-directory v0.33.10/go.mod h1:CYRXxtDtf4zSwYYBBkGqW3b7HWJWvoIEBWgah9SGMAM= github.com/aserto-dev/logger v0.0.7 h1:ORvXxZDMNIcN/E3SYHj8fxmNZnOD7Gf87pOLB2XQavw= github.com/aserto-dev/logger v0.0.7/go.mod h1:66ff7ALo68NT1HcCg5zytOnGh6I5R0HeDpN85cwHcD0= +github.com/aserto-dev/logger v0.0.9 h1:QH11l8937Sw+GAe2yvgpoLg70fqQvPrEufkXAmDUk0g= +github.com/aserto-dev/logger v0.0.9/go.mod h1:mMXq/bhdIKoOVsIZ2zJOqgjcc/jR2x14FhU0St/8AVQ= github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= +github.com/aws/aws-sdk-go v1.55.6 h1:cSg4pvZ3m8dgYcgqB97MrcdjUmZ1BeMYKUxMMB89IPk= +github.com/aws/aws-sdk-go v1.55.6/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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= @@ -70,8 +78,11 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= @@ -93,23 +104,39 @@ go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a h1:OQ7sHVzkx6L57dQpzUS4ckfWJ51KDH74XHTDe23xWAs= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a/go.mod h1:2R6XrVC8Oc08GlNh8ujEpc7HkLiEZ16QeY7FxIs20ac= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a h1:GIqLhp/cYUkuGuiT+vJk8vhOP86L4+SP5j8yXgeVpvI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= +google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= +google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/plugins/cognito/pkg/app/constants.go b/plugins/cognito/pkg/app/constants.go index d9e23434..affaa4a5 100644 --- a/plugins/cognito/pkg/app/constants.go +++ b/plugins/cognito/pkg/app/constants.go @@ -1,4 +1,6 @@ package app -const AppName = "ds-load-cognito" -const AppDescription = "Cognito directory loader" +const ( + AppName = "ds-load-cognito" + AppDescription = "Cognito directory loader" +) diff --git a/plugins/cognito/pkg/app/fetch.go b/plugins/cognito/pkg/app/fetch.go index 974fa013..69bf19fd 100644 --- a/plugins/cognito/pkg/app/fetch.go +++ b/plugins/cognito/pkg/app/fetch.go @@ -5,6 +5,7 @@ import ( "github.com/aserto-dev/ds-load/plugins/cognito/pkg/cognitoclient" "github.com/aserto-dev/ds-load/plugins/cognito/pkg/fetch" + "github.com/aserto-dev/ds-load/sdk/common" "github.com/aserto-dev/ds-load/sdk/common/cc" ) @@ -29,5 +30,5 @@ func (cmd *FetchCmd) Run(ctx *cc.CommonCtx) error { fetcher = fetcher.WithGroups(cmd.Groups) - return fetcher.Fetch(ctx.Context, os.Stdout, os.Stderr) + return fetcher.Fetch(ctx.Context, os.Stdout, common.NewErrorWriter(os.Stderr)) } diff --git a/plugins/cognito/pkg/cognitoclient/cognito.go b/plugins/cognito/pkg/cognitoclient/cognito.go index 30507001..6cca5833 100644 --- a/plugins/cognito/pkg/cognitoclient/cognito.go +++ b/plugins/cognito/pkg/cognitoclient/cognito.go @@ -15,6 +15,8 @@ type CognitoClient struct { userPoolID string } +const maximumNumberOfUsers = 60 + func NewCognitoClient(accessKey, secretKey, userPoolID, region string) (*CognitoClient, error) { c := &CognitoClient{} @@ -45,7 +47,7 @@ func (c *CognitoClient) ListUsers(ctx context.Context) ([]*cognitoidentityprovid listUsersInput := &cognitoidentityprovider.ListUsersInput{ UserPoolId: aws.String(c.userPoolID), PaginationToken: paginationToken, - Limit: aws.Int64(60), + Limit: aws.Int64(maximumNumberOfUsers), } listUsersOutput, err := c.cognitoClient.ListUsersWithContext(ctx, listUsersInput) diff --git a/plugins/cognito/pkg/fetch/fetch.go b/plugins/cognito/pkg/fetch/fetch.go index 95e88eb9..74782946 100644 --- a/plugins/cognito/pkg/fetch/fetch.go +++ b/plugins/cognito/pkg/fetch/fetch.go @@ -4,10 +4,13 @@ import ( "context" "encoding/json" "io" + "iter" "github.com/aserto-dev/ds-load/plugins/cognito/pkg/cognitoclient" "github.com/aserto-dev/ds-load/sdk/common" "github.com/aserto-dev/ds-load/sdk/common/js" + "github.com/aserto-dev/ds-load/sdk/fetcher" + "github.com/aws/aws-sdk-go/service/cognitoidentityprovider" ) type Fetcher struct { @@ -26,38 +29,21 @@ func (f *Fetcher) WithGroups(groups bool) *Fetcher { return f } -func (f *Fetcher) Fetch(ctx context.Context, outputWriter, errorWriter io.Writer) error { +func (f *Fetcher) Fetch(ctx context.Context, outputWriter io.Writer, errorWriter common.ErrorWriter) error { writer := js.NewJSONArrayWriter(outputWriter) defer writer.Close() if f.groups { - groups, err := f.cognitoClient.ListGroups() - if err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } - - for _, group := range groups { - groupBytes, err := json.Marshal(group) - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - return err - } - - var obj map[string]interface{} - if err := json.Unmarshal(groupBytes, &obj); err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } + for obj, err := range f.fetchGroups() { + errorWriter.Error(err, common.WithExitCode) - if err := writer.Write(obj); err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } + err := writer.Write(obj) + errorWriter.Error(err) } } users, err := f.cognitoClient.ListUsers(ctx) - if err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } + errorWriter.Error(err, common.WithExitCode) for _, user := range users { attributes := make(map[string]string) @@ -67,42 +53,50 @@ func (f *Fetcher) Fetch(ctx context.Context, outputWriter, errorWriter io.Writer userBytes, err := json.Marshal(user) if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) + errorWriter.Error(err, common.WithExitCode) return err } - var obj map[string]interface{} - if err := json.Unmarshal(userBytes, &obj); err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } + var obj map[string]any + err = json.Unmarshal(userBytes, &obj) + errorWriter.Error(err) obj["Attributes"] = attributes if f.groups { groups, err := f.cognitoClient.GetGroupsForUser(*user.Username) if err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) + errorWriter.Error(err) continue } groupBytes, err := json.Marshal(groups.Groups) if err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) + errorWriter.Error(err) return err } var grps []map[string]string - if err := json.Unmarshal(groupBytes, &grps); err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } + err = json.Unmarshal(groupBytes, &grps) + errorWriter.Error(err) obj["Groups"] = grps } - if err := writer.Write(obj); err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } + err = writer.Write(obj) + errorWriter.Error(err) } return nil } + +func (f *Fetcher) fetchGroups() iter.Seq2[map[string]any, error] { + groups, err := f.cognitoClient.ListGroups() + if err != nil { + return fetcher.YieldError(err) + } + + return fetcher.YieldMap(groups, func(group *cognitoidentityprovider.GroupType) ([]byte, error) { + return json.Marshal(group) + }) +} diff --git a/plugins/fusionauth/go.mod b/plugins/fusionauth/go.mod index 2f6263b7..26eabb2d 100644 --- a/plugins/fusionauth/go.mod +++ b/plugins/fusionauth/go.mod @@ -7,20 +7,20 @@ toolchain go1.24.1 replace github.com/aserto-dev/ds-load/sdk => ../../sdk require ( - github.com/FusionAuth/go-client v0.0.0-20241126020005-1254a936741f - github.com/alecthomas/kong v1.8.1 + github.com/FusionAuth/go-client v0.0.0-20250407195615-3d43b821c30d + github.com/alecthomas/kong v1.10.0 github.com/pkg/errors v0.9.1 ) -require github.com/aserto-dev/ds-load/sdk v0.0.0-20241206112725-5d200d771446 +require github.com/aserto-dev/ds-load/sdk v0.0.0-20250408143332-e8965667fcc0 require ( dario.cat/mergo v1.0.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.3.1 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect - github.com/aserto-dev/go-directory v0.33.7 // indirect - github.com/aserto-dev/logger v0.0.7 // indirect + github.com/aserto-dev/go-directory v0.33.10 // indirect + github.com/aserto-dev/logger v0.0.9 // indirect github.com/dongri/phonenumber v0.1.12 // indirect github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect @@ -30,16 +30,16 @@ require ( github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect - github.com/rs/zerolog v1.33.0 // indirect + github.com/rs/zerolog v1.34.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/spf13/cast v1.7.1 // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/net v0.37.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/grpc v1.71.0 // indirect - google.golang.org/protobuf v1.36.5 // indirect + golang.org/x/crypto v0.37.0 // indirect + golang.org/x/net v0.39.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/grpc v1.71.1 // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/plugins/fusionauth/go.sum b/plugins/fusionauth/go.sum index 85b8bd5c..5672c752 100644 --- a/plugins/fusionauth/go.sum +++ b/plugins/fusionauth/go.sum @@ -2,6 +2,8 @@ dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/FusionAuth/go-client v0.0.0-20241126020005-1254a936741f h1:RmJ+JwVXvvG2nFNikMgF+bfeJP0VL2GlKEikMNuJqD0= github.com/FusionAuth/go-client v0.0.0-20241126020005-1254a936741f/go.mod h1:SyRrXMJAzMVQLiJjKfQUR59dRI3jPyZv+BXIZ//HwE4= +github.com/FusionAuth/go-client v0.0.0-20250407195615-3d43b821c30d h1:r9ReaBB+cX8wfoEuq2MzwO3TJYZayujN2Ezc3JawpFg= +github.com/FusionAuth/go-client v0.0.0-20250407195615-3d43b821c30d/go.mod h1:SyRrXMJAzMVQLiJjKfQUR59dRI3jPyZv+BXIZ//HwE4= github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= github.com/Masterminds/semver/v3 v3.3.1 h1:QtNSWtVZ3nBfk8mAOu/B6v7FMJ+NHTIgUPi7rj+4nv4= @@ -12,12 +14,18 @@ github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8v github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/kong v1.8.1 h1:6aamvWBE/REnR/BCq10EcozmcpUPc5aGI1lPAWdB0EE= github.com/alecthomas/kong v1.8.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= +github.com/alecthomas/kong v1.10.0 h1:8K4rGDpT7Iu+jEXCIJUeKqvpwZHbsFRoebLbnzlmrpw= +github.com/alecthomas/kong v1.10.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/aserto-dev/go-directory v0.33.7 h1:jldr2cGQp5EYM4l3IKSNyuK3Rr30taQ7MejbIHt+rGQ= github.com/aserto-dev/go-directory v0.33.7/go.mod h1:mY53j91JUnGRk9lsfw3yxgQXO41SCnt2bSP/2PamxCo= +github.com/aserto-dev/go-directory v0.33.10 h1:PLevCAWc9QeLZZv5Wc+yGk4psSd3507y1+9Fps+CzdI= +github.com/aserto-dev/go-directory v0.33.10/go.mod h1:CYRXxtDtf4zSwYYBBkGqW3b7HWJWvoIEBWgah9SGMAM= github.com/aserto-dev/logger v0.0.7 h1:ORvXxZDMNIcN/E3SYHj8fxmNZnOD7Gf87pOLB2XQavw= github.com/aserto-dev/logger v0.0.7/go.mod h1:66ff7ALo68NT1HcCg5zytOnGh6I5R0HeDpN85cwHcD0= +github.com/aserto-dev/logger v0.0.9 h1:QH11l8937Sw+GAe2yvgpoLg70fqQvPrEufkXAmDUk0g= +github.com/aserto-dev/logger v0.0.9/go.mod h1:mMXq/bhdIKoOVsIZ2zJOqgjcc/jR2x14FhU0St/8AVQ= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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= @@ -66,8 +74,11 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= @@ -90,23 +101,39 @@ go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a h1:OQ7sHVzkx6L57dQpzUS4ckfWJ51KDH74XHTDe23xWAs= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a/go.mod h1:2R6XrVC8Oc08GlNh8ujEpc7HkLiEZ16QeY7FxIs20ac= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a h1:GIqLhp/cYUkuGuiT+vJk8vhOP86L4+SP5j8yXgeVpvI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= +google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= +google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/plugins/fusionauth/pkg/app/constants.go b/plugins/fusionauth/pkg/app/constants.go index 8c683caf..0859372d 100644 --- a/plugins/fusionauth/pkg/app/constants.go +++ b/plugins/fusionauth/pkg/app/constants.go @@ -1,4 +1,6 @@ package app -const AppName = "ds-load-fusionauth" -const AppDescription = "FusionAuth directory loader" +const ( + AppName = "ds-load-fusionauth" + AppDescription = "FusionAuth directory loader" +) diff --git a/plugins/fusionauth/pkg/app/fetch.go b/plugins/fusionauth/pkg/app/fetch.go index baf4b456..6ca0ffab 100644 --- a/plugins/fusionauth/pkg/app/fetch.go +++ b/plugins/fusionauth/pkg/app/fetch.go @@ -5,6 +5,7 @@ import ( "github.com/aserto-dev/ds-load/plugins/fusionauth/pkg/fetch" "github.com/aserto-dev/ds-load/plugins/fusionauth/pkg/fusionauthclient" + "github.com/aserto-dev/ds-load/sdk/common" "github.com/aserto-dev/ds-load/sdk/common/cc" ) @@ -27,5 +28,5 @@ func (cmd *FetchCmd) Run(ctx *cc.CommonCtx) error { fetcher = fetcher.WithGroups(cmd.Groups).WithHost(cmd.HostURL) - return fetcher.Fetch(ctx.Context, os.Stdout, os.Stderr) + return fetcher.Fetch(ctx.Context, os.Stdout, common.NewErrorWriter(os.Stderr)) } diff --git a/plugins/fusionauth/pkg/fetch/fetch.go b/plugins/fusionauth/pkg/fetch/fetch.go index a6477945..d9355f5f 100644 --- a/plugins/fusionauth/pkg/fetch/fetch.go +++ b/plugins/fusionauth/pkg/fetch/fetch.go @@ -7,6 +7,7 @@ import ( "io" "github.com/aserto-dev/ds-load/plugins/fusionauth/pkg/fusionauthclient" + "github.com/aserto-dev/ds-load/sdk/common" "github.com/aserto-dev/ds-load/sdk/common/js" ) @@ -32,27 +33,25 @@ func (f *Fetcher) WithHost(host string) *Fetcher { return f } -func (f *Fetcher) Fetch(ctx context.Context, outputWriter, errorWriter io.Writer) error { +func (f *Fetcher) Fetch(ctx context.Context, outputWriter io.Writer, errorWriter common.ErrorWriter) error { writer := js.NewJSONArrayWriter(outputWriter) defer writer.Close() users, err := f.fusionauthClient.ListUsers(ctx) - if err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } + errorWriter.Error(err) for i := range users { user := &users[i] userBytes, err := json.Marshal(user) if err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) + errorWriter.Error(err) return err } - var obj map[string]interface{} + var obj map[string]any if err := json.Unmarshal(userBytes, &obj); err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) + errorWriter.Error(err) return err } @@ -60,22 +59,18 @@ func (f *Fetcher) Fetch(ctx context.Context, outputWriter, errorWriter io.Writer obj["picture"] = fmt.Sprintf("%s%s", f.host, user.ImageUrl) } - if err := writer.Write(obj); err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } + err = writer.Write(obj) + errorWriter.Error(err) } if f.groups { groups, err := f.fusionauthClient.ListGroups(ctx) - if err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } + errorWriter.Error(err) for i := range groups { group := &groups[i] - if err := writer.Write(group); err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } + err := writer.Write(group) + errorWriter.Error(err) } } diff --git a/plugins/fusionauth/pkg/fusionauthclient/fusionauth.go b/plugins/fusionauth/pkg/fusionauthclient/fusionauth.go index 17bed314..79bc599f 100644 --- a/plugins/fusionauth/pkg/fusionauthclient/fusionauth.go +++ b/plugins/fusionauth/pkg/fusionauthclient/fusionauth.go @@ -15,11 +15,13 @@ type FusionAuthClient struct { host string } +const defaultTimeout = 10 * time.Second + func NewFusionAuthClient(host, apiKey string) (*FusionAuthClient, error) { c := &FusionAuthClient{} httpClient := &http.Client{ - Timeout: time.Second * 10, + Timeout: defaultTimeout, } baseURL, _ := url.Parse(host) diff --git a/plugins/google/go.mod b/plugins/google/go.mod index 642e9b19..7162b38b 100644 --- a/plugins/google/go.mod +++ b/plugins/google/go.mod @@ -7,31 +7,31 @@ toolchain go1.24.1 replace github.com/aserto-dev/ds-load/sdk => ../../sdk require ( - github.com/alecthomas/kong v1.8.1 - github.com/aserto-dev/ds-load/sdk v0.0.0-20241206112725-5d200d771446 + github.com/alecthomas/kong v1.10.0 + github.com/aserto-dev/ds-load/sdk v0.0.0-20250408143332-e8965667fcc0 github.com/pkg/errors v0.9.1 - golang.org/x/oauth2 v0.27.0 - google.golang.org/api v0.213.0 + golang.org/x/oauth2 v0.29.0 + google.golang.org/api v0.228.0 ) require ( - cloud.google.com/go/auth v0.13.0 // indirect - cloud.google.com/go/auth/oauth2adapt v0.2.6 // indirect + cloud.google.com/go/auth v0.15.0 // indirect + cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect cloud.google.com/go/compute/metadata v0.6.0 // indirect dario.cat/mergo v1.0.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.3.1 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect - github.com/aserto-dev/go-directory v0.33.7 // indirect - github.com/aserto-dev/logger v0.0.7 // indirect + github.com/aserto-dev/go-directory v0.33.10 // indirect + github.com/aserto-dev/logger v0.0.9 // indirect github.com/dongri/phonenumber v0.1.12 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/google/s2a-go v0.1.8 // indirect + github.com/google/s2a-go v0.1.9 // indirect github.com/google/uuid v1.6.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect - github.com/googleapis/gax-go/v2 v2.14.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect + github.com/googleapis/gax-go/v2 v2.14.1 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect github.com/huandu/xstrings v1.5.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect @@ -39,21 +39,21 @@ require ( github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect - github.com/rs/zerolog v1.33.0 // indirect + github.com/rs/zerolog v1.34.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/spf13/cast v1.7.1 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0 // indirect - go.opentelemetry.io/otel v1.34.0 // indirect - go.opentelemetry.io/otel/metric v1.34.0 // indirect - go.opentelemetry.io/otel/trace v1.34.0 // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/net v0.37.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/grpc v1.71.0 // indirect - google.golang.org/protobuf v1.36.5 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect + go.opentelemetry.io/otel v1.35.0 // indirect + go.opentelemetry.io/otel/metric v1.35.0 // indirect + go.opentelemetry.io/otel/trace v1.35.0 // indirect + golang.org/x/crypto v0.37.0 // indirect + golang.org/x/net v0.39.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/grpc v1.71.1 // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/plugins/google/go.sum b/plugins/google/go.sum index 8806d0e6..f42fcd94 100644 --- a/plugins/google/go.sum +++ b/plugins/google/go.sum @@ -1,7 +1,11 @@ cloud.google.com/go/auth v0.13.0 h1:8Fu8TZy167JkW8Tj3q7dIkr2v4cndv41ouecJx0PAHs= cloud.google.com/go/auth v0.13.0/go.mod h1:COOjD9gwfKNKz+IIduatIhYJQIc0mG3H102r/EMxX6Q= +cloud.google.com/go/auth v0.15.0 h1:Ly0u4aA5vG/fsSsxu98qCQBemXtAtJf+95z9HK+cxps= +cloud.google.com/go/auth v0.15.0/go.mod h1:WJDGqZ1o9E9wKIL+IwStfyn/+s59zl4Bi+1KQNVXLZ8= cloud.google.com/go/auth/oauth2adapt v0.2.6 h1:V6a6XDu2lTwPZWOawrAa9HUK+DB2zfJyTuciBG5hFkU= cloud.google.com/go/auth/oauth2adapt v0.2.6/go.mod h1:AlmsELtlEBnaNTL7jCj8VQFLy6mbZv0s4Q7NGBeQ5E8= +cloud.google.com/go/auth/oauth2adapt v0.2.8 h1:keo8NaayQZ6wimpNSmW5OPc283g65QNIiLpZnkHRbnc= +cloud.google.com/go/auth/oauth2adapt v0.2.8/go.mod h1:XQ9y31RkqZCcwJWNSx2Xvric3RrU88hAYYbjDWYDL+c= cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= @@ -16,12 +20,18 @@ github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8v github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/kong v1.8.1 h1:6aamvWBE/REnR/BCq10EcozmcpUPc5aGI1lPAWdB0EE= github.com/alecthomas/kong v1.8.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= +github.com/alecthomas/kong v1.10.0 h1:8K4rGDpT7Iu+jEXCIJUeKqvpwZHbsFRoebLbnzlmrpw= +github.com/alecthomas/kong v1.10.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/aserto-dev/go-directory v0.33.7 h1:jldr2cGQp5EYM4l3IKSNyuK3Rr30taQ7MejbIHt+rGQ= github.com/aserto-dev/go-directory v0.33.7/go.mod h1:mY53j91JUnGRk9lsfw3yxgQXO41SCnt2bSP/2PamxCo= +github.com/aserto-dev/go-directory v0.33.10 h1:PLevCAWc9QeLZZv5Wc+yGk4psSd3507y1+9Fps+CzdI= +github.com/aserto-dev/go-directory v0.33.10/go.mod h1:CYRXxtDtf4zSwYYBBkGqW3b7HWJWvoIEBWgah9SGMAM= github.com/aserto-dev/logger v0.0.7 h1:ORvXxZDMNIcN/E3SYHj8fxmNZnOD7Gf87pOLB2XQavw= github.com/aserto-dev/logger v0.0.7/go.mod h1:66ff7ALo68NT1HcCg5zytOnGh6I5R0HeDpN85cwHcD0= +github.com/aserto-dev/logger v0.0.9 h1:QH11l8937Sw+GAe2yvgpoLg70fqQvPrEufkXAmDUk0g= +github.com/aserto-dev/logger v0.0.9/go.mod h1:mMXq/bhdIKoOVsIZ2zJOqgjcc/jR2x14FhU0St/8AVQ= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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= @@ -43,12 +53,18 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM= github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA= +github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0= +github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw= github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= +github.com/googleapis/enterprise-certificate-proxy v0.3.6 h1:GW/XbdyBFQ8Qe+YAmFU9uHLo7OnF5tL52HFAgMmyrf4= +github.com/googleapis/enterprise-certificate-proxy v0.3.6/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA= github.com/googleapis/gax-go/v2 v2.14.0 h1:f+jMrjBPl+DL9nI4IQzLUxMq7XrAqFYB7hBPqMNIe8o= github.com/googleapis/gax-go/v2 v2.14.0/go.mod h1:lhBCnjdLrWRaPvLWhmc8IS24m9mr07qSYnHncrgo+zk= +github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q= +github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA= github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= @@ -78,8 +94,11 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= @@ -90,22 +109,36 @@ go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJyS go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0 h1:DheMAlT6POBP+gh8RUH19EOTnQIor5QE0uSRPtzCpSw= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0/go.mod h1:wZcGmeVO9nzP67aYSLDqXNWK87EZWhi7JWj1v7ZXf94= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk= go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98= +golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -113,18 +146,32 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= google.golang.org/api v0.213.0 h1:KmF6KaDyFqB417T68tMPbVmmwtIXs2VB60OJKIHB0xQ= google.golang.org/api v0.213.0/go.mod h1:V0T5ZhNUUNpYAlL306gFZPFt5F5D/IeyLoktduYYnvQ= +google.golang.org/api v0.228.0 h1:X2DJ/uoWGnY5obVjewbp8icSL5U4FzuCfy9OjbLSnLs= +google.golang.org/api v0.228.0/go.mod h1:wNvRS1Pbe8r4+IfBIniV8fwCpGwTrYa+kMUDiC5z5a4= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a h1:OQ7sHVzkx6L57dQpzUS4ckfWJ51KDH74XHTDe23xWAs= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a/go.mod h1:2R6XrVC8Oc08GlNh8ujEpc7HkLiEZ16QeY7FxIs20ac= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a h1:GIqLhp/cYUkuGuiT+vJk8vhOP86L4+SP5j8yXgeVpvI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= +google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= +google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/plugins/google/pkg/app/constants.go b/plugins/google/pkg/app/constants.go index 0d2991c4..ae2c663c 100644 --- a/plugins/google/pkg/app/constants.go +++ b/plugins/google/pkg/app/constants.go @@ -1,4 +1,6 @@ package app -const AppName = "ds-load-google" -const AppDescription = "Google Workspace directory loader" +const ( + AppName = "ds-load-google" + AppDescription = "Google Workspace directory loader" +) diff --git a/plugins/google/pkg/app/fetch.go b/plugins/google/pkg/app/fetch.go index ac443052..7123e346 100644 --- a/plugins/google/pkg/app/fetch.go +++ b/plugins/google/pkg/app/fetch.go @@ -5,6 +5,7 @@ import ( "github.com/aserto-dev/ds-load/plugins/google/pkg/fetch" "github.com/aserto-dev/ds-load/plugins/google/pkg/googleclient" + "github.com/aserto-dev/ds-load/sdk/common" "github.com/aserto-dev/ds-load/sdk/common/cc" ) @@ -29,5 +30,5 @@ func (cmd *FetchCmd) Run(ctx *cc.CommonCtx) error { fetcher = fetcher.WithGroups(cmd.Groups) - return fetcher.Fetch(ctx.Context, os.Stdout, os.Stderr) + return fetcher.Fetch(ctx.Context, os.Stdout, common.NewErrorWriter(os.Stderr)) } diff --git a/plugins/google/pkg/fetch/fetch.go b/plugins/google/pkg/fetch/fetch.go index e289082b..ea83a24d 100644 --- a/plugins/google/pkg/fetch/fetch.go +++ b/plugins/google/pkg/fetch/fetch.go @@ -4,10 +4,14 @@ import ( "context" "encoding/json" "io" + "iter" "github.com/aserto-dev/ds-load/plugins/google/pkg/googleclient" "github.com/aserto-dev/ds-load/sdk/common" "github.com/aserto-dev/ds-load/sdk/common/js" + "github.com/aserto-dev/ds-load/sdk/fetcher" + + admin "google.golang.org/api/admin/directory/v1" ) type Fetcher struct { @@ -26,76 +30,98 @@ func (f *Fetcher) WithGroups(groups bool) *Fetcher { return f } -func (f *Fetcher) Fetch(ctx context.Context, outputWriter, errorWriter io.Writer) error { +func (f *Fetcher) Fetch(ctx context.Context, outputWriter io.Writer, errorWriter common.ErrorWriter) error { writer := js.NewJSONArrayWriter(outputWriter) defer writer.Close() - users, err := f.gClient.ListUsers() - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - return err - } - - for _, user := range users { - userBytes, err := json.Marshal(user) + for user, err := range f.fetchUsers() { if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) + errorWriter.Error(err, common.WithExitCode) continue } - var obj map[string]interface{} - if err := json.Unmarshal(userBytes, &obj); err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - continue - } - - if err := writer.Write(obj); err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } + err := writer.Write(user) + errorWriter.Error(err) } if f.Groups { - groups, err := f.gClient.ListGroups() - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - return err + for group, err := range f.fetchGroups() { + if err != nil { + errorWriter.Error(err, common.WithExitCode) + continue + } + + err := writer.Write(group) + errorWriter.Error(err) } + } + + return nil +} +func (f *Fetcher) fetchUsers() iter.Seq2[map[string]any, error] { + users, err := f.gClient.ListUsers() + if err != nil { + return fetcher.YieldError(err) + } + + return fetcher.YieldMap(users, func(user *admin.User) ([]byte, error) { + return json.Marshal(user) + }) +} + +func (f *Fetcher) fetchGroups() iter.Seq2[map[string]any, error] { + groups, err := f.gClient.ListGroups() + if err != nil { + return fetcher.YieldError(err) + } + + return func(yield func(map[string]any, error) bool) { for _, group := range groups { groupBytes, err := json.Marshal(group) if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - continue + if !yield(nil, err) { + return + } } - var obj map[string]interface{} + var obj map[string]any if err := json.Unmarshal(groupBytes, &obj); err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - continue + if !yield(nil, err) { + return + } } - usersInGroup, err := f.gClient.GetUsersInGroup(group.Id) + users, err := f.fetchUsersInGroup(group.Id) if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - } else { - usersInGroupBytes, err := json.Marshal(usersInGroup) - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - } else { - var users []map[string]interface{} - if err := json.Unmarshal(usersInGroupBytes, &users); err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - } - - obj["users"] = users + if !yield(nil, err) { + return } } - if err := writer.Write(obj); err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) + obj["users"] = users + if !(yield(obj, nil)) { + return } } } +} - return nil +func (f *Fetcher) fetchUsersInGroup(groupId string) ([]map[string]any, error) { + usersInGroup, err := f.gClient.GetUsersInGroup(groupId) + if err != nil { + return nil, err + } + + usersInGroupBytes, err := json.Marshal(usersInGroup) + if err != nil { + return nil, err + } + + var users []map[string]any + if err := json.Unmarshal(usersInGroupBytes, &users); err != nil { + return nil, err + } + + return users, nil } diff --git a/plugins/google/pkg/googleclient/google.go b/plugins/google/pkg/googleclient/google.go index ee1e032f..1b713312 100644 --- a/plugins/google/pkg/googleclient/google.go +++ b/plugins/google/pkg/googleclient/google.go @@ -19,6 +19,10 @@ type GoogleClient struct { customer string } +const ( + defaultReaderTimeout = 5 * time.Second +) + func GetRefreshToken(ctx context.Context, clientID, clientSecret string, port int) (string, error) { redirectURL := fmt.Sprintf("http://localhost:%d", port) config := &oauth2.Config{ @@ -41,7 +45,7 @@ func GetRefreshToken(ctx context.Context, clientID, clientSecret string, port in fmt.Println("Waiting for authorization code...") // Create an HTTP server for handling the OAuth 2.0 callback - server := &http.Server{Addr: fmt.Sprintf(":%d", port), ReadHeaderTimeout: 5 * time.Second} + server := &http.Server{Addr: fmt.Sprintf(":%d", port), ReadHeaderTimeout: defaultReaderTimeout} http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { code := r.URL.Query().Get("code") diff --git a/plugins/jumpcloud/go.mod b/plugins/jumpcloud/go.mod index 154c5a1a..d297d616 100644 --- a/plugins/jumpcloud/go.mod +++ b/plugins/jumpcloud/go.mod @@ -7,12 +7,12 @@ toolchain go1.24.1 replace github.com/aserto-dev/ds-load/sdk => ../../sdk require ( - github.com/alecthomas/kong v1.8.1 - github.com/aserto-dev/ds-load/sdk v0.0.0-20241206112725-5d200d771446 + github.com/alecthomas/kong v1.10.0 + github.com/aserto-dev/ds-load/sdk v0.0.0-20250408143332-e8965667fcc0 github.com/pkg/errors v0.9.1 github.com/samber/lo v1.49.1 github.com/stretchr/testify v1.10.0 - google.golang.org/grpc v1.71.0 + google.golang.org/grpc v1.71.1 ) require ( @@ -20,8 +20,8 @@ require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.3.1 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect - github.com/aserto-dev/go-directory v0.33.7 // indirect - github.com/aserto-dev/logger v0.0.7 // indirect + github.com/aserto-dev/go-directory v0.33.10 // indirect + github.com/aserto-dev/logger v0.0.9 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dongri/phonenumber v0.1.12 // indirect github.com/google/uuid v1.6.0 // indirect @@ -33,15 +33,15 @@ require ( github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/rs/zerolog v1.33.0 // indirect + github.com/rs/zerolog v1.34.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/spf13/cast v1.7.1 // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/net v0.37.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/protobuf v1.36.5 // indirect + golang.org/x/crypto v0.37.0 // indirect + golang.org/x/net v0.39.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/plugins/jumpcloud/go.sum b/plugins/jumpcloud/go.sum index c8bc5a31..8bb534e6 100644 --- a/plugins/jumpcloud/go.sum +++ b/plugins/jumpcloud/go.sum @@ -10,12 +10,18 @@ github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8v github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/kong v1.8.1 h1:6aamvWBE/REnR/BCq10EcozmcpUPc5aGI1lPAWdB0EE= github.com/alecthomas/kong v1.8.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= +github.com/alecthomas/kong v1.10.0 h1:8K4rGDpT7Iu+jEXCIJUeKqvpwZHbsFRoebLbnzlmrpw= +github.com/alecthomas/kong v1.10.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/aserto-dev/go-directory v0.33.7 h1:jldr2cGQp5EYM4l3IKSNyuK3Rr30taQ7MejbIHt+rGQ= github.com/aserto-dev/go-directory v0.33.7/go.mod h1:mY53j91JUnGRk9lsfw3yxgQXO41SCnt2bSP/2PamxCo= +github.com/aserto-dev/go-directory v0.33.10 h1:PLevCAWc9QeLZZv5Wc+yGk4psSd3507y1+9Fps+CzdI= +github.com/aserto-dev/go-directory v0.33.10/go.mod h1:CYRXxtDtf4zSwYYBBkGqW3b7HWJWvoIEBWgah9SGMAM= github.com/aserto-dev/logger v0.0.7 h1:ORvXxZDMNIcN/E3SYHj8fxmNZnOD7Gf87pOLB2XQavw= github.com/aserto-dev/logger v0.0.7/go.mod h1:66ff7ALo68NT1HcCg5zytOnGh6I5R0HeDpN85cwHcD0= +github.com/aserto-dev/logger v0.0.9 h1:QH11l8937Sw+GAe2yvgpoLg70fqQvPrEufkXAmDUk0g= +github.com/aserto-dev/logger v0.0.9/go.mod h1:mMXq/bhdIKoOVsIZ2zJOqgjcc/jR2x14FhU0St/8AVQ= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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= @@ -63,9 +69,13 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/samber/lo v1.49.1 h1:4BIFyVfuQSEpluc7Fua+j1NolZHiEHEpaSEKdsH0tew= +github.com/samber/lo v1.49.1/go.mod h1:dO6KHFzUKXgP8LDhU0oI8d2hekjXnGOu0DB8Jecxd6o= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= @@ -80,22 +90,38 @@ go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a h1:OQ7sHVzkx6L57dQpzUS4ckfWJ51KDH74XHTDe23xWAs= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a/go.mod h1:2R6XrVC8Oc08GlNh8ujEpc7HkLiEZ16QeY7FxIs20ac= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a h1:GIqLhp/cYUkuGuiT+vJk8vhOP86L4+SP5j8yXgeVpvI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= +google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= +google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/plugins/jumpcloud/pkg/app/fetch.go b/plugins/jumpcloud/pkg/app/fetch.go index e975fed6..63ed9bcf 100644 --- a/plugins/jumpcloud/pkg/app/fetch.go +++ b/plugins/jumpcloud/pkg/app/fetch.go @@ -5,6 +5,7 @@ import ( "github.com/aserto-dev/ds-load/plugins/jumpcloud/pkg/fetch" "github.com/aserto-dev/ds-load/plugins/jumpcloud/pkg/jc" + "github.com/aserto-dev/ds-load/sdk/common" "github.com/aserto-dev/ds-load/sdk/common/cc" ) @@ -26,5 +27,5 @@ func (cmd *FetchCmd) Run(ctx *cc.CommonCtx) error { fetcher = fetcher.WithGroups(cmd.Groups) - return fetcher.Fetch(ctx.Context, os.Stdout, os.Stderr) + return fetcher.Fetch(ctx.Context, os.Stdout, common.NewErrorWriter(os.Stderr)) } diff --git a/plugins/jumpcloud/pkg/fetch/fetch.go b/plugins/jumpcloud/pkg/fetch/fetch.go index 76ca7a35..7cbedc27 100644 --- a/plugins/jumpcloud/pkg/fetch/fetch.go +++ b/plugins/jumpcloud/pkg/fetch/fetch.go @@ -26,13 +26,13 @@ func (f *Fetcher) WithGroups(groups bool) *Fetcher { return f } -func (f *Fetcher) Fetch(ctx context.Context, outputWriter, errorWriter io.Writer) error { +func (f *Fetcher) Fetch(ctx context.Context, outputWriter io.Writer, errorWriter common.ErrorWriter) error { writer := js.NewJSONArrayWriter(outputWriter) defer writer.Close() users, err := f.jcc.ListUsers(ctx) if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) + errorWriter.Error(err) return err } @@ -41,65 +41,70 @@ func (f *Fetcher) Fetch(ctx context.Context, outputWriter, errorWriter io.Writer for _, user := range users { userBytes, err := json.Marshal(user) if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) + errorWriter.Error(err) continue } - var obj map[string]interface{} + var obj map[string]any if err := json.Unmarshal(userBytes, &obj); err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) + errorWriter.Error(err) continue } if err := writer.Write(obj); err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) + errorWriter.Error(err) } idLookup[user.ID] = &user.BaseUser } if f.Groups { - groups, err := f.jcc.ListGroups(ctx, jc.UserGroups) - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) + if err := f.fetchGroups(ctx, writer, errorWriter, idLookup); err != nil { return err } + } + + return nil +} + +func (f *Fetcher) fetchGroups(ctx context.Context, + writer *js.JSONArrayWriter, + errorWriter common.ErrorWriter, + idLookup map[string]*jc.BaseUser, +) error { + groups, err := f.jcc.ListGroups(ctx, jc.UserGroups) + if err != nil { + errorWriter.Error(err) + return err + } + + for _, group := range groups { + groupBytes, err := json.Marshal(group) + errorWriter.Error(err) + + var obj map[string]any + if err := json.Unmarshal(groupBytes, &obj); err != nil { + errorWriter.Error(err) + continue + } + + usersInGroup, err := f.jcc.ExpandUsersInGroup(ctx, group.ID, idLookup) + errorWriter.Error(err) - for _, group := range groups { - groupBytes, err := json.Marshal(group) - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - continue - } - - var obj map[string]interface{} - if err := json.Unmarshal(groupBytes, &obj); err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - continue - } - - usersInGroup, err := f.jcc.ExpandUsersInGroup(ctx, group.ID, idLookup) - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - } else { - usersInGroupBytes, err := json.Marshal(usersInGroup) - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - } else { - var users []map[string]interface{} - if err := json.Unmarshal(usersInGroupBytes, &users); err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - } - - obj["users"] = users - } - } - - if err := writer.Write(obj); err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } + usersInGroupBytes, err := json.Marshal(usersInGroup) + + errorWriter.Error(err) + + var users []map[string]any + if err := json.Unmarshal(usersInGroupBytes, &users); err != nil { + errorWriter.Error(err) } + + obj["users"] = users + + err = writer.Write(obj) + errorWriter.Error(err) } return nil diff --git a/plugins/jumpcloud/pkg/jc/jc.go b/plugins/jumpcloud/pkg/jc/jc.go index e760f609..e3a32ebc 100644 --- a/plugins/jumpcloud/pkg/jc/jc.go +++ b/plugins/jumpcloud/pkg/jc/jc.go @@ -17,9 +17,10 @@ import ( ) const ( - baseURL string = "https://console.jumpcloud.com/api" - apiKeyHeader string = "x-api-key" - batchSize int = 50 + baseURL string = "https://console.jumpcloud.com/api" + apiKeyHeader string = "x-api-key" + batchSize int = 50 + defaultConnectionTimeout = 30 * time.Second ) type JumpCloudClient struct { @@ -40,7 +41,7 @@ func NewJumpCloudClient(ctx context.Context, apiKey string) (*JumpCloudClient, e "Accept": "application/json", apiKeyHeader: apiKey, }, - timeout: 30 * time.Second, + timeout: defaultConnectionTimeout, } return c, nil @@ -63,7 +64,7 @@ func (c *JumpCloudClient) ListUsers(ctx context.Context) ([]*User, error) { users := struct { Results []*User `json:"results"` - TotalCount int `json:"totalCount"` + TotalCount int `json:"totalCount"` //nolint:tagliatelle // keep jc format }{} if err := makeHTTPRequest(ctx, url, http.MethodPost, c.headers, nil, nil, &users); err != nil { @@ -229,7 +230,14 @@ var ( ErrStatusNotOK = errors.New("status not OK") ) -func makeHTTPRequest[T any](ctx context.Context, reqURL, method string, headers map[string]string, queryParams url.Values, body io.Reader, resp T) error { +func makeHTTPRequest[T any]( + ctx context.Context, + reqURL, method string, + headers map[string]string, + queryParams url.Values, + body io.Reader, + resp T, +) error { client := http.Client{} u, err := url.Parse(reqURL) diff --git a/plugins/jumpcloud/pkg/jc/jc_test.go b/plugins/jumpcloud/pkg/jc/jc_test.go index 57e8711b..cff1a7e2 100644 --- a/plugins/jumpcloud/pkg/jc/jc_test.go +++ b/plugins/jumpcloud/pkg/jc/jc_test.go @@ -11,7 +11,7 @@ import ( "github.com/stretchr/testify/require" ) -const JcAPIKey string = "JC_API_KEY" // nolint: gosec // no hardcoded credentials. +const JcAPIKey string = "JC_API_KEY" //nolint:gosec // no hardcoded credentials. func TestMain(m *testing.M) { if os.Getenv(JcAPIKey) == "" { diff --git a/plugins/jumpcloud/pkg/jc/user.go b/plugins/jumpcloud/pkg/jc/user.go index e078052f..2b68e252 100644 --- a/plugins/jumpcloud/pkg/jc/user.go +++ b/plugins/jumpcloud/pkg/jc/user.go @@ -4,6 +4,7 @@ import "time" const TypeUser string = "user" +//nolint:tagliatelle // maintain json user formatting type BaseUser struct { IID string `json:"_id"` ID string `json:"id"` @@ -13,6 +14,7 @@ type BaseUser struct { Username string `json:"username"` } +//nolint:tagliatelle // maintain json user formatting type User struct { BaseUser SystemUsername string `json:"systemUsername"` diff --git a/plugins/ldap/go.mod b/plugins/ldap/go.mod index b014f2bb..4367d5a3 100644 --- a/plugins/ldap/go.mod +++ b/plugins/ldap/go.mod @@ -7,12 +7,12 @@ toolchain go1.24.1 replace github.com/aserto-dev/ds-load/sdk => ../../sdk require ( - github.com/alecthomas/kong v1.8.1 - github.com/aserto-dev/ds-load/sdk v0.0.0-20241206112725-5d200d771446 + github.com/alecthomas/kong v1.10.0 + github.com/aserto-dev/ds-load/sdk v0.0.0-20250408143332-e8965667fcc0 github.com/bwmarrin/go-objectsid v0.0.0-20191126144531-5fee401a2f37 - github.com/go-ldap/ldap/v3 v3.4.9 + github.com/go-ldap/ldap/v3 v3.4.10 github.com/google/uuid v1.6.0 - github.com/rs/zerolog v1.33.0 + github.com/rs/zerolog v1.34.0 ) require ( @@ -21,8 +21,8 @@ require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.3.1 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect - github.com/aserto-dev/go-directory v0.33.7 // indirect - github.com/aserto-dev/logger v0.0.7 // indirect + github.com/aserto-dev/go-directory v0.33.10 // indirect + github.com/aserto-dev/logger v0.0.9 // indirect github.com/dongri/phonenumber v0.1.12 // indirect github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect @@ -35,13 +35,13 @@ require ( github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/spf13/cast v1.7.1 // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/net v0.37.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/grpc v1.71.0 // indirect - google.golang.org/protobuf v1.36.5 // indirect + golang.org/x/crypto v0.37.0 // indirect + golang.org/x/net v0.39.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/grpc v1.71.1 // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/plugins/ldap/go.sum b/plugins/ldap/go.sum index 5140c691..6046a9d1 100644 --- a/plugins/ldap/go.sum +++ b/plugins/ldap/go.sum @@ -12,14 +12,20 @@ github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8v github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/kong v1.8.1 h1:6aamvWBE/REnR/BCq10EcozmcpUPc5aGI1lPAWdB0EE= github.com/alecthomas/kong v1.8.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= +github.com/alecthomas/kong v1.10.0 h1:8K4rGDpT7Iu+jEXCIJUeKqvpwZHbsFRoebLbnzlmrpw= +github.com/alecthomas/kong v1.10.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/aserto-dev/go-directory v0.33.7 h1:jldr2cGQp5EYM4l3IKSNyuK3Rr30taQ7MejbIHt+rGQ= github.com/aserto-dev/go-directory v0.33.7/go.mod h1:mY53j91JUnGRk9lsfw3yxgQXO41SCnt2bSP/2PamxCo= +github.com/aserto-dev/go-directory v0.33.10 h1:PLevCAWc9QeLZZv5Wc+yGk4psSd3507y1+9Fps+CzdI= +github.com/aserto-dev/go-directory v0.33.10/go.mod h1:CYRXxtDtf4zSwYYBBkGqW3b7HWJWvoIEBWgah9SGMAM= github.com/aserto-dev/logger v0.0.7 h1:ORvXxZDMNIcN/E3SYHj8fxmNZnOD7Gf87pOLB2XQavw= github.com/aserto-dev/logger v0.0.7/go.mod h1:66ff7ALo68NT1HcCg5zytOnGh6I5R0HeDpN85cwHcD0= +github.com/aserto-dev/logger v0.0.9 h1:QH11l8937Sw+GAe2yvgpoLg70fqQvPrEufkXAmDUk0g= +github.com/aserto-dev/logger v0.0.9/go.mod h1:mMXq/bhdIKoOVsIZ2zJOqgjcc/jR2x14FhU0St/8AVQ= github.com/bwmarrin/go-objectsid v0.0.0-20191126144531-5fee401a2f37 h1:MuLKITJFJ3Q4zql+AMdvOWgL1c4sB9SIF3tIrbQ8Jw0= github.com/bwmarrin/go-objectsid v0.0.0-20191126144531-5fee401a2f37/go.mod h1:bh3gp4JMNaDCqhJfKGjttehBWFtgfQ/FUevRm5fr88E= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -34,6 +40,8 @@ github.com/go-asn1-ber/asn1-ber v1.5.7 h1:DTX+lbVTWaTw1hQ+PbZPlnDZPEIs0SS/GCZAl5 github.com/go-asn1-ber/asn1-ber v1.5.7/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= github.com/go-ldap/ldap/v3 v3.4.9 h1:KxX9eO44/MpqPXVVMPJDB+k/35GEePHE/Jfvl7oRMUo= github.com/go-ldap/ldap/v3 v3.4.9/go.mod h1:+CE/4PPOOdEPGTi2B7qXKQOq+pNBvXZtlBNcVZY0AWI= +github.com/go-ldap/ldap/v3 v3.4.10 h1:ot/iwPOhfpNVgB1o+AVXljizWZ9JTp7YF5oeyONmcJU= +github.com/go-ldap/ldap/v3 v3.4.10/go.mod h1:JXh4Uxgi40P6E9rdsYqpUtbW46D9UTjJ9QSwGRznplY= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -92,8 +100,11 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= @@ -130,6 +141,8 @@ golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ss golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -146,8 +159,11 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -170,6 +186,8 @@ golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= 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= @@ -190,6 +208,8 @@ golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= @@ -199,12 +219,20 @@ golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxb golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a h1:OQ7sHVzkx6L57dQpzUS4ckfWJ51KDH74XHTDe23xWAs= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a/go.mod h1:2R6XrVC8Oc08GlNh8ujEpc7HkLiEZ16QeY7FxIs20ac= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a h1:GIqLhp/cYUkuGuiT+vJk8vhOP86L4+SP5j8yXgeVpvI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= +google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= +google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/plugins/ldap/pkg/app/constants.go b/plugins/ldap/pkg/app/constants.go index b0472999..71cba3ec 100644 --- a/plugins/ldap/pkg/app/constants.go +++ b/plugins/ldap/pkg/app/constants.go @@ -1,4 +1,6 @@ package app -const AppName = "ds-load-ldap" -const AppDescription = "ldap directory loader" +const ( + AppName = "ds-load-ldap" + AppDescription = "ldap directory loader" +) diff --git a/plugins/ldap/pkg/app/fetch.go b/plugins/ldap/pkg/app/fetch.go index 95cd76a0..9d80f15c 100644 --- a/plugins/ldap/pkg/app/fetch.go +++ b/plugins/ldap/pkg/app/fetch.go @@ -5,6 +5,7 @@ import ( "github.com/aserto-dev/ds-load/plugins/ldap/pkg/fetch" "github.com/aserto-dev/ds-load/plugins/ldap/pkg/ldapclient" + "github.com/aserto-dev/ds-load/sdk/common" "github.com/aserto-dev/ds-load/sdk/common/cc" ) @@ -42,5 +43,5 @@ func (cmd *FetchCmd) Run(ctx *cc.CommonCtx) error { fetcher := fetch.New(ldapClient, cmd.IDField) - return fetcher.Fetch(ctx.Context, os.Stdout, os.Stderr) + return fetcher.Fetch(ctx.Context, os.Stdout, common.NewErrorWriter(os.Stderr)) } diff --git a/plugins/ldap/pkg/fetch/fetch.go b/plugins/ldap/pkg/fetch/fetch.go index b53de6cd..4fd30ddd 100644 --- a/plugins/ldap/pkg/fetch/fetch.go +++ b/plugins/ldap/pkg/fetch/fetch.go @@ -6,6 +6,7 @@ import ( "github.com/aserto-dev/ds-load/plugins/ldap/pkg/attribute" "github.com/aserto-dev/ds-load/plugins/ldap/pkg/ldapclient" + "github.com/aserto-dev/ds-load/sdk/common" "github.com/aserto-dev/ds-load/sdk/common/js" "github.com/go-ldap/ldap/v3" ) @@ -28,7 +29,7 @@ func New(ldapClient *ldapclient.LDAPClient, idField string) *Fetcher { } } -func (f *Fetcher) Fetch(ctx context.Context, outputWriter, errorWriter io.Writer) error { +func (f *Fetcher) Fetch(ctx context.Context, outputWriter io.Writer, errorWriter common.ErrorWriter) error { jsonWriter := js.NewJSONArrayWriter(outputWriter) defer jsonWriter.Close() diff --git a/plugins/ldap/pkg/ldapclient/ldapclient.go b/plugins/ldap/pkg/ldapclient/ldapclient.go index f545e13b..f8d92132 100644 --- a/plugins/ldap/pkg/ldapclient/ldapclient.go +++ b/plugins/ldap/pkg/ldapclient/ldapclient.go @@ -30,6 +30,11 @@ type ConnectionOptions struct { IDField string } +const ( + defaultConnectionTimeout = 10 * time.Second + defaultPageSize = 1000 +) + func NewLDAPClient(credentials *Credentials, conOptions *ConnectionOptions, logger *zerolog.Logger) (*LDAPClient, error) { ldapClient := &LDAPClient{} @@ -50,7 +55,7 @@ func (l *LDAPClient) initLDAPConnection(username, password, host string, insecur var dialOptions []ldap.DialOpt // Set default timeout for init connection - ldap.DefaultTimeout = 10 * time.Second + ldap.DefaultTimeout = defaultConnectionTimeout // Disable the security check if insecure is true if insecure { // #nosec G402 @@ -73,7 +78,7 @@ func (l *LDAPClient) initLDAPConnection(username, password, host string, insecur func (l *LDAPClient) Close() { err := l.ldapConn.Close() if err != nil { - l.logger.Error().Err(err) + l.logger.Error().Err(err).Msg("failed to close ldap connection") } } @@ -96,7 +101,7 @@ func (l *LDAPClient) search(filter string) []*ldap.Entry { nil, ) - sr, err := l.ldapConn.SearchWithPaging(searchRequest, 1000) + sr, err := l.ldapConn.SearchWithPaging(searchRequest, defaultPageSize) if err != nil { log.Fatal(err) } diff --git a/plugins/okta/go.mod b/plugins/okta/go.mod index 03510d5e..106a95d7 100644 --- a/plugins/okta/go.mod +++ b/plugins/okta/go.mod @@ -7,11 +7,11 @@ toolchain go1.24.1 replace github.com/aserto-dev/ds-load/sdk => ../../sdk require ( - github.com/alecthomas/kong v1.8.1 - github.com/aserto-dev/ds-load/sdk v0.0.0-20241206112725-5d200d771446 + github.com/alecthomas/kong v1.10.0 + github.com/aserto-dev/ds-load/sdk v0.0.0-20250408143332-e8965667fcc0 github.com/okta/okta-sdk-golang/v5 v5.0.4 github.com/pkg/errors v0.9.1 - google.golang.org/grpc v1.71.0 + google.golang.org/grpc v1.71.1 ) require ( @@ -19,13 +19,13 @@ require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.3.1 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect - github.com/aserto-dev/go-directory v0.33.7 // indirect - github.com/aserto-dev/logger v0.0.7 // indirect + github.com/aserto-dev/go-directory v0.33.10 // indirect + github.com/aserto-dev/logger v0.0.9 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect github.com/dongri/phonenumber v0.1.12 // indirect github.com/go-jose/go-jose/v3 v3.0.4 // indirect - github.com/goccy/go-json v0.10.3 // indirect + github.com/goccy/go-json v0.10.5 // indirect github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect github.com/huandu/xstrings v1.5.0 // indirect @@ -34,7 +34,7 @@ require ( github.com/lestrrat-go/blackmagic v1.0.2 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect github.com/lestrrat-go/iter v1.0.2 // indirect - github.com/lestrrat-go/jwx v1.2.29 // indirect + github.com/lestrrat-go/jwx v1.2.31 // indirect github.com/lestrrat-go/option v1.0.1 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -42,16 +42,16 @@ require ( github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/patrickmn/go-cache v0.0.0-20180815053127-5633e0862627 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect - github.com/rs/zerolog v1.33.0 // indirect + github.com/rs/zerolog v1.34.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/spf13/cast v1.7.1 // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/net v0.37.0 // indirect - golang.org/x/oauth2 v0.27.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/protobuf v1.36.5 // indirect + golang.org/x/crypto v0.37.0 // indirect + golang.org/x/net v0.39.0 // indirect + golang.org/x/oauth2 v0.29.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/plugins/okta/go.sum b/plugins/okta/go.sum index b7494013..77eea70a 100644 --- a/plugins/okta/go.sum +++ b/plugins/okta/go.sum @@ -10,12 +10,18 @@ github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8v github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/kong v1.8.1 h1:6aamvWBE/REnR/BCq10EcozmcpUPc5aGI1lPAWdB0EE= github.com/alecthomas/kong v1.8.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= +github.com/alecthomas/kong v1.10.0 h1:8K4rGDpT7Iu+jEXCIJUeKqvpwZHbsFRoebLbnzlmrpw= +github.com/alecthomas/kong v1.10.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/aserto-dev/go-directory v0.33.7 h1:jldr2cGQp5EYM4l3IKSNyuK3Rr30taQ7MejbIHt+rGQ= github.com/aserto-dev/go-directory v0.33.7/go.mod h1:mY53j91JUnGRk9lsfw3yxgQXO41SCnt2bSP/2PamxCo= +github.com/aserto-dev/go-directory v0.33.10 h1:PLevCAWc9QeLZZv5Wc+yGk4psSd3507y1+9Fps+CzdI= +github.com/aserto-dev/go-directory v0.33.10/go.mod h1:CYRXxtDtf4zSwYYBBkGqW3b7HWJWvoIEBWgah9SGMAM= github.com/aserto-dev/logger v0.0.7 h1:ORvXxZDMNIcN/E3SYHj8fxmNZnOD7Gf87pOLB2XQavw= github.com/aserto-dev/logger v0.0.7/go.mod h1:66ff7ALo68NT1HcCg5zytOnGh6I5R0HeDpN85cwHcD0= +github.com/aserto-dev/logger v0.0.9 h1:QH11l8937Sw+GAe2yvgpoLg70fqQvPrEufkXAmDUk0g= +github.com/aserto-dev/logger v0.0.9/go.mod h1:mMXq/bhdIKoOVsIZ2zJOqgjcc/jR2x14FhU0St/8AVQ= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -26,6 +32,8 @@ github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPc github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= github.com/dongri/phonenumber v0.1.12 h1:rR/4VZzxqpocUdyM4dIdfY0TWd8FcW43oiyPaOUxNIk= github.com/dongri/phonenumber v0.1.12/go.mod h1:cuHFSstIxh6qh/Qs/SCV3Grb/JMYregBLuXELvSYmT4= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= @@ -39,6 +47,8 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= +github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= @@ -71,6 +81,8 @@ github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzlt github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4= github.com/lestrrat-go/jwx v1.2.29 h1:QT0utmUJ4/12rmsVQrJ3u55bycPkKqGYuGT4tyRhxSQ= github.com/lestrrat-go/jwx v1.2.29/go.mod h1:hU8k2l6WF0ncx20uQdOmik/Gjg6E3/wIRtXSNFeZuB8= +github.com/lestrrat-go/jwx v1.2.31 h1:/OM9oNl/fzyldpv5HKZ9m7bTywa7COUfg8gujd9nJ54= +github.com/lestrrat-go/jwx v1.2.31/go.mod h1:eQJKoRwWcLg4PfD5CFA5gIZGxhPgoPYq9pZISdxLf0c= github.com/lestrrat-go/option v1.0.0/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= @@ -98,8 +110,11 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= @@ -135,6 +150,8 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -145,8 +162,12 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98= +golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -164,6 +185,8 @@ golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 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= @@ -178,6 +201,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= @@ -185,12 +210,20 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a h1:OQ7sHVzkx6L57dQpzUS4ckfWJ51KDH74XHTDe23xWAs= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a/go.mod h1:2R6XrVC8Oc08GlNh8ujEpc7HkLiEZ16QeY7FxIs20ac= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a h1:GIqLhp/cYUkuGuiT+vJk8vhOP86L4+SP5j8yXgeVpvI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= +google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= +google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/plugins/okta/pkg/app/constants.go b/plugins/okta/pkg/app/constants.go index 3e34aaf0..f02c7334 100644 --- a/plugins/okta/pkg/app/constants.go +++ b/plugins/okta/pkg/app/constants.go @@ -1,4 +1,6 @@ package app -const AppName = "ds-load-okta" -const AppDescription = "okta directory loader" +const ( + AppName = "ds-load-okta" + AppDescription = "okta directory loader" +) diff --git a/plugins/okta/pkg/app/fetch.go b/plugins/okta/pkg/app/fetch.go index 58997867..4f8abf26 100644 --- a/plugins/okta/pkg/app/fetch.go +++ b/plugins/okta/pkg/app/fetch.go @@ -5,6 +5,7 @@ import ( "github.com/aserto-dev/ds-load/plugins/okta/pkg/fetch" "github.com/aserto-dev/ds-load/plugins/okta/pkg/oktaclient" + "github.com/aserto-dev/ds-load/sdk/common" "github.com/aserto-dev/ds-load/sdk/common/cc" ) @@ -27,5 +28,5 @@ func (f *FetchCmd) Run(ctx *cc.CommonCtx) error { return err } - return fetcher.WithGroups(f.Groups).WithRoles(f.Roles).Fetch(ctx.Context, os.Stdout, os.Stderr) + return fetcher.WithGroups(f.Groups).WithRoles(f.Roles).Fetch(ctx.Context, os.Stdout, common.NewErrorWriter(os.Stderr)) } diff --git a/plugins/okta/pkg/app/transform.go b/plugins/okta/pkg/app/transform.go index 50d46b93..1263a17a 100644 --- a/plugins/okta/pkg/app/transform.go +++ b/plugins/okta/pkg/app/transform.go @@ -15,13 +15,17 @@ type TransformCmd struct { Template string `name:"template" short:"t" env:"DS_TEMPLATE_FILE" help:"transformation template file path" type:"path" optional:""` } +const ( + defaultTimeout = 1500 * time.Millisecond +) + func (t *TransformCmd) Run(kongContext *kong.Context) error { template, err := t.getTemplateContent() if err != nil { return err } - timeoutCtx, cancel := context.WithTimeout(context.Background(), 1500*time.Millisecond) + timeoutCtx, cancel := context.WithTimeout(context.Background(), defaultTimeout) defer cancel() goTemplateTransformer := transform.NewGoTemplateTransform(template) diff --git a/plugins/okta/pkg/fetch/fetch.go b/plugins/okta/pkg/fetch/fetch.go index efdeb686..52c4302c 100644 --- a/plugins/okta/pkg/fetch/fetch.go +++ b/plugins/okta/pkg/fetch/fetch.go @@ -1,3 +1,4 @@ +//nolint:dupl // similar code in getting group details package fetch import ( @@ -34,7 +35,7 @@ func (fetcher *Fetcher) WithRoles(roles bool) *Fetcher { return fetcher } -func (fetcher *Fetcher) Fetch(ctx context.Context, outputWriter, errorWriter io.Writer) error { +func (fetcher *Fetcher) Fetch(ctx context.Context, outputWriter io.Writer, errorWriter common.ErrorWriter) error { writer := js.NewJSONArrayWriter(outputWriter) defer writer.Close() @@ -48,10 +49,10 @@ func (fetcher *Fetcher) Fetch(ctx context.Context, outputWriter, errorWriter io. return fetcher.fetchUsers(ctx, writer, errorWriter) } -func (fetcher *Fetcher) fetchUsers(ctx context.Context, writer *js.JSONArrayWriter, errorWriter io.Writer) error { +func (fetcher *Fetcher) fetchUsers(ctx context.Context, writer *js.JSONArrayWriter, errorWriter common.ErrorWriter) error { users, response, err := fetcher.oktaClient.User.ListUsers(ctx).Execute() if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) + errorWriter.Error(err) return err } @@ -62,21 +63,15 @@ func (fetcher *Fetcher) fetchUsers(ctx context.Context, writer *js.JSONArrayWrit user := &users[i] userResult, err := fetcher.processUser(ctx, user, errorWriter) - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - } + errorWriter.Error(err) err = writer.Write(userResult) - if err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } + errorWriter.Error(err) } if response != nil && response.HasNextPage() { response, err = response.Next(&users) - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - } + errorWriter.Error(err) } else { break } @@ -85,10 +80,10 @@ func (fetcher *Fetcher) fetchUsers(ctx context.Context, writer *js.JSONArrayWrit return nil } -func (fetcher *Fetcher) fetchGroups(ctx context.Context, writer *js.JSONArrayWriter, errorWriter io.Writer) error { +func (fetcher *Fetcher) fetchGroups(ctx context.Context, writer *js.JSONArrayWriter, errorWriter common.ErrorWriter) error { groups, response, err := fetcher.oktaClient.Group.ListGroups(ctx).Execute() if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) + errorWriter.Error(err) return err } @@ -97,21 +92,15 @@ func (fetcher *Fetcher) fetchGroups(ctx context.Context, writer *js.JSONArrayWri for _, group := range groups { groupResult, err := fetcher.processGroup(ctx, &group, errorWriter) - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - } + errorWriter.Error(err, common.WithExitCode) err = writer.Write(groupResult) - if err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } + errorWriter.Error(err) } if response != nil && response.HasNextPage() { response, err = response.Next(&groups) - if err != nil { - common.WriteErrorWithExitCode(errorWriter, err, 1) - } + errorWriter.Error(err) } else { break } @@ -120,14 +109,14 @@ func (fetcher *Fetcher) fetchGroups(ctx context.Context, writer *js.JSONArrayWri return nil } -func (fetcher *Fetcher) processUser(ctx context.Context, user *okta.User, errorWriter io.Writer) (map[string]interface{}, error) { +func (fetcher *Fetcher) processUser(ctx context.Context, user *okta.User, errorWriter common.ErrorWriter) (map[string]any, error) { userBytes, err := json.Marshal(user) if err != nil { common.SetExitCode(1) return nil, err } - var userResult map[string]interface{} + var userResult map[string]any if err := json.Unmarshal(userBytes, &userResult); err != nil { common.SetExitCode(1) @@ -159,14 +148,14 @@ func (fetcher *Fetcher) processUser(ctx context.Context, user *okta.User, errorW return userResult, nil } -func (fetcher *Fetcher) processGroup(ctx context.Context, group *okta.Group, errorWriter io.Writer) (map[string]interface{}, error) { +func (fetcher *Fetcher) processGroup(ctx context.Context, group *okta.Group, errorWriter common.ErrorWriter) (map[string]any, error) { userBytes, err := json.Marshal(group) if err != nil { common.SetExitCode(1) return nil, err } - var groupResult map[string]interface{} + var groupResult map[string]any if err := json.Unmarshal(userBytes, &groupResult); err != nil { common.SetExitCode(1) @@ -187,10 +176,10 @@ func (fetcher *Fetcher) processGroup(ctx context.Context, group *okta.Group, err return groupResult, nil } -func (fetcher *Fetcher) getGroups(ctx context.Context, userID string, errorWriter io.Writer) ([]map[string]interface{}, error) { +func (fetcher *Fetcher) getGroups(ctx context.Context, userID string, errorWriter common.ErrorWriter) ([]map[string]any, error) { var ( response *okta.APIResponse - result []map[string]interface{} + result []map[string]any groups []okta.Group err error ) @@ -209,7 +198,7 @@ func (fetcher *Fetcher) getGroups(ctx context.Context, userID string, errorWrite return nil, err } - var obj map[string]interface{} + var obj map[string]any if err := json.Unmarshal(groupBytes, &obj); err != nil { return nil, err } @@ -230,10 +219,10 @@ func (fetcher *Fetcher) getGroups(ctx context.Context, userID string, errorWrite return result, nil } -func (fetcher *Fetcher) getUserRoles(ctx context.Context, userID string, errorWriter io.Writer) ([]map[string]interface{}, error) { +func (fetcher *Fetcher) getUserRoles(ctx context.Context, userID string, errorWriter common.ErrorWriter) ([]map[string]any, error) { var ( response *okta.APIResponse - result []map[string]interface{} + result []map[string]any roles []okta.Role err error ) @@ -252,7 +241,7 @@ func (fetcher *Fetcher) getUserRoles(ctx context.Context, userID string, errorWr return nil, err } - var obj map[string]interface{} + var obj map[string]any if err := json.Unmarshal(roleBytes, &obj); err != nil { return nil, err @@ -274,10 +263,10 @@ func (fetcher *Fetcher) getUserRoles(ctx context.Context, userID string, errorWr return result, nil } -func (fetcher *Fetcher) getGroupRoles(ctx context.Context, groupID string, errorWriter io.Writer) ([]map[string]interface{}, error) { +func (fetcher *Fetcher) getGroupRoles(ctx context.Context, groupID string, errorWriter common.ErrorWriter) ([]map[string]any, error) { var ( response *okta.APIResponse - result []map[string]interface{} + result []map[string]any roles []okta.Role err error ) @@ -296,7 +285,7 @@ func (fetcher *Fetcher) getGroupRoles(ctx context.Context, groupID string, error return nil, err } - var obj map[string]interface{} + var obj map[string]any if err := json.Unmarshal(roleBytes, &obj); err != nil { return nil, err } @@ -317,7 +306,7 @@ func (fetcher *Fetcher) getGroupRoles(ctx context.Context, groupID string, error return result, nil } -func logIfRateLimitExceeded(resp *okta.APIResponse, errorWriter io.Writer) { +func logIfRateLimitExceeded(resp *okta.APIResponse, errorWriter common.ErrorWriter) { if resp.Response != nil && resp.StatusCode == http.StatusTooManyRequests { _, _ = errorWriter.Write([]byte("Rate limit exceeded")) } diff --git a/plugins/okta/pkg/oktaclient/okta.go b/plugins/okta/pkg/oktaclient/okta.go index aee368fb..f17822b0 100644 --- a/plugins/okta/pkg/oktaclient/okta.go +++ b/plugins/okta/pkg/oktaclient/okta.go @@ -1,8 +1,6 @@ package oktaclient import ( - "fmt" - "github.com/okta/okta-sdk-golang/v5/okta" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -14,14 +12,20 @@ type OktaClient struct { RoleAssignments okta.RoleAssignmentAPI } +const ( + defaultConnectionTimeout = 5 + defaultRateLimitBackoff = 30 + defaultRateLimitRetries = 3 +) + func NewOktaClient(domain, token string, requestTimeout int64) (*OktaClient, error) { config, err := okta.NewConfiguration( - okta.WithOrgUrl(fmt.Sprintf("https://%s", domain)), + okta.WithOrgUrl("https://"+domain), okta.WithToken(token), - okta.WithConnectionTimeout(5), + okta.WithConnectionTimeout(defaultConnectionTimeout), okta.WithRequestTimeout(requestTimeout), - okta.WithRateLimitMaxBackOff(30), - okta.WithRateLimitMaxRetries(3), + okta.WithRateLimitMaxBackOff(defaultRateLimitBackoff), + okta.WithRateLimitMaxRetries(defaultRateLimitRetries), ) if err != nil { return nil, status.Errorf(codes.Internal, "failed to create Okta configuration: %s", err.Error()) diff --git a/plugins/openapi/go.mod b/plugins/openapi/go.mod index 3fcbb710..2288a790 100644 --- a/plugins/openapi/go.mod +++ b/plugins/openapi/go.mod @@ -7,28 +7,33 @@ toolchain go1.24.1 replace github.com/aserto-dev/ds-load/sdk => ../../sdk require ( - github.com/alecthomas/kong v1.8.1 - github.com/aserto-dev/ds-load/sdk v0.0.0-20241206112725-5d200d771446 + github.com/alecthomas/kong v1.10.0 + github.com/aserto-dev/ds-load/sdk v0.0.0-20250408143332-e8965667fcc0 github.com/pkg/errors v0.9.1 ) +require ( + github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 // indirect + github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect +) + require ( dario.cat/mergo v1.0.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.3.1 // indirect github.com/Masterminds/sprig/v3 v3.3.0 // indirect - github.com/aserto-dev/go-directory v0.33.7 // indirect - github.com/aserto-dev/logger v0.0.7 // indirect + github.com/aserto-dev/go-directory v0.33.10 // indirect + github.com/aserto-dev/logger v0.0.9 // indirect github.com/dongri/phonenumber v0.1.12 // indirect - github.com/getkin/kin-openapi v0.128.0 - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/swag v0.23.0 // indirect + github.com/getkin/kin-openapi v0.131.0 + github.com/go-openapi/jsonpointer v0.21.1 // indirect + github.com/go-openapi/swag v0.23.1 // indirect github.com/google/uuid v1.6.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect github.com/huandu/xstrings v1.5.0 // indirect github.com/invopop/yaml v0.3.1 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect @@ -36,17 +41,17 @@ require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect - github.com/rs/zerolog v1.33.0 // indirect + github.com/rs/zerolog v1.34.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/spf13/cast v1.7.1 // indirect github.com/ugorji/go/codec v1.2.12 // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/net v0.37.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/grpc v1.71.0 // indirect - google.golang.org/protobuf v1.36.5 // indirect + golang.org/x/crypto v0.37.0 // indirect + golang.org/x/net v0.39.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/grpc v1.71.1 // indirect + google.golang.org/protobuf v1.36.6 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/plugins/openapi/go.sum b/plugins/openapi/go.sum index b9be5569..cd52d65f 100644 --- a/plugins/openapi/go.sum +++ b/plugins/openapi/go.sum @@ -10,12 +10,18 @@ github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8v github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/kong v1.8.1 h1:6aamvWBE/REnR/BCq10EcozmcpUPc5aGI1lPAWdB0EE= github.com/alecthomas/kong v1.8.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= +github.com/alecthomas/kong v1.10.0 h1:8K4rGDpT7Iu+jEXCIJUeKqvpwZHbsFRoebLbnzlmrpw= +github.com/alecthomas/kong v1.10.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/aserto-dev/go-directory v0.33.7 h1:jldr2cGQp5EYM4l3IKSNyuK3Rr30taQ7MejbIHt+rGQ= github.com/aserto-dev/go-directory v0.33.7/go.mod h1:mY53j91JUnGRk9lsfw3yxgQXO41SCnt2bSP/2PamxCo= +github.com/aserto-dev/go-directory v0.33.10 h1:PLevCAWc9QeLZZv5Wc+yGk4psSd3507y1+9Fps+CzdI= +github.com/aserto-dev/go-directory v0.33.10/go.mod h1:CYRXxtDtf4zSwYYBBkGqW3b7HWJWvoIEBWgah9SGMAM= github.com/aserto-dev/logger v0.0.7 h1:ORvXxZDMNIcN/E3SYHj8fxmNZnOD7Gf87pOLB2XQavw= github.com/aserto-dev/logger v0.0.7/go.mod h1:66ff7ALo68NT1HcCg5zytOnGh6I5R0HeDpN85cwHcD0= +github.com/aserto-dev/logger v0.0.9 h1:QH11l8937Sw+GAe2yvgpoLg70fqQvPrEufkXAmDUk0g= +github.com/aserto-dev/logger v0.0.9/go.mod h1:mMXq/bhdIKoOVsIZ2zJOqgjcc/jR2x14FhU0St/8AVQ= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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= @@ -25,14 +31,20 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= +github.com/getkin/kin-openapi v0.131.0 h1:NO2UeHnFKRYhZ8wg6Nyh5Cq7dHk4suQQr72a4pMrDxE= +github.com/getkin/kin-openapi v0.131.0/go.mod h1:3OlG51PCYNsPByuiMB0t4fjnNlIDnaEDsjiKUV8nL58= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonpointer v0.21.1 h1:whnzv/pNXtK2FbX/W9yJfRmE2gsmkfahjMKB0fZvcic= +github.com/go-openapi/jsonpointer v0.21.1/go.mod h1:50I1STOfbY1ycR8jGz8DaMeLCdXiI6aDteEdRNNzpdk= github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-openapi/swag v0.23.1 h1:lpsStH0n2ittzTnbaSloVZLuB5+fvSY/+hnagBjSNZU= +github.com/go-openapi/swag v0.23.1/go.mod h1:STZs8TbRvEQQKUA+JZNAm3EWlgaOBGpyFDqQnDHMef0= github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -58,6 +70,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= @@ -71,6 +85,10 @@ github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zx github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY= +github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw= +github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c= +github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -81,8 +99,11 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= @@ -105,23 +126,39 @@ go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a h1:OQ7sHVzkx6L57dQpzUS4ckfWJ51KDH74XHTDe23xWAs= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a/go.mod h1:2R6XrVC8Oc08GlNh8ujEpc7HkLiEZ16QeY7FxIs20ac= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a h1:GIqLhp/cYUkuGuiT+vJk8vhOP86L4+SP5j8yXgeVpvI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= +google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= +google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/plugins/openapi/pkg/app/fetch.go b/plugins/openapi/pkg/app/fetch.go index f9e2b3d4..14c70f2d 100644 --- a/plugins/openapi/pkg/app/fetch.go +++ b/plugins/openapi/pkg/app/fetch.go @@ -5,6 +5,7 @@ import ( "github.com/aserto-dev/ds-load/plugins/openapi/pkg/fetch" "github.com/aserto-dev/ds-load/plugins/openapi/pkg/openapi" + "github.com/aserto-dev/ds-load/sdk/common" "github.com/aserto-dev/ds-load/sdk/common/cc" ) @@ -28,5 +29,5 @@ func (cmd *FetchCmd) Run(ctx *cc.CommonCtx) error { fetcher = fetcher.WithDirectory(cmd.Directory).WithURL(cmd.URL).WithIDFormat(cmd.IDFormat).WithServiceName(cmd.ServiceName) - return fetcher.Fetch(ctx.Context, os.Stdout, os.Stderr) + return fetcher.Fetch(ctx.Context, os.Stdout, common.NewErrorWriter(os.Stderr)) } diff --git a/plugins/openapi/pkg/fetch/fetch.go b/plugins/openapi/pkg/fetch/fetch.go index 7d189fa7..394f5bdc 100644 --- a/plugins/openapi/pkg/fetch/fetch.go +++ b/plugins/openapi/pkg/fetch/fetch.go @@ -5,6 +5,7 @@ import ( "io" "github.com/aserto-dev/ds-load/plugins/openapi/pkg/openapi" + "github.com/aserto-dev/ds-load/sdk/common" "github.com/aserto-dev/ds-load/sdk/common/js" ) @@ -42,30 +43,24 @@ func (f *Fetcher) WithServiceName(serviceName string) *Fetcher { return f } -func (f *Fetcher) Fetch(ctx context.Context, outputWriter, errorWriter io.Writer) error { +func (f *Fetcher) Fetch(ctx context.Context, outputWriter io.Writer, errorWriter common.ErrorWriter) error { writer := js.NewJSONArrayWriter(outputWriter) defer writer.Close() services, err := f.client.ListServices() - if err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } + errorWriter.Error(err) for _, service := range services { - if err := writer.Write(service); err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } + err := writer.Write(service) + errorWriter.Error(err) } apis, err := f.client.ListAPIs() - if err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } + errorWriter.Error(err) for _, api := range apis { - if err := writer.Write(api); err != nil { - _, _ = errorWriter.Write([]byte(err.Error())) - } + err := writer.Write(api) + errorWriter.Error(err) } return nil diff --git a/plugins/openapi/pkg/openapi/openapi.go b/plugins/openapi/pkg/openapi/openapi.go index 86c059d4..21a65731 100644 --- a/plugins/openapi/pkg/openapi/openapi.go +++ b/plugins/openapi/pkg/openapi/openapi.go @@ -26,14 +26,14 @@ type API struct { Service string `json:"service"` Method string `json:"method"` Path string `json:"path"` - DisplayName string `json:"displayName"` + DisplayName string `json:"displayName"` //nolint:tagliatelle // keep open api format ID string `json:"id"` - ServiceID string `json:"serviceID"` + ServiceID string `json:"serviceID"` //nolint:tagliatelle // keep open api format } type Service struct { Type string `json:"type"` - DisplayName string `json:"displayName"` + DisplayName string `json:"displayName"` //nolint:tagliatelle // keep open api format ID string `json:"id"` } @@ -42,49 +42,53 @@ func New(directory, specURL, idFormat, serviceName string) (*Client, error) { c.idFormat = idFormat c.docs = make([]*openapi3.T, 0) - if specURL != "" { - parsedURL, err := url.Parse(specURL) - if err != nil { - return nil, errors.Wrapf(err, "url not parsed: %s", specURL) - } + if specURL == "" { + return nil, errors.Errorf("spec URL must be set") + } - doc, err := openapi3.NewLoader().LoadFromURI(parsedURL) - if err != nil { - return nil, errors.Wrapf(err, "cannot load OpenAPI spec from URL : %s", specURL) - } + parsedURL, err := url.Parse(specURL) + if err != nil { + return nil, errors.Wrapf(err, "url not parsed: %s", specURL) + } - if serviceName != "" { - if doc.Info.Extensions == nil { - doc.Info.Extensions = make(map[string]interface{}, 0) - } + doc, err := openapi3.NewLoader().LoadFromURI(parsedURL) + if err != nil { + return nil, errors.Wrapf(err, "cannot load OpenAPI spec from URL : %s", specURL) + } - doc.Info.Extensions["ServiceName"] = canonicalizeServiceName(serviceName, Canonical) + if serviceName != "" { + if doc.Info.Extensions == nil { + doc.Info.Extensions = make(map[string]any, 0) } - c.docs = append(c.docs, doc) + doc.Info.Extensions["ServiceName"] = canonicalizeServiceName(serviceName, Canonical) } - if directory != "" { - if _, err := os.Stat(directory); errors.Is(err, os.ErrNotExist) { - return nil, errors.Wrapf(err, "directory not found: %s", directory) - } + c.docs = append(c.docs, doc) - files, err := os.ReadDir(directory) - if err != nil { - return nil, errors.Wrapf(err, "cannot read directory: %s", directory) - } + if directory == "" { + return nil, errors.Errorf("directory must be set") + } - for _, file := range files { - if !file.IsDir() { - filename := fmt.Sprintf("%s/%s", directory, file.Name()) + if _, err := os.Stat(directory); errors.Is(err, os.ErrNotExist) { + return nil, errors.Wrapf(err, "directory not found: %s", directory) + } + + files, err := os.ReadDir(directory) + if err != nil { + return nil, errors.Wrapf(err, "cannot read directory: %s", directory) + } - doc, err := openapi3.NewLoader().LoadFromFile(filename) - if err != nil { - return nil, errors.Wrapf(err, "cannot open file: %s", file.Name()) - } + for _, file := range files { + if !file.IsDir() { + filename := fmt.Sprintf("%s/%s", directory, file.Name()) - c.docs = append(c.docs, doc) + doc, err := openapi3.NewLoader().LoadFromFile(filename) + if err != nil { + return nil, errors.Wrapf(err, "cannot open file: %s", file.Name()) } + + c.docs = append(c.docs, doc) } } @@ -96,8 +100,15 @@ func (c *Client) ListServices() ([]Service, error) { for _, service := range c.docs { id := "" + if service.Info.Extensions["ServiceName"] != "" { - id = service.Info.Extensions["ServiceName"].(string) + serviceName, ok := service.Info.Extensions["ServiceName"].(string) + + if !ok { + return services, errors.Errorf("service name cannot be cast to string") + } + + id = serviceName } svc := newService(service.Info.Title, id, c.idFormat) @@ -121,8 +132,8 @@ func (c *Client) ListAPIs() ([]API, error) { func (c *Client) ListAPIsInService(service *openapi3.T, idFormat string) []API { apis := make([]API, 0) - serviceID := service.Info.Extensions["ServiceName"].(string) - if serviceID == "" { + serviceID, ok := service.Info.Extensions["ServiceName"].(string) + if serviceID == "" || !ok { serviceID = service.Info.Title } @@ -213,8 +224,8 @@ func canonicalizeServiceName(serviceName, idFormat string) string { case Base64: return base64.StdEncoding.EncodeToString([]byte(serviceName)) case Canonical: - return strings.Replace(serviceName, " ", "_", -1) + return strings.ReplaceAll(serviceName, " ", "_") default: - return strings.Replace(serviceName, " ", "_", -1) + return strings.ReplaceAll(serviceName, " ", "_") } } diff --git a/sdk/common/cc/cc.go b/sdk/common/cc/cc.go index 4e843f89..394c660f 100644 --- a/sdk/common/cc/cc.go +++ b/sdk/common/cc/cc.go @@ -16,6 +16,13 @@ type CommonCtx struct { ConfigPath string } +const ( + errLogLevel = 1 + infoLogLevel = 2 + debugLogLevel = 3 + traceLogLevel = 4 +) + func NewCommonContext(verbosity int, config string) *CommonCtx { logLevelParsed := GetLogLevel(verbosity) logCfg := &logger.Config{ @@ -40,13 +47,13 @@ func GetLogLevel(intLevel int) zerolog.Level { logLevel := zerolog.FatalLevel switch intLevel { - case 1: + case errLogLevel: logLevel = zerolog.ErrorLevel - case 2: + case infoLogLevel: logLevel = zerolog.InfoLevel - case 3: + case debugLogLevel: logLevel = zerolog.DebugLevel - case 4: + case traceLogLevel: logLevel = zerolog.TraceLevel } diff --git a/sdk/common/error_writer.go b/sdk/common/error_writer.go new file mode 100644 index 00000000..b3a96f7f --- /dev/null +++ b/sdk/common/error_writer.go @@ -0,0 +1,40 @@ +package common + +import ( + "io" +) + +type errorOptions struct { + SetExitCode bool +} + +type ErrorOption func(*errorOptions) + +func WithExitCode(eo *errorOptions) { + eo.SetExitCode = true +} + +type ErrorWriter struct { + io.Writer +} + +func NewErrorWriter(f io.Writer) ErrorWriter { + return ErrorWriter{f} +} + +func (e ErrorWriter) Error(err error, opts ...ErrorOption) { + if err == nil { + return + } + + _, _ = e.Write([]byte(err.Error())) + + options := errorOptions{} + for _, opt := range opts { + opt(&options) + } + + if options.SetExitCode { + SetExitCode(1) + } +} diff --git a/sdk/common/exit_code.go b/sdk/common/exit_code.go index efc92c2a..a1a644b2 100644 --- a/sdk/common/exit_code.go +++ b/sdk/common/exit_code.go @@ -1,7 +1,6 @@ package common import ( - "io" "sync/atomic" ) @@ -14,9 +13,3 @@ func GetExitCode() int { func SetExitCode(code int) { atomic.StoreInt32(&exitCode, int32(code)) //nolint:gosec } - -func WriteErrorWithExitCode(w io.Writer, err error, code int) { - _, _ = w.Write([]byte(err.Error())) - - SetExitCode(code) -} diff --git a/sdk/common/kongyaml/kongyaml.go b/sdk/common/kongyaml/kongyaml.go index c2c3da66..5a129ca7 100644 --- a/sdk/common/kongyaml/kongyaml.go +++ b/sdk/common/kongyaml/kongyaml.go @@ -19,9 +19,11 @@ func NewYAMLResolver(yamlKey string) *YAMLResolver { } // Loader is a Kong configuration loader for YAML. +// +//nolint:ireturn // loader returns a kong resolver interface func (y *YAMLResolver) Loader(r io.Reader) (kong.Resolver, error) { decoder := yaml.NewDecoder(r) - config := map[string]interface{}{} + config := map[string]any{} if err := decoder.Decode(config); err != nil { return nil, err @@ -29,7 +31,7 @@ func (y *YAMLResolver) Loader(r io.Reader) (kong.Resolver, error) { if y.yamlKey != "" { var ok bool - config, ok = config[y.yamlKey].(map[string]interface{}) + config, ok = config[y.yamlKey].(map[string]any) if !ok { return kong.ResolverFunc(func(context *kong.Context, parent *kong.Path, flag *kong.Flag) (interface{}, error) { @@ -59,10 +61,10 @@ func (y *YAMLResolver) Loader(r io.Reader) (kong.Resolver, error) { }), nil } -func find(config map[string]interface{}, path []string) interface{} { - for i := 0; i < len(path); i++ { +func find(config map[string]any, path []string) any { + for i := range path { prefix := strings.Join(path[:i+1], "-") - if child, ok := config[prefix].(map[string]interface{}); ok { + if child, ok := config[prefix].(map[string]any); ok { return find(child, path[i+1:]) } } diff --git a/sdk/common/version/version.go b/sdk/common/version/version.go index 17f42db6..b11a11d8 100644 --- a/sdk/common/version/version.go +++ b/sdk/common/version/version.go @@ -7,10 +7,12 @@ import ( ) // values set by linker using ldflag -X. +// +//nolint:gochecknoglobals // set by linker var ( - ver string // nolint:gochecknoglobals // set by linker - date string // nolint:gochecknoglobals // set by linker - commit string // nolint:gochecknoglobals // set by linker + ver string + date string + commit string ) // Info - version info. @@ -56,8 +58,8 @@ func (vi *Info) String() string { ) } -func (vi *Info) AsMap() map[string]interface{} { - return map[string]interface{}{ +func (vi *Info) AsMap() map[string]any { + return map[string]any{ "version": vi.Version, "date": vi.Date, "commit": vi.Commit, diff --git a/sdk/exec/exec.go b/sdk/exec/exec.go index 0a2eb506..8a16cbfe 100644 --- a/sdk/exec/exec.go +++ b/sdk/exec/exec.go @@ -5,6 +5,7 @@ import ( "io" "os" + "github.com/aserto-dev/ds-load/sdk/common" "github.com/aserto-dev/ds-load/sdk/plugin" "github.com/rs/zerolog" ) @@ -14,12 +15,14 @@ func Execute(ctx context.Context, log *zerolog.Logger, transformer plugin.Transf defer pipeReader.Close() go func() { - err := fetcher.Fetch(ctx, pipeWriter, os.Stderr) + err := fetcher.Fetch(ctx, pipeWriter, common.NewErrorWriter(os.Stderr)) if err != nil { log.Printf("Could not fetch data %s", err.Error()) } - pipeWriter.Close() + if err := pipeWriter.Close(); err != nil { + log.Err(err).Msg("failed to close pipe writer") + } }() return transformer.Transform(ctx, pipeReader, os.Stdout, os.Stderr) diff --git a/sdk/fetcher/fetcher.go b/sdk/fetcher/fetcher.go new file mode 100644 index 00000000..eb6fa09c --- /dev/null +++ b/sdk/fetcher/fetcher.go @@ -0,0 +1,30 @@ +package fetcher + +import ( + "encoding/json" + "iter" +) + +func YieldError(err error) iter.Seq2[map[string]any, error] { + return func(yield func(map[string]any, error) bool) { + (yield(nil, err)) + } +} + +func YieldMap[T any](objects []T, marshaller func(T) ([]byte, error)) iter.Seq2[map[string]any, error] { + return func(yield func(map[string]any, error) bool) { + for _, object := range objects { + objectBytes, err := marshaller(object) + if err != nil && !yield(nil, err) { + return + } + + var obj map[string]any + err = json.Unmarshal(objectBytes, &obj) + + if !(yield(obj, err)) { + return + } + } + } +} diff --git a/sdk/go.mod b/sdk/go.mod index 0314daf1..7319c500 100644 --- a/sdk/go.mod +++ b/sdk/go.mod @@ -6,14 +6,14 @@ toolchain go1.24.1 require ( github.com/Masterminds/sprig/v3 v3.3.0 - github.com/alecthomas/kong v1.8.1 - github.com/aserto-dev/go-directory v0.33.7 - github.com/aserto-dev/logger v0.0.7 + github.com/alecthomas/kong v1.10.0 + github.com/aserto-dev/go-directory v0.33.10 + github.com/aserto-dev/logger v0.0.9 github.com/dongri/phonenumber v0.1.12 github.com/pkg/errors v0.9.1 - github.com/rs/zerolog v1.33.0 + github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.10.0 - google.golang.org/protobuf v1.36.5 + google.golang.org/protobuf v1.36.6 gopkg.in/yaml.v3 v3.0.1 ) @@ -34,11 +34,11 @@ require ( github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/spf13/cast v1.7.1 // indirect - golang.org/x/crypto v0.36.0 // indirect - golang.org/x/net v0.37.0 // indirect - golang.org/x/sys v0.31.0 // indirect - golang.org/x/text v0.23.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect - google.golang.org/grpc v1.71.0 // indirect + golang.org/x/crypto v0.37.0 // indirect + golang.org/x/net v0.39.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/text v0.24.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a // indirect + google.golang.org/grpc v1.71.1 // indirect ) diff --git a/sdk/go.sum b/sdk/go.sum index 8a1c6aa9..4dc713c8 100644 --- a/sdk/go.sum +++ b/sdk/go.sum @@ -10,12 +10,18 @@ github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8v github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= github.com/alecthomas/kong v1.8.1 h1:6aamvWBE/REnR/BCq10EcozmcpUPc5aGI1lPAWdB0EE= github.com/alecthomas/kong v1.8.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= +github.com/alecthomas/kong v1.10.0 h1:8K4rGDpT7Iu+jEXCIJUeKqvpwZHbsFRoebLbnzlmrpw= +github.com/alecthomas/kong v1.10.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/aserto-dev/go-directory v0.33.7 h1:jldr2cGQp5EYM4l3IKSNyuK3Rr30taQ7MejbIHt+rGQ= github.com/aserto-dev/go-directory v0.33.7/go.mod h1:mY53j91JUnGRk9lsfw3yxgQXO41SCnt2bSP/2PamxCo= +github.com/aserto-dev/go-directory v0.33.10 h1:PLevCAWc9QeLZZv5Wc+yGk4psSd3507y1+9Fps+CzdI= +github.com/aserto-dev/go-directory v0.33.10/go.mod h1:CYRXxtDtf4zSwYYBBkGqW3b7HWJWvoIEBWgah9SGMAM= github.com/aserto-dev/logger v0.0.7 h1:ORvXxZDMNIcN/E3SYHj8fxmNZnOD7Gf87pOLB2XQavw= github.com/aserto-dev/logger v0.0.7/go.mod h1:66ff7ALo68NT1HcCg5zytOnGh6I5R0HeDpN85cwHcD0= +github.com/aserto-dev/logger v0.0.9 h1:QH11l8937Sw+GAe2yvgpoLg70fqQvPrEufkXAmDUk0g= +github.com/aserto-dev/logger v0.0.9/go.mod h1:mMXq/bhdIKoOVsIZ2zJOqgjcc/jR2x14FhU0St/8AVQ= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= 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= @@ -62,9 +68,13 @@ github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1 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/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0= github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= @@ -85,23 +95,39 @@ go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a h1:OQ7sHVzkx6L57dQpzUS4ckfWJ51KDH74XHTDe23xWAs= +google.golang.org/genproto/googleapis/api v0.0.0-20250409194420-de1ac958c67a/go.mod h1:2R6XrVC8Oc08GlNh8ujEpc7HkLiEZ16QeY7FxIs20ac= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4= google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a h1:GIqLhp/cYUkuGuiT+vJk8vhOP86L4+SP5j8yXgeVpvI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250409194420-de1ac958c67a/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg= google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= +google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI= +google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= +google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/sdk/plugin/plugin.go b/sdk/plugin/plugin.go index f5b6f0f5..1de44487 100644 --- a/sdk/plugin/plugin.go +++ b/sdk/plugin/plugin.go @@ -7,11 +7,12 @@ import ( "os" "sync" + "github.com/aserto-dev/ds-load/sdk/common" "github.com/aserto-dev/ds-load/sdk/common/js" ) type Fetcher interface { - Fetch(ctx context.Context, outputWriter, errorWriter io.Writer) error + Fetch(ctx context.Context, outputWriter io.Writer, errorWriter common.ErrorWriter) error } type Verifier interface { @@ -56,7 +57,7 @@ func NewDSPlugin(options ...PluginOption) *DSPlugin { } // json encodes results and prints to plugin writer. -func (plugin *DSPlugin) WriteFetchOutput(results chan map[string]interface{}, errCh chan error) error { +func (plugin *DSPlugin) WriteFetchOutput(results chan map[string]any, errCh chan error) error { var wg sync.WaitGroup wg.Add(1) diff --git a/sdk/template/loader.go b/sdk/template/loader.go index 1744d9a7..3040fed7 100644 --- a/sdk/template/loader.go +++ b/sdk/template/loader.go @@ -1,6 +1,9 @@ package template -import "os" +import ( + "os" + "path/filepath" +) type Loader struct { defaultTemplateContent []byte @@ -17,5 +20,5 @@ func (t *Loader) Load(path string) ([]byte, error) { return t.defaultTemplateContent, nil } - return os.ReadFile(path) + return os.ReadFile(filepath.Clean(path)) } diff --git a/sdk/transform/functions.go b/sdk/transform/functions.go index 2984a8f0..aa78362c 100644 --- a/sdk/transform/functions.go +++ b/sdk/transform/functions.go @@ -9,6 +9,7 @@ import ( "github.com/Masterminds/sprig/v3" "github.com/dongri/phonenumber" + "github.com/rs/zerolog/log" ) func customFunctions() template.FuncMap { @@ -25,7 +26,12 @@ func customFunctions() template.FuncMap { "phoneIso3166": phoneIso3166, "array_contains": func(a []interface{}, b string) bool { for _, x := range a { - if x.(string) == b { + stringX, ok := x.(string) + if !ok { + return false + } + + if stringX == b { return true } } @@ -57,14 +63,22 @@ func separator(s string) func() string { } } -func marshal(v interface{}) string { - a, _ := json.Marshal(v) +func marshal(v any) string { + a, err := json.Marshal(v) + if err != nil { + log.Error().Err(err).Msg("failed to marshal any") + } + return string(a) } func fromEnv(key, envName string) string { value := os.Getenv(envName) - strValue, _ := json.Marshal(value) + + strValue, err := json.Marshal(value) + if err != nil { + log.Error().Err(err).Msg("failed to marshal value") + } return fmt.Sprintf("%q:%s", key, string(strValue)) } diff --git a/sdk/transform/transform.go b/sdk/transform/transform.go index b8799b0d..724c281c 100644 --- a/sdk/transform/transform.go +++ b/sdk/transform/transform.go @@ -34,7 +34,12 @@ func (t *GoTemplateTransform) ExportTransform(outputWriter io.Writer) error { return nil } -func (t *GoTemplateTransform) Transform(ctx context.Context, ioReader io.Reader, outputWriter, errorWriter io.Writer) error { +func (t *GoTemplateTransform) Transform( + ctx context.Context, + ioReader io.Reader, + outputWriter, + errorWriter io.Writer, +) error { jsonWriter := js.NewJSONArrayWriter(outputWriter) defer jsonWriter.Close() @@ -44,15 +49,15 @@ func (t *GoTemplateTransform) Transform(ctx context.Context, ioReader io.Reader, } for { - var idpData map[string]interface{} + var idpData map[string]any err := reader.Read(&idpData) - if err == io.EOF { + if errors.Is(err, io.EOF) { break } if err != nil { - return errors.Wrap(err, "failed to read idpData into map[string]interface{}") + return errors.Wrap(err, "failed to read idpData into map[string]any") } if err := t.doTransform(idpData, jsonWriter); err != nil { @@ -63,7 +68,7 @@ func (t *GoTemplateTransform) Transform(ctx context.Context, ioReader io.Reader, return nil } -func (t *GoTemplateTransform) doTransform(idpData map[string]interface{}, jsonWriter *js.JSONArrayWriter) error { +func (t *GoTemplateTransform) doTransform(idpData map[string]any, jsonWriter *js.JSONArrayWriter) error { dirV3msg, err := t.TransformObject(idpData) if err != nil { return errors.Wrap(err, "failed to transform idpData into directory objects and relations") @@ -76,14 +81,16 @@ func (t *GoTemplateTransform) doTransform(idpData map[string]interface{}, jsonWr return nil } -func (t *GoTemplateTransform) TransformObject(idpData map[string]interface{}) (*msg.Transform, error) { +func (t *GoTemplateTransform) TransformObject(idpData map[string]any) (*msg.Transform, error) { output, err := t.transformToTemplate(idpData, string(t.template)) if err != nil { return nil, errors.Wrap(err, "GoTemplateTransform transformTemplate execute failed") } if os.Getenv("DEBUG") != "" { - os.Stdout.WriteString(output) + if _, err := os.Stdout.WriteString(output); err != nil { + return nil, errors.Wrap(err, "failed to write to stdout") + } } var dirV3msg msg.Transform @@ -100,7 +107,7 @@ func (t *GoTemplateTransform) TransformObject(idpData map[string]interface{}) (* return &dirV3msg, nil } -func (t *GoTemplateTransform) transformToTemplate(input map[string]interface{}, templateString string) (string, error) { +func (t *GoTemplateTransform) transformToTemplate(input map[string]any, templateString string) (string, error) { temp := template.New("GoTemplateTransform") parsed, err := temp.Funcs(customFunctions()).Parse(templateString) diff --git a/sdk/transform/transform_test.go b/sdk/transform/transform_test.go index 781ff5d1..d9cf462c 100644 --- a/sdk/transform/transform_test.go +++ b/sdk/transform/transform_test.go @@ -13,17 +13,18 @@ import ( "github.com/aserto-dev/ds-load/sdk/transform" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestTransform(t *testing.T) { // Arrange content, err := sdk.Assets().ReadFile("assets/peoplefinder.json") - assert.NoError(t, err) + require.NoError(t, err) contentReader := strings.NewReader(string(content)) template, err := sdk.Assets().ReadFile("assets/test_template.tmpl") - assert.NoError(t, err) + require.NoError(t, err) var transformBuffer bytes.Buffer writer := bufio.NewWriter(&transformBuffer) @@ -33,8 +34,9 @@ func TestTransform(t *testing.T) { // Act err = transformer.Transform(ctx, contentReader, writer, nil) - assert.NoError(t, err) - writer.Flush() + require.NoError(t, err) + err = writer.Flush() + require.NoError(t, err) // Assert bufLen := transformBuffer.Len() @@ -42,20 +44,20 @@ func TestTransform(t *testing.T) { reader := bufio.NewReader(&transformBuffer) _, err = reader.Read(transformOutput) - assert.NoError(t, err) + require.NoError(t, err) arrayReader, err := js.NewJSONArrayReader(bytes.NewReader(transformOutput)) - assert.NoError(t, err) + require.NoError(t, err) var directoryObj msg.Transform err = arrayReader.ReadProtoMessage(&directoryObj) - assert.NoError(t, err) + require.NoError(t, err) - objectCount := len(directoryObj.Objects) - assert.Equal(t, objectCount, 5) + objectCount := len(directoryObj.GetObjects()) + assert.Equal(t, 5, objectCount) - relationCount := len(directoryObj.Relations) - assert.Equal(t, relationCount, 2) + relationCount := len(directoryObj.GetRelations()) + assert.Equal(t, 2, relationCount) } func TestTransformEscapedChars(t *testing.T) { @@ -76,7 +78,7 @@ func TestTransformEscapedChars(t *testing.T) { ], "name": "oana+test666@aserto.com", "nickname": "oana+test666", - "picture": "https://s.gravatar.com/avatar/de191b7ce00efcc0cd07690f793c5186?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Foa.png", + "picture": "https://s.gravatar.com/avatar/de191b7ce00efcc0cd07690f793c5186?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Foa.png", "updated_at": "2023-06-30T12:47:52.762Z", "user_id": "auth0|64902b655c2e91cb3dee85a4", "user_metadata": { @@ -94,7 +96,7 @@ func TestTransformEscapedChars(t *testing.T) { content := []byte(auth0user) transformTemplate, err := sdk.Assets().ReadFile("assets/test_template.tmpl") - assert.NoError(t, err) + require.NoError(t, err) contentReader := strings.NewReader(string(content)) @@ -107,36 +109,37 @@ func TestTransformEscapedChars(t *testing.T) { // Act err = transformer.Transform(ctx, contentReader, writer, nil) - assert.NoError(t, err) - writer.Flush() + require.NoError(t, err) + err = writer.Flush() + require.NoError(t, err) // Assert bufLen := transformBuffer.Len() transformOutput := make([]byte, bufLen) reader := bufio.NewReader(&transformBuffer) _, err = reader.Read(transformOutput) - assert.NoError(t, err) + require.NoError(t, err) t.Log(transformOutput) arrayReader, err := js.NewJSONArrayReader(bytes.NewReader(transformOutput)) - assert.NoError(t, err) + require.NoError(t, err) var directoryObject msg.Transform err = arrayReader.ReadProtoMessage(&directoryObject) - assert.NoError(t, err) + require.NoError(t, err) - objectCount := len(directoryObject.Objects) - assert.Equal(t, objectCount, 2) + objectCount := len(directoryObject.GetObjects()) + assert.Equal(t, 2, objectCount) - relationCount := len(directoryObject.Relations) - assert.Equal(t, relationCount, 2) + relationCount := len(directoryObject.GetRelations()) + assert.Equal(t, 2, relationCount) - userObject := directoryObject.Objects[0] - assert.Equal(t, userObject.Type, "user") - assert.Equal(t, userObject.DisplayName, "oana+test666") + userObject := directoryObject.GetObjects()[0] + assert.Equal(t, "user", userObject.GetType()) + assert.Equal(t, "oana+test666", userObject.GetDisplayName()) - userEmail, ok := userObject.Properties.Fields["email"] + userEmail, ok := userObject.GetProperties().GetFields()["email"] assert.True(t, ok) - assert.Equal(t, userEmail.GetStringValue(), "oana+test666@aserto.com") + assert.Equal(t, "oana+test666@aserto.com", userEmail.GetStringValue()) }