Skip to content

Commit

Permalink
Merge pull request #1 from ConductorOne/goldschmidt/workato-connector
Browse files Browse the repository at this point in the history
Implement baton-workato Connector
  • Loading branch information
ggreer authored Jan 17, 2025
2 parents de1b6e0 + cca67dc commit dbec6de
Show file tree
Hide file tree
Showing 43 changed files with 3,111 additions and 149 deletions.
77 changes: 25 additions & 52 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ jobs:
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,41 @@ 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 ]

env:
BATON_LOG_LEVEL: debug
# Add any environment variables needed to run baton-workato
# 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_WORKATO_API_KEY: ${{ secrets.BATON_WORKATO_API_KEY }}
BATON_CONNECTOR: ./baton-workato
BATON_WORKATO_ENV: dev

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-workato
run: go build ./cmd/baton-workato
- name: Run baton-workato
run: ./baton-workato

- 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-workato --revoke-grant="${{ env.CONNECTOR_GRANT }}"

- name: Check grant was revoked
run: ./baton-workato && 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-workato --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-workato
run: go build ./cmd/baton-workato

- name: Run tests for ${{ matrix.test-case }}
run: |
case "${{ matrix.test-case }}" in
"roles")
BATON_SKIP_REVOKE=1 ./scripts/validate-grant.sh ${{ env.CONNECTOR_PRINCIPAL }} collaborator role:Operator:collaborator-has role:Operator:collaborator-has:collaborator:${{ env.CONNECTOR_PRINCIPAL }}
;;
esac
2 changes: 1 addition & 1 deletion .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: [ 300 ]
# 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
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
![Baton Logo](./baton-logo.png)

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

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

`baton-workato` 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

## Prerequisites

You need to pass the workato-api-key:

1. Create an Workato Account.
2. Create an API KEY https://app.workato.com/members/api/clients.
3. Run it.

Obs: if you have a basic account, you can ignore the subusers using.

## brew

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

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

- Users

