Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BB-75] Coupa Connector #1

Merged
merged 10 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 36 additions & 56 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
- name: Run linters
uses: golangci/golangci-lint-action@v5
uses: golangci/golangci-lint-action@v6
with:
version: latest
args: --timeout=3m
go-test:
strategy:
matrix:
go-version: [1.22.x]
platform: [ubuntu-latest]
go-version: [ 1.22.x ]
platform: [ ubuntu-latest ]
runs-on: ${{ matrix.platform }}
steps:
- name: Install Go
Expand All @@ -37,68 +37,48 @@ jobs:
with:
test-results: test.json

test:
test-provisioning:
needs:
- go-lint
- go-test
runs-on: ubuntu-latest
# Define any services needed for the test suite (or delete this section)
# services:
# postgres:
# image: postgres:16
# ports:
# - "5432:5432"
# env:
# POSTGRES_PASSWORD: secretpassword
strategy:
fail-fast: true
matrix:
test-case: [ roles, groups, licenses ]

env:
BATON_LOG_LEVEL: debug
# Add any environment variables needed to run baton-coupa
# BATON_BASE_URL: 'http://localhost:8080'
# BATON_ACCESS_TOKEN: 'secret_token'
# The following parameters are passed to grant/revoke commands
# Change these to the correct IDs for your test data
CONNECTOR_GRANT: 'grant:entitlement:group:1234:member:user:9876'
CONNECTOR_ENTITLEMENT: 'entitlement:group:1234:member'
CONNECTOR_PRINCIPAL: 'user:9876'
CONNECTOR_PRINCIPAL_TYPE: 'user'

CONNECTOR_PRINCIPAL: "${{ secrets.CONNECTOR_PRINCIPAL }}"

BATON_COUPA_CLIENT_ID: "${{ secrets.BATON_COUPA_CLIENT_ID }}"
BATON_COUPA_CLIENT_SECRET: "${{ secrets.BATON_COUPA_CLIENT_SECRET }}"
BATON_COUPA_DOMAIN: "${{ secrets.BATON_COUPA_DOMAIN }}"

BATON_CONNECTOR: ./baton-coupa

steps:
- name: Install Go
uses: actions/setup-go@v5
with:
go-version: 1.22.x
- name: Checkout code
uses: actions/checkout@v4
# Install any dependencies here (or delete this)
# - name: Install postgres client
# run: sudo apt install postgresql-client
# Run any fixture setup here (or delete this)
# - name: Import sql into postgres
# run: psql -h localhost --user postgres -f environment.sql
# env:
# PGPASSWORD: secretpassword
- name: Build baton-coupa
run: go build ./cmd/baton-coupa
- name: Run baton-coupa
run: ./baton-coupa

- name: Install baton
run: ./scripts/get-baton.sh && mv baton /usr/local/bin

- name: Check for grant before revoking

run:
baton grants --entitlement="${{ env.CONNECTOR_ENTITLEMENT }}" --output-format=json | jq --exit-status ".grants[].principal.id.resource == \"${{ env.CONNECTOR_PRINCIPAL }}\""


- name: Revoke grants
run: ./baton-coupa --revoke-grant="${{ env.CONNECTOR_GRANT }}"

- name: Check grant was revoked
run: ./baton-coupa && baton grants --entitlement="${{ env.CONNECTOR_ENTITLEMENT }}" --output-format=json | jq --exit-status "if .grants then .grants[]?.principal.id.resource != \"${{ env.CONNECTOR_PRINCIPAL }}\" else . end"

- name: Grant entitlement
# Change the grant arguments to the correct IDs for your test data
run: ./baton-coupa --grant-entitlement="${{ env.CONNECTOR_ENTITLEMENT }}" --grant-principal="${{ env.CONNECTOR_PRINCIPAL }}" --grant-principal-type="${{ env.CONNECTOR_PRINCIPAL_TYPE }}"

- name: Check grant was re-granted

run:
baton grants --entitlement="${{ env.CONNECTOR_ENTITLEMENT }}" --output-format=json | jq --exit-status ".grants[].principal.id.resource == \"${{ env.CONNECTOR_PRINCIPAL }}\""

- name: Build baton-coupa
run: go build ./cmd/baton-coupa
- name: Run tests for ${{ matrix.test-case }}
run: |
case "${{ matrix.test-case }}" in
"roles")
./scripts/validate-grant.sh ${{ env.CONNECTOR_PRINCIPAL }} user role:4:member role:4:member:user:${{ env.CONNECTOR_PRINCIPAL }}
;;
"groups")
./scripts/validate-grant.sh ${{ env.CONNECTOR_PRINCIPAL }} user group:2:member group:2:member:user:${{ env.CONNECTOR_PRINCIPAL }}
;;
"licenses")
./scripts/validate-grant.sh ${{ env.CONNECTOR_PRINCIPAL }} user license:treasury_user:assigned license:treasury_user:assigned:user:${{ env.CONNECTOR_PRINCIPAL }}
;;
esac
2 changes: 1 addition & 1 deletion .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
- name: Run linters
uses: golangci/golangci-lint-action@v5
uses: golangci/golangci-lint-action@v6
with:
version: latest
args: --timeout=3m
Expand Down
3 changes: 1 addition & 2 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ linters-settings:
rules:
- name: atomic
- name: line-length-limit
arguments: [ 200 ]
arguments: [ 250 ]
# These are functions that we use without checking the errors often. Most of these can't return an error even
# though they implement an interface that can.
- name: unhandled-error
Expand Down Expand Up @@ -71,7 +71,6 @@ linters:
- durationcheck # check for two durations multiplied together
- errorlint # errorlint is a linter for that can be used to find code that will cause problems with the error wrapping scheme introduced in Go 1.13.
- exhaustive # check exhaustiveness of enum switch statements
- exportloopref # checks for pointers to enclosing loop variables
- forbidigo # Forbids identifiers
- gochecknoinits # Checks that no init functions are present in Go code
- goconst # Finds repeated strings that could be replaced by a constant
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
![Baton Logo](./docs/images/baton-logo.png)

# `baton-coupa` [![Go Reference](https://pkg.go.dev/badge/github.com/conductorone/baton-coupa.svg)](https://pkg.go.dev/github.com/conductorone/baton-coupa) ![main ci](https://github.com/conductorone/baton-coupa/actions/workflows/main.yaml/badge.svg)
#
`baton-coupa` [![Go Reference](https://pkg.go.dev/badge/github.com/conductorone/baton-coupa.svg)](https://pkg.go.dev/github.com/conductorone/baton-coupa) ![main ci](https://github.com/conductorone/baton-coupa/actions/workflows/main.yaml/badge.svg)

`baton-coupa` is a connector for built using the [Baton SDK](https://github.com/conductorone/baton-sdk).

Check out [Baton](https://github.com/conductorone/baton) to learn more the project in general.

# Getting Started

- [Coupa docs](https://compass.coupa.com/en-us/products/core-platform/integration-playbooks-and-resources/integration-knowledge-articles/postman-collection-for-coupa-apis)
- [Coupa GraphQL](https://compass.coupa.com/en-us/products/product-documentation/integration-technical-documentation/the-coupa-core-api/get-started-with-the-api/introducing-graphql)

## brew

```
Expand Down Expand Up @@ -37,6 +41,7 @@ baton resources
# Data Model

`baton-coupa` will pull down information about the following resources:

- Users

# Contributing, Support and Issues
Expand Down
29 changes: 0 additions & 29 deletions cmd/baton-coupa/config.go

This file was deleted.

21 changes: 0 additions & 21 deletions cmd/baton-coupa/config_test.go

This file was deleted.

24 changes: 15 additions & 9 deletions cmd/baton-coupa/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,29 @@ import (
"fmt"
"os"

coppaConfig "github.com/conductorone/baton-coupa/pkg/config"
"github.com/conductorone/baton-coupa/pkg/connector"
"github.com/conductorone/baton-sdk/pkg/config"
"github.com/conductorone/baton-sdk/pkg/connectorbuilder"
"github.com/conductorone/baton-sdk/pkg/field"
"github.com/conductorone/baton-sdk/pkg/types"
"github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap"
"github.com/spf13/viper"
"github.com/conductorone/baton-coupa/pkg/connector"
"go.uber.org/zap"
)

var version = "dev"
var (
connectorName = "baton-coupa"
version = "dev"
)

func main() {
ctx := context.Background()

_, cmd, err := config.DefineConfiguration(
ctx,
"baton-coupa",
connectorName,
getConnector,
field.Configuration{
Fields: ConfigurationFields,
},
coppaConfig.ConfigurationSchema,
)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
Expand All @@ -44,11 +45,16 @@ func main() {

func getConnector(ctx context.Context, v *viper.Viper) (types.ConnectorServer, error) {
l := ctxzap.Extract(ctx)
if err := ValidateConfig(ctx, v); err != nil {
if err := coppaConfig.ValidateConfig(v); err != nil {
return nil, err
}

cb, err := connector.New(ctx)
cb, err := connector.New(
ctx,
v.GetString(coppaConfig.CoupaDomain.FieldName),
v.GetString(coppaConfig.ClientIdField.FieldName),
v.GetString(coppaConfig.ClientSecretField.FieldName),
)
if err != nil {
l.Error("error creating connector", zap.Error(err))
return nil, err
Expand Down
10 changes: 6 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ module github.com/conductorone/baton-coupa
go 1.22.7

require (
github.com/conductorone/baton-sdk v0.2.31
github.com/conductorone/baton-sdk v0.2.58
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.9.0
go.uber.org/zap v1.27.0
golang.org/x/oauth2 v0.23.0
)

require (
filippo.io/age v1.1.1 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/allegro/bigcache/v3 v3.1.0 // indirect
github.com/aws/aws-sdk-go-v2 v1.26.1 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2 // indirect
github.com/aws/aws-sdk-go-v2/config v1.27.11 // indirect
Expand All @@ -35,10 +36,12 @@ require (
github.com/benbjohnson/clock v1.3.5 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/deckarep/golang-set/v2 v2.6.0 // indirect
github.com/dolthub/maphash v0.1.0 // indirect
github.com/doug-martin/goqu/v9 v9.19.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/envoyproxy/protoc-gen-validate v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/gammazero/deque v0.2.1 // indirect
github.com/glebarez/go-sqlite v1.22.0 // indirect
github.com/go-jose/go-jose/v3 v3.0.3 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
Expand All @@ -51,6 +54,7 @@ require (
github.com/lufia/plan9stats v0.0.0-20240408141607-282e7b5d6b74 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/maypok86/otter v1.2.4 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
Expand All @@ -68,7 +72,6 @@ require (
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/cobra v1.8.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/testify v1.9.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/tklauser/go-sysconf v0.3.14 // indirect
github.com/tklauser/numcpus v0.8.0 // indirect
Expand All @@ -80,7 +83,6 @@ require (
golang.org/x/crypto v0.24.0 // indirect
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
golang.org/x/net v0.26.0 // indirect
golang.org/x/oauth2 v0.20.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.21.0 // indirect
golang.org/x/text v0.16.0 // indirect
Expand Down
Loading
Loading