# Contributing, Support and Issues
Expand Down Expand Up @@ -69,9 +82,10 @@ Flags:
-h, --help help for baton-workato
--log-format string The output format for logs: json, console ($BATON_LOG_FORMAT) (default "json")
--log-level string The log level: debug, info, warn, error ($BATON_LOG_LEVEL) (default "info")
-p, --provisioning If this connector supports provisioning, this must be set in order for provisioning actions to be enabled ($BATON_PROVISIONING)
-p, --provisioning This must be set in order for provisioning actions to be enabled ($BATON_PROVISIONING)
--skip-full-sync This must be set to skip a full sync ($BATON_SKIP_FULL_SYNC)
--ticketing This must be set to enable ticketing support ($BATON_TICKETING)
-v, --version version for baton-workato
Use "baton-workato [command] --help" for more information about a command.
--workato-api-key string required: Your workato API key ($BATON_WORKATO_API_KEY)
--workato-data-center string Your workato data center (us, eu, jp, sg, au) default is 'us' see more on https://docs.workato.com/workato-api.html#base-url ($BATON_WORKATO_DATA_CENTER) (default "us")
```
57 changes: 48 additions & 9 deletions baton_capabilities.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,60 @@
{
"@type": "type.googleapis.com/c1.connector.v2.ConnectorCapabilities",
"resourceTypeCapabilities": [
"@type": "type.googleapis.com/c1.connector.v2.ConnectorCapabilities",
"resourceTypeCapabilities": [
{
"resourceType": {
"id": "user",
"displayName": "User",
"traits": [
"resourceType": {
"id": "collaborator",
"displayName": "Collaborator",
"traits": [
"TRAIT_USER"
]
},
"capabilities": [
"capabilities": [
"CAPABILITY_SYNC"
]
},
{
"resourceType": {
"id": "folder",
"displayName": "Folder"
},
"capabilities": [
"CAPABILITY_SYNC"
]
},
{
"resourceType": {
"id": "privilege",
"displayName": "Privilege"
},
"capabilities": [
"CAPABILITY_SYNC"
]
},
{
"resourceType": {
"id": "project",
"displayName": "Project"
},
"capabilities": [
"CAPABILITY_SYNC"
]
},
{
"resourceType": {
"id": "role",
"displayName": "Roles",
"traits": [
"TRAIT_ROLE"
]
},
"capabilities": [
"CAPABILITY_SYNC"
]
}
],
"connectorCapabilities": [
"connectorCapabilities": [
"CAPABILITY_SYNC"
],
"credentialDetails": {}
"credentialDetails": {}
}
63 changes: 63 additions & 0 deletions cmd/baton-workato/conf/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package conf

import (
"errors"

"github.com/conductorone/baton-workato/pkg/connector/workato"

"github.com/conductorone/baton-sdk/pkg/field"
"github.com/conductorone/baton-workato/pkg/connector/client"
"github.com/spf13/viper"
)

var (
ApiKeyField = field.StringField(
"workato-api-key",
field.WithRequired(true),
field.WithDescription("Your workato API key"),
)

WorkatoDataCenterFiekd = field.StringField(
"workato-data-center",
field.WithDescription("Your workato data center (us, eu, jp, sg, au) default is 'us' see more on https://docs.workato.com/workato-api.html#base-url"),
field.WithDefaultValue("us"),
)

WorkatoEnv = field.StringField(
"workato-env",
field.WithDescription("Your workato environment (dev, test, prod) default is 'dev'"),
field.WithDefaultValue("dev"),
)

// ConfigurationFields defines the external configuration required for the
// connector to run. Note: these fields can be marked as optional or
// required.
ConfigurationFields = []field.SchemaField{
ApiKeyField,
WorkatoDataCenterFiekd,
WorkatoEnv,
}

// FieldRelationships defines relationships between the fields listed in
// ConfigurationFields that can be automatically validated. For example, a
// username and password can be required together, or an access token can be
// marked as mutually exclusive from the username password pair.
FieldRelationships = []field.SchemaFieldRelationship{}
)

// ValidateConfig is run after the configuration is loaded, and should return an
// error if it isn't valid. Implementing this function is optional, it only
// needs to perform extra validations that cannot be encoded with configuration
// parameters.
func ValidateConfig(v *viper.Viper) error {
if _, ok := client.WorkatoDataCenters[v.GetString(WorkatoDataCenterFiekd.FieldName)]; !ok {
return errors.New("invalid workato data center")
}

_, err := workato.EnvFromString(v.GetString(WorkatoEnv.FieldName))
if err != nil {
return err
}

return nil
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package conf

import (
"testing"
Expand Down
27 changes: 0 additions & 27 deletions cmd/baton-workato/config.go

This file was deleted.

27 changes: 23 additions & 4 deletions cmd/baton-workato/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,19 @@ import (
"fmt"
"os"

"github.com/conductorone/baton-workato/pkg/connector/workato"

"github.com/conductorone/baton-workato/cmd/baton-workato/conf"

"github.com/conductorone/baton-workato/pkg/connector/client"

"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/conductorone/baton-workato/pkg/connector"
"github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap"
"github.com/spf13/viper"
"github.com/conductorone/baton-workato/pkg/connector"
"go.uber.org/zap"
)

Expand All @@ -25,7 +31,7 @@ func main() {
"baton-workato",
getConnector,
field.Configuration{
Fields: ConfigurationFields,
Fields: conf.ConfigurationFields,
},
)
if err != nil {
Expand All @@ -44,11 +50,24 @@ func main() {

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

key := v.GetString(conf.ApiKeyField.FieldName)
dataCenterUrl := client.WorkatoDataCenters[v.GetString(conf.WorkatoDataCenterFiekd.FieldName)]

env, err := workato.EnvFromString(v.GetString(conf.WorkatoEnv.FieldName))
if err != nil {
return nil, err
}

workatoClient, err := client.NewWorkatoClient(ctx, key, dataCenterUrl)
if err != nil {
return nil, err
}

cb, err := connector.New(ctx)
cb, err := connector.New(ctx, workatoClient, env)
if err != nil {
l.Error("error creating connector", zap.Error(err))
return nil, err
Expand Down
Loading

0 comments on commit dbec6de

Please sign in to comment.