├── .errcheck-exclusions.txt ├── .gitignore ├── .golangci.yml ├── .goreleaser.yml ├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── cmd ├── genpostmanctldocs │ └── main.go └── postmanctl │ └── main.go ├── configs └── example.postmanctl.yaml ├── doc ├── postmanctl.md ├── postmanctl_config.md ├── postmanctl_config_current-context.md ├── postmanctl_config_get-contexts.md ├── postmanctl_config_set-context.md ├── postmanctl_config_use-context.md ├── postmanctl_create.md ├── postmanctl_create_api-version.md ├── postmanctl_create_api.md ├── postmanctl_create_collection.md ├── postmanctl_create_environment.md ├── postmanctl_create_mock.md ├── postmanctl_create_monitor.md ├── postmanctl_create_schema.md ├── postmanctl_create_workspace.md ├── postmanctl_delete.md ├── postmanctl_delete_api-version.md ├── postmanctl_delete_api.md ├── postmanctl_delete_collection.md ├── postmanctl_delete_environment.md ├── postmanctl_delete_mock.md ├── postmanctl_delete_monitor.md ├── postmanctl_delete_schema.md ├── postmanctl_delete_workspace.md ├── postmanctl_describe.md ├── postmanctl_describe_api-relations.md ├── postmanctl_describe_api-versions.md ├── postmanctl_describe_apis.md ├── postmanctl_describe_collections.md ├── postmanctl_describe_environments.md ├── postmanctl_describe_mocks.md ├── postmanctl_describe_monitors.md ├── postmanctl_describe_schema.md ├── postmanctl_describe_user.md ├── postmanctl_describe_workspaces.md ├── postmanctl_fork.md ├── postmanctl_fork_collection.md ├── postmanctl_get.md ├── postmanctl_get_api-relations.md ├── postmanctl_get_api-versions.md ├── postmanctl_get_apis.md ├── postmanctl_get_collections.md ├── postmanctl_get_environments.md ├── postmanctl_get_mocks.md ├── postmanctl_get_monitors.md ├── postmanctl_get_schema.md ├── postmanctl_get_user.md ├── postmanctl_get_workspaces.md ├── postmanctl_merge.md ├── postmanctl_merge_collection.md ├── postmanctl_replace.md ├── postmanctl_replace_api-version.md ├── postmanctl_replace_api.md ├── postmanctl_replace_collection.md ├── postmanctl_replace_environment.md ├── postmanctl_replace_mock.md ├── postmanctl_replace_monitor.md ├── postmanctl_replace_schema.md ├── postmanctl_replace_workspace.md ├── postmanctl_run.md ├── postmanctl_run_monitor.md └── postmanctl_version.md ├── examples ├── find-orphan-collections │ └── find-orphan-collections.sh ├── go-template │ ├── convert-to-jmeter.sh │ ├── jmeter.tmpl │ └── openapi3.tmpl ├── iterate-over-environments │ └── find-environment-with-key.sh └── spectral-linting │ └── lint-api-from-postman.sh ├── go.mod ├── go.sum ├── internal └── runtime │ ├── cmd │ ├── config.go │ ├── create.go │ ├── delete.go │ ├── describe.go │ ├── fork.go │ ├── get.go │ ├── merge.go │ ├── replace.go │ ├── root.go │ ├── run.go │ ├── util.go │ └── version.go │ └── config │ └── config.go ├── output └── .gitkeep ├── pkg └── sdk │ ├── client │ ├── options.go │ ├── request.go │ └── request_test.go │ ├── helpers_test.go │ ├── printers │ ├── printers.go │ ├── tableprinter.go │ └── tableprinter_test.go │ ├── resources │ ├── apirelations.go │ ├── apis.go │ ├── apiversions.go │ ├── collections.go │ ├── environments.go │ ├── error.go │ ├── gen │ │ └── collection.go │ ├── itemtree.go │ ├── mocks.go │ ├── monitors.go │ ├── resources.go │ ├── schema.go │ ├── user.go │ └── workspaces.go │ ├── service.go │ ├── servicecreate.go │ ├── servicecreate_test.go │ ├── servicedelete.go │ ├── servicedelete_test.go │ ├── servicefork.go │ ├── servicefork_test.go │ ├── serviceget.go │ ├── serviceget_test.go │ ├── servicereplace.go │ ├── servicereplace_test.go │ ├── servicerun.go │ └── servicerun_test.go └── schema └── collection.schema.json /.errcheck-exclusions.txt: -------------------------------------------------------------------------------- 1 | (*github.com/spf13/cobra.Command).MarkFlagRequired 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | output 2 | dist 3 | coverage.txt 4 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | linters-settings: 2 | errcheck: 3 | exclude: ./.errcheck-exclusions.txt 4 | gocyclo: 5 | min-complexity: 21 # 21-50 = High Risk 6 | 7 | linters: 8 | enable: 9 | - gofmt 10 | - gocyclo 11 | - misspell 12 | - testpackage 13 | - gosec 14 | disable-all: false -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | before: 2 | hooks: 3 | - go mod download 4 | builds: 5 | - env: 6 | - CGO_ENABLED=0 7 | main: ./cmd/postmanctl/main.go 8 | goos: 9 | - linux 10 | - windows 11 | - darwin 12 | ldflags: 13 | - -s -w -X "github.com/kevinswiber/postmanctl/internal/runtime/cmd.version=v{{.Version}}" 14 | - -X "github.com/kevinswiber/postmanctl/internal/runtime/cmd.commit={{.ShortCommit}}" 15 | - -X "github.com/kevinswiber/postmanctl/internal/runtime/cmd.date={{.Date}}" 16 | brews: 17 | - name: postmanctl 18 | custom_block: | 19 | head do 20 | url "https://github.com/kevinswiber/postmanctl.git" 21 | depends_on "go" 22 | end 23 | install: | 24 | if head? 25 | system "go", "build", "./cmd/postmanctl" 26 | end 27 | 28 | bin.install "postmanctl" 29 | github: 30 | owner: kevinswiber 31 | name: homebrew-postmanctl 32 | commit_author: 33 | name: Kevin Swiber 34 | email: kswiber@gmail.com 35 | folder: Formula 36 | homepage: https://github.com/kevinswiber/postmanctl 37 | archives: 38 | - replacements: 39 | darwin: Darwin 40 | linux: Linux 41 | windows: Windows 42 | 386: i386 43 | amd64: x86_64 44 | checksum: 45 | name_template: 'checksums.txt' 46 | snapshot: 47 | name_template: "{{ .Tag }}-next" 48 | changelog: 49 | sort: asc 50 | filters: 51 | exclude: 52 | - '^docs:' 53 | - '^test:' 54 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.14.x 5 | 6 | before_script: 7 | - curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.27.0 8 | 9 | script: 10 | - make test 11 | 12 | after_success: 13 | - bash <(curl -s https://codecov.io/bash) -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | build: 3 | GITBRANCH=$(shell git rev-parse --abbrev-ref HEAD); \ 4 | GITCOMMIT=$(shell git rev-parse --short HEAD); \ 5 | DATE=$(shell date -u +%Y-%m-%dT%H:%M:%SZ); \ 6 | GOVERSION=$(shell go version | awk '{print $$3}'); \ 7 | GOPLATFORM=$(shell go version | awk '{print $$4}'); \ 8 | go build -ldflags "-s -w \ 9 | -X github.com/kevinswiber/postmanctl/internal/runtime/cmd.version=v0.1.0-dev.$$GITBRANCH+$$GITCOMMIT \ 10 | -X github.com/kevinswiber/postmanctl/internal/runtime/cmd.commit=$$GITCOMMIT \ 11 | -X github.com/kevinswiber/postmanctl/internal/runtime/cmd.date=$$DATE \ 12 | -X github.com/kevinswiber/postmanctl/internal/runtime/cmd.goVersion=$$GOVERSION \ 13 | -X github.com/kevinswiber/postmanctl/internal/runtime/cmd.platform=$$GOPLATFORM \ 14 | " -o ./output/postmanctl ./cmd/postmanctl 15 | 16 | test: lint 17 | go test -v -race -coverprofile=coverage.txt -covermode=atomic ./... 18 | 19 | lint: 20 | golangci-lint run 21 | 22 | generate: 23 | go generate ./... 24 | 25 | release: 26 | GOVERSION=$(shell go version | awk '{print $$3}'); \ 27 | GOPLATFORM=$(shell go version | awk '{print $$4}'); \ 28 | goreleaser --rm-dist 29 | 30 | release-snapshot: 31 | GOVERSION=$(shell go version | awk '{print $$3}'); \ 32 | GOPLATFORM=$(shell go version | awk '{print $$4}'); \ 33 | goreleaser --snapshot --skip-publish --rm-dist 34 | 35 | install: 36 | go install ./cmd/postmanctl 37 | 38 | doc: 39 | go build -o ./output/genpostmanctldocs ./cmd/genpostmanctldocs 40 | ./output/genpostmanctldocs 41 | 42 | .PHONY: generate build install doc release release-snapshot lint -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # postmanctl 2 | 3 | [![go.dev reference](https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/github.com/kevinswiber/postmanctl) [![Build Status](https://travis-ci.com/kevinswiber/postmanctl.svg?branch=main)](https://travis-ci.com/kevinswiber/postmanctl) 4 | 5 | A command-line interface to the [Postman API](https://docs.api.getpostman.com/). 6 | 7 | ## Usage 8 | 9 | ``` 10 | Controls the Postman API 11 | 12 | Usage: 13 | postmanctl [command] 14 | 15 | Available Commands: 16 | config Configure access to the Postman API. 17 | create Create new Postman resources. 18 | delete Delete existing Postman resources. 19 | describe Describe an entity in the Postman API 20 | fork Create a fork of a Postman resource. 21 | get Retrieve Postman resources. 22 | help Help about any command 23 | merge Merge a fork of a Postman resource. 24 | replace Replace existing Postman resources. 25 | run Execute runnable Postman resources. 26 | version Print version information for postmanctl. 27 | 28 | Flags: 29 | --config string config file (default is $HOME/.postmanctl.yaml) 30 | --context string context to use, overrides the current context in the config file 31 | -h, --help help for postmanctl 32 | 33 | Use "postmanctl [command] --help" for more information about a command. 34 | ``` 35 | 36 | ## Install 37 | 38 | ### Download binary 39 | 40 | Binaries for Windows, MacOS, and Linux can be downloaded from the GitHub releases page: https://github.com/kevinswiber/postmanctl/releases. 41 | 42 | ### Homebrew 43 | 44 | Homebrew users can install `postmanctl` from the `kevinswiber/postmanctl` tap: 45 | 46 | ``` 47 | $ brew install kevinswiber/postmanctl/postmanctl 48 | ``` 49 | 50 | ### Using `go get` 51 | 52 | ``` 53 | $ go get -u github.com/kevinswiber/postmanctl/cmd/postmanctl 54 | ``` 55 | 56 | ### From source: 57 | 58 | Download and install from source. 59 | 60 | ``` 61 | $ git clone https://github.com/kevinswiber/postmanctl.git && make install 62 | ``` 63 | 64 | ## Getting started 65 | 66 | ### Configuring access 67 | 68 | To start using `postmanctl`, configure access to your Postman account. 69 | 70 | ``` 71 | $ postmanctl config set-context 72 | ``` 73 | 74 | You'll need a Postman API Key to add to your configuration, which can be generated here: https://go.postman.co/settings/me/api-keys. 75 | 76 | Example: 77 | 78 | ``` 79 | $ postmanctl config set-context personal 80 | Postman API Key: 81 | config file written to $HOME/.postmanctl.yaml 82 | ``` 83 | 84 | You're now ready to start using `postmanctl`! 85 | 86 | ### Fetching a list of Postman collections 87 | 88 | Now that access to the Postman API has been configured, you can start playing around with different commands. 89 | 90 | Fetch a list of Postman collections. 91 | 92 | ``` 93 | $ postmanctl get collections 94 | UID NAME 95 | 10354132-0a428e3b-4112-46ee-b57a-d2f3e1b7c860 httpbin 96 | 10354132-22f0b9af-83e6-4f4a-b14a-879342f3e582 Using data files 97 | 10354132-e02524dc-54d5-49d7-9ef8-121209316083 Demo API 98 | ``` 99 | 100 | ### Get more information about a collection 101 | 102 | ``` 103 | $ postmanctl describe collection 10354132-e02524dc-54d5-49d7-9ef8-121209316083 104 | Info: 105 | ID: e02524dc-54d5-49d7-9ef8-121209316083 106 | Name: Demo API 107 | Schema: https://schema.getpostman.com/json/collection/v2.1.0/collection.json 108 | Scripts: 109 | PreRequest: true 110 | Test: true 111 | Variables: baseUrl 112 | Items: 113 | . 114 | └── Weather Forecast 115 | ├── Get Weather Forecast (scripts: prerequest,test) 116 | └── Create Weather Forecast (scripts: prerequest,test) 117 | ``` 118 | 119 | ### Create a mock server 120 | 121 | You can create resources by piping in a JSON object describing that resource or by passing in a file with the `--filename` flag. 122 | 123 | ``` 124 | $ cat << EOF | postmanctl create mock 125 | { 126 | "name": "demo-api-mock", 127 | "collection": "10354132-e02524dc-54d5-49d7-9ef8-121209316083", 128 | "environment": "10354132-84e7635f-9b30-427f-bead-27901790659e" 129 | } 130 | EOF 131 | 132 | 10354132-588394be-63e5-4194-828c-4439fee85ca8 133 | ``` 134 | 135 | The ID of the newly created resource is returned. 136 | 137 | You can check the new resource by running: 138 | 139 | ``` 140 | $ postmanctl describe mock 10354132-588394be-63e5-4194-828c-4439fee85ca8 141 | ``` 142 | 143 | ### Using a custom JSONPath output to filter results 144 | 145 | Now that we have a mock server, let's run a command to get its public URL. 146 | 147 | ``` 148 | $ postmanctl get mock 10354132-588394be-63e5-4194-828c-4439fee85ca8 -o jsonpath="{[].mockUrl}" 149 | https://588394be-63e5-4194-828c-4439fee85ca8.mock.pstmn.io 150 | ``` 151 | 152 | Now that we have our mock server URL, we can start making requests. 153 | 154 | ``` 155 | $ curl https://588394be-63e5-4194-828c-4439fee85ca8.mock.pstmn.io/WeatherForecast 156 | [ 157 | { 158 | "date": "", 159 | "temperatureC": "", 160 | "temperatureF": "", 161 | "summary": "" 162 | }, 163 | { 164 | "date": "", 165 | "temperatureC": "", 166 | "temperatureF": "", 167 | "summary": "" 168 | } 169 | ]% 170 | ``` 171 | 172 | ## Learning more 173 | 174 | Feel free to peruse the auto-generated [CLI docs](doc/postmanctl.md) to learn more about the commands or just explore with `postmanctl --help`. 175 | 176 | JSONPath syntax is borrowed from the implementation used by the Kubernetes CLI. You can find more documentation on that in the `kubectl` documentation: https://kubernetes.io/docs/reference/kubectl/jsonpath/. 177 | 178 | ## License 179 | 180 | Apache License 2.0 (Apache-2.0) 181 | 182 | Copyright © 2020 Kevin Swiber 183 | -------------------------------------------------------------------------------- /cmd/genpostmanctldocs/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "fmt" 21 | "os" 22 | 23 | "github.com/kevinswiber/postmanctl/internal/runtime/cmd" 24 | ) 25 | 26 | func main() { 27 | err := cmd.GenMarkdownTree("./doc") 28 | if err != nil { 29 | fmt.Fprint(os.Stderr, err.Error()) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /cmd/postmanctl/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import "github.com/kevinswiber/postmanctl/internal/runtime/cmd" 20 | 21 | func main() { 22 | cmd.Execute() 23 | } 24 | -------------------------------------------------------------------------------- /configs/example.postmanctl.yaml: -------------------------------------------------------------------------------- 1 | currentContext: personal # Required 2 | contexts: 3 | personal: 4 | apiKey: XXXXXXXXXXXXXX # Required 5 | apiRoot: https://api.postman.com # Optional 6 | workspace: 12345-67890-12345-67890 # Optional 7 | -------------------------------------------------------------------------------- /doc/postmanctl.md: -------------------------------------------------------------------------------- 1 | ## postmanctl 2 | 3 | Controls the Postman API 4 | 5 | ### Synopsis 6 | 7 | Controls the Postman API 8 | 9 | ### Options 10 | 11 | ``` 12 | --config string config file (default is $HOME/.postmanctl.yaml) 13 | --context string context to use, overrides the current context in the config file 14 | -h, --help help for postmanctl 15 | ``` 16 | 17 | ### SEE ALSO 18 | 19 | * [postmanctl config](postmanctl_config.md) - Configure access to the Postman API. 20 | * [postmanctl create](postmanctl_create.md) - Create new Postman resources. 21 | * [postmanctl delete](postmanctl_delete.md) - Delete existing Postman resources. 22 | * [postmanctl describe](postmanctl_describe.md) - Describe an entity in the Postman API 23 | * [postmanctl fork](postmanctl_fork.md) - Create a fork of a Postman resource. 24 | * [postmanctl get](postmanctl_get.md) - Retrieve Postman resources. 25 | * [postmanctl merge](postmanctl_merge.md) - Merge a fork of a Postman resource. 26 | * [postmanctl replace](postmanctl_replace.md) - Replace existing Postman resources. 27 | * [postmanctl run](postmanctl_run.md) - Execute runnable Postman resources. 28 | * [postmanctl version](postmanctl_version.md) - Print version information for postmanctl. 29 | 30 | ###### Auto generated by spf13/cobra on 13-May-2020 31 | -------------------------------------------------------------------------------- /doc/postmanctl_config.md: -------------------------------------------------------------------------------- 1 | ## postmanctl config 2 | 3 | Configure access to the Postman API. 4 | 5 | ### Synopsis 6 | 7 | Configure access to the Postman API. 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for config 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --config string config file (default is $HOME/.postmanctl.yaml) 19 | --context string context to use, overrides the current context in the config file 20 | ``` 21 | 22 | ### SEE ALSO 23 | 24 | * [postmanctl](postmanctl.md) - Controls the Postman API 25 | * [postmanctl config current-context](postmanctl_config_current-context.md) - Get the currently set context for postmanctl commands. 26 | * [postmanctl config get-contexts](postmanctl_config_get-contexts.md) - Shows the list of configured contexts. 27 | * [postmanctl config set-context](postmanctl_config_set-context.md) - Create a context for accessing the Postman API. 28 | * [postmanctl config use-context](postmanctl_config_use-context.md) - Use an existing context for postmanctl commands. 29 | 30 | ###### Auto generated by spf13/cobra on 13-May-2020 31 | -------------------------------------------------------------------------------- /doc/postmanctl_config_current-context.md: -------------------------------------------------------------------------------- 1 | ## postmanctl config current-context 2 | 3 | Get the currently set context for postmanctl commands. 4 | 5 | ### Synopsis 6 | 7 | Get the currently set context for postmanctl commands. 8 | 9 | ``` 10 | postmanctl config current-context [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for current-context 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [postmanctl config](postmanctl_config.md) - Configure access to the Postman API. 29 | 30 | ###### Auto generated by spf13/cobra on 13-May-2020 31 | -------------------------------------------------------------------------------- /doc/postmanctl_config_get-contexts.md: -------------------------------------------------------------------------------- 1 | ## postmanctl config get-contexts 2 | 3 | Shows the list of configured contexts. 4 | 5 | ### Synopsis 6 | 7 | Shows the list of configured contexts. 8 | 9 | ``` 10 | postmanctl config get-contexts [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for get-contexts 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [postmanctl config](postmanctl_config.md) - Configure access to the Postman API. 29 | 30 | ###### Auto generated by spf13/cobra on 13-May-2020 31 | -------------------------------------------------------------------------------- /doc/postmanctl_config_set-context.md: -------------------------------------------------------------------------------- 1 | ## postmanctl config set-context 2 | 3 | Create a context for accessing the Postman API. 4 | 5 | ### Synopsis 6 | 7 | Create a context for accessing the Postman API. 8 | 9 | ``` 10 | postmanctl config set-context [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | --api-root string API root URL for accessing the Postman API. (default "https://api.postman.com") 17 | -h, --help help for set-context 18 | ``` 19 | 20 | ### Options inherited from parent commands 21 | 22 | ``` 23 | --config string config file (default is $HOME/.postmanctl.yaml) 24 | --context string context to use, overrides the current context in the config file 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [postmanctl config](postmanctl_config.md) - Configure access to the Postman API. 30 | 31 | ###### Auto generated by spf13/cobra on 13-May-2020 32 | -------------------------------------------------------------------------------- /doc/postmanctl_config_use-context.md: -------------------------------------------------------------------------------- 1 | ## postmanctl config use-context 2 | 3 | Use an existing context for postmanctl commands. 4 | 5 | ### Synopsis 6 | 7 | Use an existing context for postmanctl commands. 8 | 9 | ``` 10 | postmanctl config use-context [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for use-context 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [postmanctl config](postmanctl_config.md) - Configure access to the Postman API. 29 | 30 | ###### Auto generated by spf13/cobra on 13-May-2020 31 | -------------------------------------------------------------------------------- /doc/postmanctl_create.md: -------------------------------------------------------------------------------- 1 | ## postmanctl create 2 | 3 | Create new Postman resources. 4 | 5 | ### Synopsis 6 | 7 | Create new Postman resources. 8 | 9 | ### Options 10 | 11 | ``` 12 | -f, --filename string the filename used to create the resource (required when not using data from stdin) 13 | -h, --help help for create 14 | ``` 15 | 16 | ### Options inherited from parent commands 17 | 18 | ``` 19 | --config string config file (default is $HOME/.postmanctl.yaml) 20 | --context string context to use, overrides the current context in the config file 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [postmanctl](postmanctl.md) - Controls the Postman API 26 | * [postmanctl create api](postmanctl_create_api.md) - 27 | * [postmanctl create api-version](postmanctl_create_api-version.md) - 28 | * [postmanctl create collection](postmanctl_create_collection.md) - 29 | * [postmanctl create environment](postmanctl_create_environment.md) - 30 | * [postmanctl create mock](postmanctl_create_mock.md) - 31 | * [postmanctl create monitor](postmanctl_create_monitor.md) - 32 | * [postmanctl create schema](postmanctl_create_schema.md) - 33 | * [postmanctl create workspace](postmanctl_create_workspace.md) - 34 | 35 | ###### Auto generated by spf13/cobra on 13-May-2020 36 | -------------------------------------------------------------------------------- /doc/postmanctl_create_api-version.md: -------------------------------------------------------------------------------- 1 | ## postmanctl create api-version 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl create api-version [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | --for-api string the associated API ID (required) 17 | -h, --help help for api-version 18 | -w, --workspace string workspace for create operation 19 | ``` 20 | 21 | ### Options inherited from parent commands 22 | 23 | ``` 24 | --config string config file (default is $HOME/.postmanctl.yaml) 25 | --context string context to use, overrides the current context in the config file 26 | -f, --filename string the filename used to create the resource (required when not using data from stdin) 27 | ``` 28 | 29 | ### SEE ALSO 30 | 31 | * [postmanctl create](postmanctl_create.md) - Create new Postman resources. 32 | 33 | ###### Auto generated by spf13/cobra on 13-May-2020 34 | -------------------------------------------------------------------------------- /doc/postmanctl_create_api.md: -------------------------------------------------------------------------------- 1 | ## postmanctl create api 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl create api [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for api 17 | -w, --workspace string workspace for create operation 18 | ``` 19 | 20 | ### Options inherited from parent commands 21 | 22 | ``` 23 | --config string config file (default is $HOME/.postmanctl.yaml) 24 | --context string context to use, overrides the current context in the config file 25 | -f, --filename string the filename used to create the resource (required when not using data from stdin) 26 | ``` 27 | 28 | ### SEE ALSO 29 | 30 | * [postmanctl create](postmanctl_create.md) - Create new Postman resources. 31 | 32 | ###### Auto generated by spf13/cobra on 13-May-2020 33 | -------------------------------------------------------------------------------- /doc/postmanctl_create_collection.md: -------------------------------------------------------------------------------- 1 | ## postmanctl create collection 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl create collection [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for collection 17 | -w, --workspace string workspace for create operation 18 | ``` 19 | 20 | ### Options inherited from parent commands 21 | 22 | ``` 23 | --config string config file (default is $HOME/.postmanctl.yaml) 24 | --context string context to use, overrides the current context in the config file 25 | -f, --filename string the filename used to create the resource (required when not using data from stdin) 26 | ``` 27 | 28 | ### SEE ALSO 29 | 30 | * [postmanctl create](postmanctl_create.md) - Create new Postman resources. 31 | 32 | ###### Auto generated by spf13/cobra on 13-May-2020 33 | -------------------------------------------------------------------------------- /doc/postmanctl_create_environment.md: -------------------------------------------------------------------------------- 1 | ## postmanctl create environment 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl create environment [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for environment 17 | -w, --workspace string workspace for create operation 18 | ``` 19 | 20 | ### Options inherited from parent commands 21 | 22 | ``` 23 | --config string config file (default is $HOME/.postmanctl.yaml) 24 | --context string context to use, overrides the current context in the config file 25 | -f, --filename string the filename used to create the resource (required when not using data from stdin) 26 | ``` 27 | 28 | ### SEE ALSO 29 | 30 | * [postmanctl create](postmanctl_create.md) - Create new Postman resources. 31 | 32 | ###### Auto generated by spf13/cobra on 13-May-2020 33 | -------------------------------------------------------------------------------- /doc/postmanctl_create_mock.md: -------------------------------------------------------------------------------- 1 | ## postmanctl create mock 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl create mock [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for mock 17 | -w, --workspace string workspace for create operation 18 | ``` 19 | 20 | ### Options inherited from parent commands 21 | 22 | ``` 23 | --config string config file (default is $HOME/.postmanctl.yaml) 24 | --context string context to use, overrides the current context in the config file 25 | -f, --filename string the filename used to create the resource (required when not using data from stdin) 26 | ``` 27 | 28 | ### SEE ALSO 29 | 30 | * [postmanctl create](postmanctl_create.md) - Create new Postman resources. 31 | 32 | ###### Auto generated by spf13/cobra on 13-May-2020 33 | -------------------------------------------------------------------------------- /doc/postmanctl_create_monitor.md: -------------------------------------------------------------------------------- 1 | ## postmanctl create monitor 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl create monitor [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for monitor 17 | -w, --workspace string workspace for create operation 18 | ``` 19 | 20 | ### Options inherited from parent commands 21 | 22 | ``` 23 | --config string config file (default is $HOME/.postmanctl.yaml) 24 | --context string context to use, overrides the current context in the config file 25 | -f, --filename string the filename used to create the resource (required when not using data from stdin) 26 | ``` 27 | 28 | ### SEE ALSO 29 | 30 | * [postmanctl create](postmanctl_create.md) - Create new Postman resources. 31 | 32 | ###### Auto generated by spf13/cobra on 13-May-2020 33 | -------------------------------------------------------------------------------- /doc/postmanctl_create_schema.md: -------------------------------------------------------------------------------- 1 | ## postmanctl create schema 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl create schema [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | --for-api string the associated API ID (required) 17 | --for-api-version string the associated API Version ID (required) 18 | -h, --help help for schema 19 | -w, --workspace string workspace for create operation 20 | ``` 21 | 22 | ### Options inherited from parent commands 23 | 24 | ``` 25 | --config string config file (default is $HOME/.postmanctl.yaml) 26 | --context string context to use, overrides the current context in the config file 27 | -f, --filename string the filename used to create the resource (required when not using data from stdin) 28 | ``` 29 | 30 | ### SEE ALSO 31 | 32 | * [postmanctl create](postmanctl_create.md) - Create new Postman resources. 33 | 34 | ###### Auto generated by spf13/cobra on 13-May-2020 35 | -------------------------------------------------------------------------------- /doc/postmanctl_create_workspace.md: -------------------------------------------------------------------------------- 1 | ## postmanctl create workspace 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl create workspace [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for workspace 17 | -w, --workspace string workspace for create operation 18 | ``` 19 | 20 | ### Options inherited from parent commands 21 | 22 | ``` 23 | --config string config file (default is $HOME/.postmanctl.yaml) 24 | --context string context to use, overrides the current context in the config file 25 | -f, --filename string the filename used to create the resource (required when not using data from stdin) 26 | ``` 27 | 28 | ### SEE ALSO 29 | 30 | * [postmanctl create](postmanctl_create.md) - Create new Postman resources. 31 | 32 | ###### Auto generated by spf13/cobra on 13-May-2020 33 | -------------------------------------------------------------------------------- /doc/postmanctl_delete.md: -------------------------------------------------------------------------------- 1 | ## postmanctl delete 2 | 3 | Delete existing Postman resources. 4 | 5 | ### Synopsis 6 | 7 | Delete existing Postman resources. 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for delete 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --config string config file (default is $HOME/.postmanctl.yaml) 19 | --context string context to use, overrides the current context in the config file 20 | ``` 21 | 22 | ### SEE ALSO 23 | 24 | * [postmanctl](postmanctl.md) - Controls the Postman API 25 | * [postmanctl delete api](postmanctl_delete_api.md) - 26 | * [postmanctl delete api-version](postmanctl_delete_api-version.md) - 27 | * [postmanctl delete collection](postmanctl_delete_collection.md) - 28 | * [postmanctl delete environment](postmanctl_delete_environment.md) - 29 | * [postmanctl delete mock](postmanctl_delete_mock.md) - 30 | * [postmanctl delete monitor](postmanctl_delete_monitor.md) - 31 | * [postmanctl delete schema](postmanctl_delete_schema.md) - 32 | * [postmanctl delete workspace](postmanctl_delete_workspace.md) - 33 | 34 | ###### Auto generated by spf13/cobra on 13-May-2020 35 | -------------------------------------------------------------------------------- /doc/postmanctl_delete_api-version.md: -------------------------------------------------------------------------------- 1 | ## postmanctl delete api-version 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl delete api-version [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | --for-api string the associated API ID (required) 17 | -h, --help help for api-version 18 | ``` 19 | 20 | ### Options inherited from parent commands 21 | 22 | ``` 23 | --config string config file (default is $HOME/.postmanctl.yaml) 24 | --context string context to use, overrides the current context in the config file 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [postmanctl delete](postmanctl_delete.md) - Delete existing Postman resources. 30 | 31 | ###### Auto generated by spf13/cobra on 13-May-2020 32 | -------------------------------------------------------------------------------- /doc/postmanctl_delete_api.md: -------------------------------------------------------------------------------- 1 | ## postmanctl delete api 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl delete api [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for api 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [postmanctl delete](postmanctl_delete.md) - Delete existing Postman resources. 29 | 30 | ###### Auto generated by spf13/cobra on 13-May-2020 31 | -------------------------------------------------------------------------------- /doc/postmanctl_delete_collection.md: -------------------------------------------------------------------------------- 1 | ## postmanctl delete collection 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl delete collection [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for collection 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [postmanctl delete](postmanctl_delete.md) - Delete existing Postman resources. 29 | 30 | ###### Auto generated by spf13/cobra on 13-May-2020 31 | -------------------------------------------------------------------------------- /doc/postmanctl_delete_environment.md: -------------------------------------------------------------------------------- 1 | ## postmanctl delete environment 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl delete environment [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for environment 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [postmanctl delete](postmanctl_delete.md) - Delete existing Postman resources. 29 | 30 | ###### Auto generated by spf13/cobra on 13-May-2020 31 | -------------------------------------------------------------------------------- /doc/postmanctl_delete_mock.md: -------------------------------------------------------------------------------- 1 | ## postmanctl delete mock 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl delete mock [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for mock 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [postmanctl delete](postmanctl_delete.md) - Delete existing Postman resources. 29 | 30 | ###### Auto generated by spf13/cobra on 13-May-2020 31 | -------------------------------------------------------------------------------- /doc/postmanctl_delete_monitor.md: -------------------------------------------------------------------------------- 1 | ## postmanctl delete monitor 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl delete monitor [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for monitor 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [postmanctl delete](postmanctl_delete.md) - Delete existing Postman resources. 29 | 30 | ###### Auto generated by spf13/cobra on 13-May-2020 31 | -------------------------------------------------------------------------------- /doc/postmanctl_delete_schema.md: -------------------------------------------------------------------------------- 1 | ## postmanctl delete schema 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl delete schema [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | --for-api string the associated API ID (required) 17 | --for-api-version string the associated API Version ID (required) 18 | -h, --help help for schema 19 | ``` 20 | 21 | ### Options inherited from parent commands 22 | 23 | ``` 24 | --config string config file (default is $HOME/.postmanctl.yaml) 25 | --context string context to use, overrides the current context in the config file 26 | ``` 27 | 28 | ### SEE ALSO 29 | 30 | * [postmanctl delete](postmanctl_delete.md) - Delete existing Postman resources. 31 | 32 | ###### Auto generated by spf13/cobra on 13-May-2020 33 | -------------------------------------------------------------------------------- /doc/postmanctl_delete_workspace.md: -------------------------------------------------------------------------------- 1 | ## postmanctl delete workspace 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl delete workspace [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for workspace 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [postmanctl delete](postmanctl_delete.md) - Delete existing Postman resources. 29 | 30 | ###### Auto generated by spf13/cobra on 13-May-2020 31 | -------------------------------------------------------------------------------- /doc/postmanctl_describe.md: -------------------------------------------------------------------------------- 1 | ## postmanctl describe 2 | 3 | Describe an entity in the Postman API 4 | 5 | ### Synopsis 6 | 7 | Describe an entity in the Postman API 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for describe 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --config string config file (default is $HOME/.postmanctl.yaml) 19 | --context string context to use, overrides the current context in the config file 20 | ``` 21 | 22 | ### SEE ALSO 23 | 24 | * [postmanctl](postmanctl.md) - Controls the Postman API 25 | * [postmanctl describe api-relations](postmanctl_describe_api-relations.md) - 26 | * [postmanctl describe api-versions](postmanctl_describe_api-versions.md) - 27 | * [postmanctl describe apis](postmanctl_describe_apis.md) - 28 | * [postmanctl describe collections](postmanctl_describe_collections.md) - 29 | * [postmanctl describe environments](postmanctl_describe_environments.md) - 30 | * [postmanctl describe mocks](postmanctl_describe_mocks.md) - 31 | * [postmanctl describe monitors](postmanctl_describe_monitors.md) - 32 | * [postmanctl describe schema](postmanctl_describe_schema.md) - 33 | * [postmanctl describe user](postmanctl_describe_user.md) - 34 | * [postmanctl describe workspaces](postmanctl_describe_workspaces.md) - 35 | 36 | ###### Auto generated by spf13/cobra on 13-May-2020 37 | -------------------------------------------------------------------------------- /doc/postmanctl_describe_api-relations.md: -------------------------------------------------------------------------------- 1 | ## postmanctl describe api-relations 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl describe api-relations [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | --for-api string the associated API ID (required) 17 | --for-api-version string the associated API Version ID (required) 18 | -h, --help help for api-relations 19 | ``` 20 | 21 | ### Options inherited from parent commands 22 | 23 | ``` 24 | --config string config file (default is $HOME/.postmanctl.yaml) 25 | --context string context to use, overrides the current context in the config file 26 | ``` 27 | 28 | ### SEE ALSO 29 | 30 | * [postmanctl describe](postmanctl_describe.md) - Describe an entity in the Postman API 31 | 32 | ###### Auto generated by spf13/cobra on 13-May-2020 33 | -------------------------------------------------------------------------------- /doc/postmanctl_describe_api-versions.md: -------------------------------------------------------------------------------- 1 | ## postmanctl describe api-versions 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl describe api-versions [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | --for-api string the associated API ID (required) 17 | -h, --help help for api-versions 18 | ``` 19 | 20 | ### Options inherited from parent commands 21 | 22 | ``` 23 | --config string config file (default is $HOME/.postmanctl.yaml) 24 | --context string context to use, overrides the current context in the config file 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [postmanctl describe](postmanctl_describe.md) - Describe an entity in the Postman API 30 | 31 | ###### Auto generated by spf13/cobra on 13-May-2020 32 | -------------------------------------------------------------------------------- /doc/postmanctl_describe_apis.md: -------------------------------------------------------------------------------- 1 | ## postmanctl describe apis 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl describe apis [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for apis 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [postmanctl describe](postmanctl_describe.md) - Describe an entity in the Postman API 29 | 30 | ###### Auto generated by spf13/cobra on 13-May-2020 31 | -------------------------------------------------------------------------------- /doc/postmanctl_describe_collections.md: -------------------------------------------------------------------------------- 1 | ## postmanctl describe collections 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl describe collections [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for collections 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [postmanctl describe](postmanctl_describe.md) - Describe an entity in the Postman API 29 | 30 | ###### Auto generated by spf13/cobra on 13-May-2020 31 | -------------------------------------------------------------------------------- /doc/postmanctl_describe_environments.md: -------------------------------------------------------------------------------- 1 | ## postmanctl describe environments 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl describe environments [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for environments 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [postmanctl describe](postmanctl_describe.md) - Describe an entity in the Postman API 29 | 30 | ###### Auto generated by spf13/cobra on 13-May-2020 31 | -------------------------------------------------------------------------------- /doc/postmanctl_describe_mocks.md: -------------------------------------------------------------------------------- 1 | ## postmanctl describe mocks 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl describe mocks [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for mocks 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [postmanctl describe](postmanctl_describe.md) - Describe an entity in the Postman API 29 | 30 | ###### Auto generated by spf13/cobra on 13-May-2020 31 | -------------------------------------------------------------------------------- /doc/postmanctl_describe_monitors.md: -------------------------------------------------------------------------------- 1 | ## postmanctl describe monitors 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl describe monitors [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for monitors 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [postmanctl describe](postmanctl_describe.md) - Describe an entity in the Postman API 29 | 30 | ###### Auto generated by spf13/cobra on 13-May-2020 31 | -------------------------------------------------------------------------------- /doc/postmanctl_describe_schema.md: -------------------------------------------------------------------------------- 1 | ## postmanctl describe schema 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl describe schema [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | --for-api string the associated API ID (required) 17 | --for-api-version string the associated API Version ID (required) 18 | -h, --help help for schema 19 | ``` 20 | 21 | ### Options inherited from parent commands 22 | 23 | ``` 24 | --config string config file (default is $HOME/.postmanctl.yaml) 25 | --context string context to use, overrides the current context in the config file 26 | ``` 27 | 28 | ### SEE ALSO 29 | 30 | * [postmanctl describe](postmanctl_describe.md) - Describe an entity in the Postman API 31 | 32 | ###### Auto generated by spf13/cobra on 13-May-2020 33 | -------------------------------------------------------------------------------- /doc/postmanctl_describe_user.md: -------------------------------------------------------------------------------- 1 | ## postmanctl describe user 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl describe user [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for user 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [postmanctl describe](postmanctl_describe.md) - Describe an entity in the Postman API 29 | 30 | ###### Auto generated by spf13/cobra on 13-May-2020 31 | -------------------------------------------------------------------------------- /doc/postmanctl_describe_workspaces.md: -------------------------------------------------------------------------------- 1 | ## postmanctl describe workspaces 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl describe workspaces [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for workspaces 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [postmanctl describe](postmanctl_describe.md) - Describe an entity in the Postman API 29 | 30 | ###### Auto generated by spf13/cobra on 13-May-2020 31 | -------------------------------------------------------------------------------- /doc/postmanctl_fork.md: -------------------------------------------------------------------------------- 1 | ## postmanctl fork 2 | 3 | Create a fork of a Postman resource. 4 | 5 | ### Synopsis 6 | 7 | Create a fork of a Postman resource. 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for fork 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --config string config file (default is $HOME/.postmanctl.yaml) 19 | --context string context to use, overrides the current context in the config file 20 | ``` 21 | 22 | ### SEE ALSO 23 | 24 | * [postmanctl](postmanctl.md) - Controls the Postman API 25 | * [postmanctl fork collection](postmanctl_fork_collection.md) - 26 | 27 | ###### Auto generated by spf13/cobra on 13-May-2020 28 | -------------------------------------------------------------------------------- /doc/postmanctl_fork_collection.md: -------------------------------------------------------------------------------- 1 | ## postmanctl fork collection 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl fork collection [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for collection 17 | -l, --label string label to associate with the forked collection (required) 18 | -w, --workspace string workspace for fork operation 19 | ``` 20 | 21 | ### Options inherited from parent commands 22 | 23 | ``` 24 | --config string config file (default is $HOME/.postmanctl.yaml) 25 | --context string context to use, overrides the current context in the config file 26 | ``` 27 | 28 | ### SEE ALSO 29 | 30 | * [postmanctl fork](postmanctl_fork.md) - Create a fork of a Postman resource. 31 | 32 | ###### Auto generated by spf13/cobra on 13-May-2020 33 | -------------------------------------------------------------------------------- /doc/postmanctl_get.md: -------------------------------------------------------------------------------- 1 | ## postmanctl get 2 | 3 | Retrieve Postman resources. 4 | 5 | ### Synopsis 6 | 7 | Retrieve Postman resources. 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for get 13 | -o, --output string output format (json, jsonpath, go-template-file) 14 | ``` 15 | 16 | ### Options inherited from parent commands 17 | 18 | ``` 19 | --config string config file (default is $HOME/.postmanctl.yaml) 20 | --context string context to use, overrides the current context in the config file 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [postmanctl](postmanctl.md) - Controls the Postman API 26 | * [postmanctl get api-relations](postmanctl_get_api-relations.md) - 27 | * [postmanctl get api-versions](postmanctl_get_api-versions.md) - 28 | * [postmanctl get apis](postmanctl_get_apis.md) - 29 | * [postmanctl get collections](postmanctl_get_collections.md) - 30 | * [postmanctl get environments](postmanctl_get_environments.md) - 31 | * [postmanctl get mocks](postmanctl_get_mocks.md) - 32 | * [postmanctl get monitors](postmanctl_get_monitors.md) - 33 | * [postmanctl get schema](postmanctl_get_schema.md) - 34 | * [postmanctl get user](postmanctl_get_user.md) - 35 | * [postmanctl get workspaces](postmanctl_get_workspaces.md) - 36 | 37 | ###### Auto generated by spf13/cobra on 13-May-2020 38 | -------------------------------------------------------------------------------- /doc/postmanctl_get_api-relations.md: -------------------------------------------------------------------------------- 1 | ## postmanctl get api-relations 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl get api-relations [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | --for-api string the associated API ID (required) 17 | --for-api-version string the associated API Version ID (required) 18 | -h, --help help for api-relations 19 | ``` 20 | 21 | ### Options inherited from parent commands 22 | 23 | ``` 24 | --config string config file (default is $HOME/.postmanctl.yaml) 25 | --context string context to use, overrides the current context in the config file 26 | -o, --output string output format (json, jsonpath, go-template-file) 27 | ``` 28 | 29 | ### SEE ALSO 30 | 31 | * [postmanctl get](postmanctl_get.md) - Retrieve Postman resources. 32 | 33 | ###### Auto generated by spf13/cobra on 13-May-2020 34 | -------------------------------------------------------------------------------- /doc/postmanctl_get_api-versions.md: -------------------------------------------------------------------------------- 1 | ## postmanctl get api-versions 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl get api-versions [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | --for-api string the associated API ID (required) 17 | -h, --help help for api-versions 18 | ``` 19 | 20 | ### Options inherited from parent commands 21 | 22 | ``` 23 | --config string config file (default is $HOME/.postmanctl.yaml) 24 | --context string context to use, overrides the current context in the config file 25 | -o, --output string output format (json, jsonpath, go-template-file) 26 | ``` 27 | 28 | ### SEE ALSO 29 | 30 | * [postmanctl get](postmanctl_get.md) - Retrieve Postman resources. 31 | 32 | ###### Auto generated by spf13/cobra on 13-May-2020 33 | -------------------------------------------------------------------------------- /doc/postmanctl_get_apis.md: -------------------------------------------------------------------------------- 1 | ## postmanctl get apis 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl get apis [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for apis 17 | --workspace string the associated workspace ID 18 | ``` 19 | 20 | ### Options inherited from parent commands 21 | 22 | ``` 23 | --config string config file (default is $HOME/.postmanctl.yaml) 24 | --context string context to use, overrides the current context in the config file 25 | -o, --output string output format (json, jsonpath, go-template-file) 26 | ``` 27 | 28 | ### SEE ALSO 29 | 30 | * [postmanctl get](postmanctl_get.md) - Retrieve Postman resources. 31 | 32 | ###### Auto generated by spf13/cobra on 13-May-2020 33 | -------------------------------------------------------------------------------- /doc/postmanctl_get_collections.md: -------------------------------------------------------------------------------- 1 | ## postmanctl get collections 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl get collections [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for collections 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | -o, --output string output format (json, jsonpath, go-template-file) 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [postmanctl get](postmanctl_get.md) - Retrieve Postman resources. 30 | 31 | ###### Auto generated by spf13/cobra on 13-May-2020 32 | -------------------------------------------------------------------------------- /doc/postmanctl_get_environments.md: -------------------------------------------------------------------------------- 1 | ## postmanctl get environments 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl get environments [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for environments 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | -o, --output string output format (json, jsonpath, go-template-file) 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [postmanctl get](postmanctl_get.md) - Retrieve Postman resources. 30 | 31 | ###### Auto generated by spf13/cobra on 13-May-2020 32 | -------------------------------------------------------------------------------- /doc/postmanctl_get_mocks.md: -------------------------------------------------------------------------------- 1 | ## postmanctl get mocks 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl get mocks [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for mocks 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | -o, --output string output format (json, jsonpath, go-template-file) 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [postmanctl get](postmanctl_get.md) - Retrieve Postman resources. 30 | 31 | ###### Auto generated by spf13/cobra on 13-May-2020 32 | -------------------------------------------------------------------------------- /doc/postmanctl_get_monitors.md: -------------------------------------------------------------------------------- 1 | ## postmanctl get monitors 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl get monitors [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for monitors 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | -o, --output string output format (json, jsonpath, go-template-file) 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [postmanctl get](postmanctl_get.md) - Retrieve Postman resources. 30 | 31 | ###### Auto generated by spf13/cobra on 13-May-2020 32 | -------------------------------------------------------------------------------- /doc/postmanctl_get_schema.md: -------------------------------------------------------------------------------- 1 | ## postmanctl get schema 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl get schema [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | --for-api string the associated API ID (required) 17 | --for-api-version string the associated API Version ID (required) 18 | -h, --help help for schema 19 | ``` 20 | 21 | ### Options inherited from parent commands 22 | 23 | ``` 24 | --config string config file (default is $HOME/.postmanctl.yaml) 25 | --context string context to use, overrides the current context in the config file 26 | -o, --output string output format (json, jsonpath, go-template-file) 27 | ``` 28 | 29 | ### SEE ALSO 30 | 31 | * [postmanctl get](postmanctl_get.md) - Retrieve Postman resources. 32 | 33 | ###### Auto generated by spf13/cobra on 13-May-2020 34 | -------------------------------------------------------------------------------- /doc/postmanctl_get_user.md: -------------------------------------------------------------------------------- 1 | ## postmanctl get user 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl get user [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for user 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | -o, --output string output format (json, jsonpath, go-template-file) 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [postmanctl get](postmanctl_get.md) - Retrieve Postman resources. 30 | 31 | ###### Auto generated by spf13/cobra on 13-May-2020 32 | -------------------------------------------------------------------------------- /doc/postmanctl_get_workspaces.md: -------------------------------------------------------------------------------- 1 | ## postmanctl get workspaces 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl get workspaces [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for workspaces 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | -o, --output string output format (json, jsonpath, go-template-file) 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [postmanctl get](postmanctl_get.md) - Retrieve Postman resources. 30 | 31 | ###### Auto generated by spf13/cobra on 13-May-2020 32 | -------------------------------------------------------------------------------- /doc/postmanctl_merge.md: -------------------------------------------------------------------------------- 1 | ## postmanctl merge 2 | 3 | Merge a fork of a Postman resource. 4 | 5 | ### Synopsis 6 | 7 | Merge a fork of a Postman resource. 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for merge 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --config string config file (default is $HOME/.postmanctl.yaml) 19 | --context string context to use, overrides the current context in the config file 20 | ``` 21 | 22 | ### SEE ALSO 23 | 24 | * [postmanctl](postmanctl.md) - Controls the Postman API 25 | * [postmanctl merge collection](postmanctl_merge_collection.md) - 26 | 27 | ###### Auto generated by spf13/cobra on 13-May-2020 28 | -------------------------------------------------------------------------------- /doc/postmanctl_merge_collection.md: -------------------------------------------------------------------------------- 1 | ## postmanctl merge collection 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl merge collection [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for collection 17 | -s, --strategy string strategy for merging fork (optional, values: deleteSource, updateSourceWithDestination) 18 | --to string the destination collection to receive the merged changes 19 | ``` 20 | 21 | ### Options inherited from parent commands 22 | 23 | ``` 24 | --config string config file (default is $HOME/.postmanctl.yaml) 25 | --context string context to use, overrides the current context in the config file 26 | ``` 27 | 28 | ### SEE ALSO 29 | 30 | * [postmanctl merge](postmanctl_merge.md) - Merge a fork of a Postman resource. 31 | 32 | ###### Auto generated by spf13/cobra on 13-May-2020 33 | -------------------------------------------------------------------------------- /doc/postmanctl_replace.md: -------------------------------------------------------------------------------- 1 | ## postmanctl replace 2 | 3 | Replace existing Postman resources. 4 | 5 | ### Synopsis 6 | 7 | Replace existing Postman resources. 8 | 9 | ### Options 10 | 11 | ``` 12 | -f, --filename string the filename used to replace the resource (required when not using data from stdin) 13 | -h, --help help for replace 14 | ``` 15 | 16 | ### Options inherited from parent commands 17 | 18 | ``` 19 | --config string config file (default is $HOME/.postmanctl.yaml) 20 | --context string context to use, overrides the current context in the config file 21 | ``` 22 | 23 | ### SEE ALSO 24 | 25 | * [postmanctl](postmanctl.md) - Controls the Postman API 26 | * [postmanctl replace api](postmanctl_replace_api.md) - 27 | * [postmanctl replace api-version](postmanctl_replace_api-version.md) - 28 | * [postmanctl replace collection](postmanctl_replace_collection.md) - 29 | * [postmanctl replace environment](postmanctl_replace_environment.md) - 30 | * [postmanctl replace mock](postmanctl_replace_mock.md) - 31 | * [postmanctl replace monitor](postmanctl_replace_monitor.md) - 32 | * [postmanctl replace schema](postmanctl_replace_schema.md) - 33 | * [postmanctl replace workspace](postmanctl_replace_workspace.md) - 34 | 35 | ###### Auto generated by spf13/cobra on 13-May-2020 36 | -------------------------------------------------------------------------------- /doc/postmanctl_replace_api-version.md: -------------------------------------------------------------------------------- 1 | ## postmanctl replace api-version 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl replace api-version [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | --for-api string the associated API ID (required) 17 | -h, --help help for api-version 18 | ``` 19 | 20 | ### Options inherited from parent commands 21 | 22 | ``` 23 | --config string config file (default is $HOME/.postmanctl.yaml) 24 | --context string context to use, overrides the current context in the config file 25 | -f, --filename string the filename used to replace the resource (required when not using data from stdin) 26 | ``` 27 | 28 | ### SEE ALSO 29 | 30 | * [postmanctl replace](postmanctl_replace.md) - Replace existing Postman resources. 31 | 32 | ###### Auto generated by spf13/cobra on 13-May-2020 33 | -------------------------------------------------------------------------------- /doc/postmanctl_replace_api.md: -------------------------------------------------------------------------------- 1 | ## postmanctl replace api 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl replace api [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for api 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | -f, --filename string the filename used to replace the resource (required when not using data from stdin) 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [postmanctl replace](postmanctl_replace.md) - Replace existing Postman resources. 30 | 31 | ###### Auto generated by spf13/cobra on 13-May-2020 32 | -------------------------------------------------------------------------------- /doc/postmanctl_replace_collection.md: -------------------------------------------------------------------------------- 1 | ## postmanctl replace collection 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl replace collection [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for collection 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | -f, --filename string the filename used to replace the resource (required when not using data from stdin) 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [postmanctl replace](postmanctl_replace.md) - Replace existing Postman resources. 30 | 31 | ###### Auto generated by spf13/cobra on 13-May-2020 32 | -------------------------------------------------------------------------------- /doc/postmanctl_replace_environment.md: -------------------------------------------------------------------------------- 1 | ## postmanctl replace environment 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl replace environment [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for environment 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | -f, --filename string the filename used to replace the resource (required when not using data from stdin) 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [postmanctl replace](postmanctl_replace.md) - Replace existing Postman resources. 30 | 31 | ###### Auto generated by spf13/cobra on 13-May-2020 32 | -------------------------------------------------------------------------------- /doc/postmanctl_replace_mock.md: -------------------------------------------------------------------------------- 1 | ## postmanctl replace mock 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl replace mock [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for mock 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | -f, --filename string the filename used to replace the resource (required when not using data from stdin) 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [postmanctl replace](postmanctl_replace.md) - Replace existing Postman resources. 30 | 31 | ###### Auto generated by spf13/cobra on 13-May-2020 32 | -------------------------------------------------------------------------------- /doc/postmanctl_replace_monitor.md: -------------------------------------------------------------------------------- 1 | ## postmanctl replace monitor 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl replace monitor [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for monitor 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | -f, --filename string the filename used to replace the resource (required when not using data from stdin) 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [postmanctl replace](postmanctl_replace.md) - Replace existing Postman resources. 30 | 31 | ###### Auto generated by spf13/cobra on 13-May-2020 32 | -------------------------------------------------------------------------------- /doc/postmanctl_replace_schema.md: -------------------------------------------------------------------------------- 1 | ## postmanctl replace schema 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl replace schema [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | --for-api string the associated API ID (required) 17 | --for-api-version string the associated API Version ID (required) 18 | -h, --help help for schema 19 | ``` 20 | 21 | ### Options inherited from parent commands 22 | 23 | ``` 24 | --config string config file (default is $HOME/.postmanctl.yaml) 25 | --context string context to use, overrides the current context in the config file 26 | -f, --filename string the filename used to replace the resource (required when not using data from stdin) 27 | ``` 28 | 29 | ### SEE ALSO 30 | 31 | * [postmanctl replace](postmanctl_replace.md) - Replace existing Postman resources. 32 | 33 | ###### Auto generated by spf13/cobra on 13-May-2020 34 | -------------------------------------------------------------------------------- /doc/postmanctl_replace_workspace.md: -------------------------------------------------------------------------------- 1 | ## postmanctl replace workspace 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl replace workspace [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for workspace 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | -f, --filename string the filename used to replace the resource (required when not using data from stdin) 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [postmanctl replace](postmanctl_replace.md) - Replace existing Postman resources. 30 | 31 | ###### Auto generated by spf13/cobra on 13-May-2020 32 | -------------------------------------------------------------------------------- /doc/postmanctl_run.md: -------------------------------------------------------------------------------- 1 | ## postmanctl run 2 | 3 | Execute runnable Postman resources. 4 | 5 | ### Synopsis 6 | 7 | Execute runnable Postman resources. 8 | 9 | ### Options 10 | 11 | ``` 12 | -h, --help help for run 13 | ``` 14 | 15 | ### Options inherited from parent commands 16 | 17 | ``` 18 | --config string config file (default is $HOME/.postmanctl.yaml) 19 | --context string context to use, overrides the current context in the config file 20 | ``` 21 | 22 | ### SEE ALSO 23 | 24 | * [postmanctl](postmanctl.md) - Controls the Postman API 25 | * [postmanctl run monitor](postmanctl_run_monitor.md) - 26 | 27 | ###### Auto generated by spf13/cobra on 13-May-2020 28 | -------------------------------------------------------------------------------- /doc/postmanctl_run_monitor.md: -------------------------------------------------------------------------------- 1 | ## postmanctl run monitor 2 | 3 | 4 | 5 | ### Synopsis 6 | 7 | 8 | 9 | ``` 10 | postmanctl run monitor [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for monitor 17 | ``` 18 | 19 | ### Options inherited from parent commands 20 | 21 | ``` 22 | --config string config file (default is $HOME/.postmanctl.yaml) 23 | --context string context to use, overrides the current context in the config file 24 | ``` 25 | 26 | ### SEE ALSO 27 | 28 | * [postmanctl run](postmanctl_run.md) - Execute runnable Postman resources. 29 | 30 | ###### Auto generated by spf13/cobra on 13-May-2020 31 | -------------------------------------------------------------------------------- /doc/postmanctl_version.md: -------------------------------------------------------------------------------- 1 | ## postmanctl version 2 | 3 | Print version information for postmanctl. 4 | 5 | ### Synopsis 6 | 7 | Print version information for postmanctl. 8 | 9 | ``` 10 | postmanctl version [flags] 11 | ``` 12 | 13 | ### Options 14 | 15 | ``` 16 | -h, --help help for version 17 | -o, --output string output format (json, short) 18 | ``` 19 | 20 | ### Options inherited from parent commands 21 | 22 | ``` 23 | --config string config file (default is $HOME/.postmanctl.yaml) 24 | --context string context to use, overrides the current context in the config file 25 | ``` 26 | 27 | ### SEE ALSO 28 | 29 | * [postmanctl](postmanctl.md) - Controls the Postman API 30 | 31 | ###### Auto generated by spf13/cobra on 13-May-2020 32 | -------------------------------------------------------------------------------- /examples/find-orphan-collections/find-orphan-collections.sh: -------------------------------------------------------------------------------- 1 | set -x 2 | 3 | # Get all workspace IDs. 4 | postmanctl get ws -o json | jq -r ".[].id" > workspaces.txt 5 | 6 | # Get all collection UIDs. 7 | postmanctl get co -o json | jq -r ".[].uid" > collections.txt 8 | 9 | # Iterate over all workspaces, and record all associated collections. 10 | cat workspaces.txt | while read workspace_id; do sh -c "postmanctl get ws $workspace_id -o json | jq -r '.[].collections[].uid' >> workspace_collections.txt"; done 11 | 12 | # Sort data in files. 13 | sort -o workspace_collections.txt workspace_collections.txt 14 | sort -o collections.txt collections.txt 15 | 16 | # Compare files and show only collections that exist in the complete collections list yet not in the list of collections associated with workspaces. 17 | comm -23 collections.txt workspace_collections.txt 18 | -------------------------------------------------------------------------------- /examples/go-template/convert-to-jmeter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ $# -lt 1 ]; then 6 | echo "Usage: $0 " 7 | exit 1 8 | fi 9 | 10 | dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 11 | 12 | postmanctl get co -o go-template-file="${dir}/jmeter.tmpl" $1 -------------------------------------------------------------------------------- /examples/go-template/jmeter.tmpl: -------------------------------------------------------------------------------- 1 | 2 | {{range . -}} 3 | 4 | 5 | 6 | false 7 | 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | false 18 | 5 19 | 20 | 1 21 | 1 22 | false 23 | 0 24 | 0 25 | continue 26 | true 27 | 28 | 29 | {{template "folder" . -}} 30 | {{if hasKey . "variable" -}} 31 | {{if .variable -}} 32 | {{if len .variable -}} 33 | {{" "}} 34 | 35 | {{range .variable -}} 36 | {{" "}} 37 | {{.key}} 38 | {{(html .value) | replace "\n" " \n"}} 39 | = 40 | 41 | {{end -}} 42 | {{" "}} 43 | 44 | 45 | {{end -}} 46 | {{end -}} 47 | {{end -}} 48 | {{" "}} 49 | 50 | 51 | 52 | {{- end -}} 53 | 54 | {{define "folder" -}} 55 | {{if (hasKey . "item") -}} 56 | {{range .item -}} 57 | {{template "folder" . -}} 58 | {{end -}} 59 | {{else -}} 60 | {{template "item" . -}} 61 | {{end -}} 62 | {{end -}} 63 | 64 | {{define "item" -}} 65 | {{$hasAdditionalHashTree := false -}} 66 | {{""}} 67 | {{if (hasKey .request "body") -}} 68 | {{if (hasKey .request.body "raw") -}} 69 | {{""}} true 70 | 71 | 72 | 73 | false 74 | {{(html .request.body.raw) | replace "\n" " \n"}} 75 | = 76 | 77 | 78 | 79 | {{else if (hasKey .request.body "urlencoded") -}} 80 | {{""}} 81 | 82 | {{range .request.body.urlencoded -}} 83 | {{""}} 84 | false 85 | {{html (regexReplaceAll "{{([\\w-]+)}}" .value "${${1}}")}} 86 | = 87 | true 88 | {{.key}} 89 | 90 | {{end -}} 91 | {{""}} 92 | 93 | {{end -}} 94 | {{else -}} 95 | {{""}} 96 | 97 | 98 | {{ end -}} 99 | {{""}} false 100 | true 101 | true 102 | false 103 | false 104 | 105 | 106 | {{.request.method}} 107 | {{regexReplaceAll "{{([\\w-]+)}}" (.request.url.host | join ".") "${${1}}"}} 108 | /{{regexReplaceAll "/:([\\w-]+)" (regexReplaceAll "{{([\\w-]+)}}" (.request.url.path | join "/") "${${1}}") "/${${1}}"}} 109 | {{coalesce .request.url.protocol "http"}} 110 | 111 | {{if hasKey .request "header" -}} 112 | {{if len .request.header -}} 113 | {{$hasAdditionalHashTree = true -}} 114 | {{""}} 115 | 116 | 117 | {{range .request.header -}} 118 | {{""}} 119 | {{.key}} 120 | {{html (regexReplaceAll "{{([\\w-]+)}}" .value "${${1}}")}} 121 | 122 | {{end -}} 123 | {{""}} 124 | 125 | 126 | {{end -}} 127 | {{end -}} 128 | {{if hasKey .request.url "variable" -}} 129 | {{if len .request.url.variable -}} 130 | {{$hasAdditionalHashTree = true -}} 131 | {{""}} 132 | 133 | 134 | {{range .request.url.variable -}} 135 | {{""}} 136 | {{.key}} 137 | {{html (regexReplaceAll "{{([\\w-]+)}}" (.value | join ",") "${${1}}")}} 138 | {{html .description}} 139 | = 140 | 141 | {{end -}} 142 | {{end -}} 143 | {{""}} 144 | 145 | 146 | 147 | {{end -}} 148 | {{if not $hasAdditionalHashTree -}} 149 | {{""}} 150 | {{end -}} 151 | {{end}} 152 | -------------------------------------------------------------------------------- /examples/go-template/openapi3.tmpl: -------------------------------------------------------------------------------- 1 | {{range . -}} 2 | 3 | {{$_ := set . "_servers" list -}} 4 | {{$_ := set . "_tags" dict -}} 5 | {{$_ := set . "_paths" dict -}} 6 | {{$_ := set . "_components" dict -}} 7 | {{$_ := set . "_depth" 0 -}} 8 | {{$_ := set . "_currentTag" list -}} 9 | {{$_ := set . "_current" . -}} 10 | 11 | {{template "transform-folder" . -}} 12 | --- 13 | openapi: "3.0.3" 14 | info: 15 | title: {{.info.name}} 16 | # TODO: update contact info. 17 | contact: 18 | name: "API Authors" 19 | {{if .info.description}} description: | 20 | {{trim (replace "\n" "\n " .info.description)}}{{"\n"}}{{end -}} 21 | {{""}} version: "1.0.0" 22 | {{if len ._servers -}} 23 | servers: 24 | {{range (._servers | uniq) -}} 25 | {{""}} - url: {{.}} 26 | {{end -}} 27 | {{end -}} 28 | 29 | {{if len ._tags -}} 30 | tags: 31 | {{range $tagName, $tagObj := ._tags -}} 32 | {{$tagDesc := get $tagObj "description" -}} 33 | {{""}} - name: {{toJson $tagName}} 34 | {{if $tagDesc}} description: | 35 | {{trim (replace "\n" "\n " $tagDesc)}}{{"\n"}}{{end -}} 36 | {{end -}} 37 | {{end -}} 38 | 39 | paths: 40 | {{range $pathKey, $methodMap := ._paths -}} 41 | {{""}} "{{$pathKey}}": 42 | {{$pathParameters := get $methodMap "_pathParameters" -}} 43 | {{if len $pathParameters -}} 44 | {{""}} parameters: 45 | {{range $pathParameters -}} 46 | {{""}} - name: {{.}} 47 | in: path 48 | required: true 49 | schema: 50 | type: string 51 | {{end -}} 52 | {{end -}} 53 | {{range $methodKey, $methodObj := $methodMap -}} 54 | {{if not (eq $methodKey "_pathParameters") -}} 55 | {{""}} {{$methodKey}}: 56 | operationId: {{$methodObj.operationId | toJson}} 57 | {{if $methodObj.summary}} summary: {{trim $methodObj.summary | toJson}}{{"\n"}}{{end -}} 58 | {{""}} description: | 59 | {{trim (replace "\n" "\n " (coalesce $methodObj.description "TODO: add description"))}} 60 | {{if $methodObj.tags}} tags:{{"\n"}}{{end -}} 61 | {{range $methodObj.tags -}} 62 | {{""}} - {{toJson .}} 63 | {{end -}} 64 | {{if $methodObj.parameters}} parameters:{{"\n"}}{{end -}} 65 | {{range $methodObj.parameters -}} 66 | {{""}} - name: {{toJson .name}} 67 | schema: 68 | type: string 69 | in: {{.in}} 70 | {{if .example}} example: {{toJson .example}}{{"\n"}}{{end -}} 71 | {{if .description}} description: | 72 | {{trim (replace "\n" "\n " .description)}}{{"\n"}}{{end -}} 73 | {{end -}} 74 | {{""}} responses: 75 | "200": 76 | description: Default Response 77 | {{end -}} 78 | {{end -}} 79 | {{end -}} 80 | 81 | {{- end -}} 82 | {{- define "transform-folder" -}} 83 | {{$global := . -}} 84 | {{if (and ._current.name (hasKey $global._current "item")) -}} 85 | {{$_ := set $global "_folder" $global._current.name -}} 86 | {{if eq $global._depth 1}}{{$_ := set $global "_currentTag" list}}{{end -}} 87 | {{if not (hasKey $global._tags ._current.name) -}} 88 | {{$_ := set $global "_currentTag" (append $global._currentTag ._current.name) -}} 89 | {{$_ := set $global._tags ._current.name (dict "description" ._current.description "collisionCount" 0) -}} 90 | {{else -}} 91 | {{$collisionCount := add (get (get $global._tags ._current.name) "collisionCount") 1 -}} 92 | {{$tag := print ._current.name $collisionCount -}} 93 | {{$_ := set $global "_currentTag" (append $global._currentTag $tag) -}} 94 | {{$_ := set (get $global._tags ._current.name) "collisionCount" $collisionCount -}} 95 | {{$_ := set $global._tags $tag (dict "description" ._current.description "collisionCount" 0) -}} 96 | {{end -}} 97 | {{end -}} 98 | {{if (hasKey $global._current "item") -}} 99 | {{$_ := set $global "_depth" (add $global._depth 1) -}} 100 | {{range $item := $global._current.item -}} 101 | {{$_ := set $global "_current" $item -}} 102 | {{template "transform-folder" $global -}} 103 | {{end -}} 104 | {{$_ := set $global "_depth" (sub $global._depth 1) -}} 105 | {{$_ := set $global "_currentTag" (initial $global._currentTag) -}} 106 | {{else -}} 107 | {{template "transform-item" $global -}} 108 | {{end -}} 109 | {{end -}} 110 | {{define "transform-item" -}} 111 | {{$_ := set . "_servers" (append ._servers (print (coalesce ._current.protocol "http") "://" (join "." ._current.request.url.host))) -}} 112 | {{$pathKey := (print "/" (._current.request.url.path | join "/")) -}} 113 | {{$matches := regexFindAll "{{([\\w-]+)}}" $pathKey -1 -}} 114 | {{$pathParameters := list -}} 115 | {{range $matches -}} 116 | {{$pathParameters = append $pathParameters (regexReplaceAll "{{([\\w-]+)}}" . "${1}") -}} 117 | {{end -}} 118 | {{$pathKey := regexReplaceAll "{{([\\w-]+)}}" $pathKey "{${1}}" -}} 119 | {{if not (hasKey ._paths $pathKey) -}} 120 | {{$_ := set ._paths $pathKey dict -}} 121 | {{end -}} 122 | {{$path := (get ._paths $pathKey) -}} 123 | {{$_ := set $path "_pathParameters" $pathParameters -}} 124 | {{$methodKey := lower ._current.request.method -}} 125 | {{if not (hasKey $path $methodKey) -}} 126 | {{$_ := set $path $methodKey dict -}} 127 | {{end -}} 128 | {{$methodObj := get $path $methodKey -}} 129 | {{$_ := set $methodObj "tags" ._currentTag -}} 130 | {{$_ := set $methodObj "summary" ._current.name -}} 131 | {{$_ := set $methodObj "operationId" (print $methodKey (regexReplaceAll "\\W" (nospace (title ._current.name)) "-")) -}} 132 | {{if ._current.request.url.query -}} 133 | {{if not $methodObj.parameters}}{{$_ := set $methodObj "parameters" list}}{{end -}} 134 | {{range ._current.request.url.query -}} 135 | {{$queryParam := dict "name" .key "in" "query" "description" .description "example" .value -}} 136 | {{$_ := set $methodObj "parameters" (append (get $methodObj "parameters") $queryParam) -}} 137 | {{end -}} 138 | {{end -}} 139 | {{if ._current.request.header -}} 140 | {{if not $methodObj.parameters}}{{$_ := set $methodObj "parameters" list}}{{end -}} 141 | {{range ._current.request.header -}} 142 | {{$header := dict "name" .key "in" "header" "description" .description "example" .value -}} 143 | {{$_ := set $methodObj "parameters" (append (get $methodObj "parameters") $header) -}} 144 | {{end -}} 145 | {{end -}} 146 | {{if ._current.request.description}}{{$_ := set $methodObj "description" ._current.request.description}}{{end -}} 147 | {{end -}} -------------------------------------------------------------------------------- /examples/iterate-over-environments/find-environment-with-key.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ $# -lt 1 ]; then 6 | echo "Usage: $0 " 7 | echo "Example: " 8 | echo " $0 apiKey" 9 | exit 1 10 | fi 11 | 12 | SEARCH_KEY="$1" 13 | USERID=$(postmanctl get user -o jsonpath="{.id}") 14 | 15 | postmanctl get env -o jsonpath="{[?(@.owner=='$USERID')].id}" | \ 16 | xargs postmanctl get env -o json | \ 17 | jq '.[] | select(has("values")) | select(.values[].key=="'"$SEARCH_KEY"'") | {id: .id, name: .name}' 18 | -------------------------------------------------------------------------------- /examples/spectral-linting/lint-api-from-postman.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | if [ $# -lt 2 ]; then 6 | echo "Usage: $0 -- " 7 | echo "Examples: " 8 | echo " $0 Cosmos v1.0.0" 9 | echo " $0 Users v1.3.0 -- -q --skip-rule=\"operation-tags\"" 10 | exit 1 11 | fi 12 | 13 | api_name="$1" 14 | api_version_name="$2" 15 | 16 | shift 17 | shift 18 | 19 | spectral_params="" 20 | if [ "$1" = "--" ]; then 21 | shift 22 | spectral_params=$@ 23 | fi 24 | 25 | api_id=$(postmanctl get apis \ 26 | -o jsonpath="{[?(.name == '$api_name')].id}") 27 | 28 | api_version_id=$(postmanctl get api-versions \ 29 | --for-api "$api_id" \ 30 | -o jsonpath="{[?(.name == '$api_version_name')].id}") 31 | 32 | schema=$(postmanctl get schema \ 33 | --for-api "$api_id" \ 34 | --for-api-version "$api_version_id" \ 35 | -o jsonpath="{.schema}") 36 | 37 | echo "$schema" | sh -c "spectral lint $spectral_params" 38 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/kevinswiber/postmanctl 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/Masterminds/sprig/v3 v3.1.0 7 | github.com/fsnotify/fsnotify v1.4.9 // indirect 8 | github.com/imdario/mergo v0.3.9 // indirect 9 | github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de 10 | github.com/mitchellh/go-homedir v1.1.0 11 | github.com/mitchellh/mapstructure v1.2.2 12 | github.com/mitchellh/reflectwalk v1.0.1 // indirect 13 | github.com/pelletier/go-toml v1.7.0 // indirect 14 | github.com/spf13/afero v1.2.2 // indirect 15 | github.com/spf13/cobra v1.0.0 16 | github.com/spf13/jwalterweatherman v1.1.0 // indirect 17 | github.com/spf13/pflag v1.0.5 // indirect 18 | github.com/spf13/viper v1.6.3 19 | github.com/xlab/treeprint v1.0.0 20 | golang.org/x/crypto v0.0.0-20200422194213-44a606286825 21 | golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f // indirect 22 | golang.org/x/text v0.3.2 // indirect 23 | gopkg.in/ini.v1 v1.55.0 // indirect 24 | k8s.io/client-go v11.0.0+incompatible 25 | ) 26 | -------------------------------------------------------------------------------- /internal/runtime/cmd/config.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package cmd 18 | 19 | import ( 20 | "fmt" 21 | "os" 22 | 23 | "github.com/kevinswiber/postmanctl/internal/runtime/config" 24 | "github.com/kevinswiber/postmanctl/pkg/sdk/printers" 25 | "github.com/mitchellh/mapstructure" 26 | "github.com/spf13/cobra" 27 | "github.com/spf13/viper" 28 | "golang.org/x/crypto/ssh/terminal" 29 | ) 30 | 31 | var setContextAPIRoot string 32 | 33 | func init() { 34 | var cmd = &cobra.Command{ 35 | Use: "config", 36 | Short: "Configure access to the Postman API.", 37 | } 38 | 39 | var setContextCmd = &cobra.Command{ 40 | Use: "set-context", 41 | Short: "Create a context for accessing the Postman API.", 42 | Args: cobra.MinimumNArgs(1), 43 | Run: func(cmd *cobra.Command, args []string) { 44 | fmt.Print("Postman API Key: ") 45 | apiKey, err := terminal.ReadPassword(int(os.Stdin.Fd())) 46 | fmt.Printf("\n") 47 | if err != nil { 48 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 49 | os.Exit(1) 50 | } 51 | 52 | cfg = &config.Config{} 53 | if configFileFound { 54 | if err := viper.Unmarshal(cfg); err != nil { 55 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 56 | os.Exit(1) 57 | } 58 | } 59 | 60 | if len(cfg.Contexts) == 0 { 61 | cfg.Contexts = make(map[string]config.Context) 62 | } 63 | 64 | newContext := config.Context{} 65 | if setContextAPIRoot != "" { 66 | newContext.APIRoot = setContextAPIRoot 67 | } 68 | 69 | newContext.APIKey = string(apiKey) 70 | 71 | cfg.Contexts[args[0]] = newContext 72 | cfg.CurrentContext = args[0] 73 | 74 | mergeConfig(cfg) 75 | }, 76 | } 77 | 78 | setContextCmd.Flags().StringVar(&setContextAPIRoot, "api-root", "https://api.postman.com", "API root URL for accessing the Postman API.") 79 | 80 | useContextCmd := &cobra.Command{ 81 | Use: "use-context", 82 | Short: "Use an existing context for postmanctl commands.", 83 | Args: cobra.MinimumNArgs(1), 84 | Run: func(cmd *cobra.Command, args []string) { 85 | cfg = &config.Config{} 86 | if err := viper.Unmarshal(cfg); err != nil { 87 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 88 | os.Exit(1) 89 | } 90 | 91 | cfg.CurrentContext = args[0] 92 | 93 | mergeConfig(cfg) 94 | }, 95 | } 96 | 97 | currentContextCmd := &cobra.Command{ 98 | Use: "current-context", 99 | Short: "Get the currently set context for postmanctl commands.", 100 | Run: func(cmd *cobra.Command, args []string) { 101 | fmt.Println(cfg.CurrentContext) 102 | }, 103 | } 104 | 105 | getContextsCmd := &cobra.Command{ 106 | Use: "get-contexts", 107 | Short: "Shows the list of configured contexts.", 108 | Run: func(cmd *cobra.Command, args []string) { 109 | w := printers.GetNewTabWriter(os.Stdout) 110 | fmt.Fprintln(w, "CURRENT\tNAME\tAPIROOT") 111 | for k, v := range cfg.Contexts { 112 | cur := "" 113 | if k == cfg.CurrentContext { 114 | cur = "*" 115 | } 116 | 117 | fmt.Fprintf(w, "%s\t%s\t%s\n", cur, k, v.APIRoot) 118 | } 119 | 120 | w.Flush() 121 | }, 122 | } 123 | 124 | cmd.AddCommand(setContextCmd, useContextCmd, currentContextCmd, getContextsCmd) 125 | rootCmd.AddCommand(cmd) 126 | } 127 | 128 | func prepareConfig(cfg *config.Config, result *map[string]interface{}) { 129 | if err := mapstructure.Decode(cfg, &result); err != nil { 130 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 131 | os.Exit(1) 132 | } 133 | 134 | contexts := make(map[string]interface{}) 135 | for k, v := range cfg.Contexts { 136 | var vi map[string]interface{} 137 | if err := mapstructure.Decode(v, &vi); err != nil { 138 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 139 | os.Exit(1) 140 | } 141 | contexts[k] = vi 142 | } 143 | 144 | (*result)["contexts"] = contexts 145 | } 146 | 147 | func mergeConfig(cfg *config.Config) { 148 | var result map[string]interface{} 149 | prepareConfig(cfg, &result) 150 | 151 | if err := viper.MergeConfigMap(result); err != nil { 152 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 153 | os.Exit(1) 154 | } 155 | 156 | viper.SetConfigType("yaml") 157 | 158 | if err := viper.WriteConfig(); err != nil { 159 | if err != nil { 160 | switch err.(type) { 161 | case viper.ConfigFileNotFoundError: 162 | if err := viper.SafeWriteConfig(); err != nil { 163 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 164 | os.Exit(1) 165 | } 166 | default: 167 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 168 | os.Exit(1) 169 | } 170 | } 171 | } 172 | 173 | fmt.Println("config file written to $HOME/.postmanctl.yaml") 174 | } 175 | -------------------------------------------------------------------------------- /internal/runtime/cmd/create.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package cmd 18 | 19 | import ( 20 | "context" 21 | "errors" 22 | "fmt" 23 | "os" 24 | 25 | "github.com/kevinswiber/postmanctl/pkg/sdk/resources" 26 | "github.com/spf13/cobra" 27 | ) 28 | 29 | func init() { 30 | createCmd := &cobra.Command{ 31 | Use: "create", 32 | Short: "Create new Postman resources.", 33 | PersistentPreRunE: func(cmd *cobra.Command, args []string) error { 34 | stat, _ := os.Stdin.Stat() 35 | if (stat.Mode() & os.ModeCharDevice) == 0 { 36 | inputReader = os.Stdin 37 | } else { 38 | if inputFile == "" { 39 | return errors.New("flag \"filename\" not set, use \"--filename\" or stdin") 40 | } 41 | } 42 | 43 | return nil 44 | }, 45 | } 46 | createCmd.PersistentFlags().StringVarP(&inputFile, "filename", "f", "", "the filename used to create the resource (required when not using data from stdin)") 47 | 48 | createCmd.AddCommand( 49 | generateCreateSubcommand(resources.CollectionType, "collection", []string{"co"}), 50 | generateCreateSubcommand(resources.EnvironmentType, "environment", []string{"env"}), 51 | generateCreateSubcommand(resources.MonitorType, "monitor", []string{"mon"}), 52 | generateCreateSubcommand(resources.MockType, "mock", []string{}), 53 | generateCreateSubcommand(resources.WorkspaceType, "workspace", []string{"ws"}), 54 | generateCreateSubcommand(resources.APIType, "api", []string{}), 55 | generateCreateSubcommand(resources.APIVersionType, "api-version", []string{}), 56 | generateCreateSubcommand(resources.SchemaType, "schema", []string{}), 57 | ) 58 | 59 | rootCmd.AddCommand(createCmd) 60 | } 61 | 62 | func generateCreateSubcommand(t resources.ResourceType, use string, aliases []string) *cobra.Command { 63 | cmd := cobra.Command{ 64 | Use: use, 65 | Aliases: aliases, 66 | RunE: func(cmd *cobra.Command, args []string) error { 67 | return createResource(t) 68 | }, 69 | } 70 | 71 | cmd.Flags().StringVarP(&usingWorkspace, "workspace", "w", "", "workspace for create operation") 72 | 73 | if t == resources.APIVersionType || t == resources.SchemaType { 74 | cmd.Flags().StringVar(&forAPI, "for-api", "", "the associated API ID (required)") 75 | cmd.MarkFlagRequired("for-api") 76 | } 77 | 78 | if t == resources.SchemaType { 79 | cmd.Flags().StringVar(&forAPIVersion, "for-api-version", "", "the associated API Version ID (required)") 80 | cmd.MarkFlagRequired("for-api-version") 81 | } 82 | 83 | return &cmd 84 | } 85 | 86 | func createResource(t resources.ResourceType) error { 87 | if inputReader == nil { 88 | r, err := os.Open(inputFile) 89 | 90 | if err != nil { 91 | return err 92 | } 93 | 94 | defer r.Close() 95 | 96 | inputReader = r 97 | } 98 | 99 | var ( 100 | id string 101 | err error 102 | ) 103 | 104 | ctx := context.Background() 105 | switch t { 106 | case resources.CollectionType: 107 | id, err = service.CreateCollectionFromReader(ctx, inputReader, usingWorkspace) 108 | case resources.EnvironmentType: 109 | id, err = service.CreateEnvironmentFromReader(ctx, inputReader, usingWorkspace) 110 | case resources.MockType: 111 | id, err = service.CreateMockFromReader(ctx, inputReader, usingWorkspace) 112 | case resources.MonitorType: 113 | id, err = service.CreateMonitorFromReader(ctx, inputReader, usingWorkspace) 114 | case resources.WorkspaceType: 115 | id, err = service.CreateWorkspaceFromReader(ctx, inputReader, usingWorkspace) 116 | case resources.APIType: 117 | id, err = service.CreateAPIFromReader(ctx, inputReader, usingWorkspace) 118 | case resources.APIVersionType: 119 | id, err = service.CreateAPIVersionFromReader(ctx, inputReader, usingWorkspace, forAPI) 120 | case resources.SchemaType: 121 | id, err = service.CreateSchemaFromReader(ctx, inputReader, usingWorkspace, forAPI, forAPIVersion) 122 | } 123 | 124 | if err != nil { 125 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 126 | os.Exit(1) 127 | } 128 | 129 | fmt.Println(id) 130 | 131 | return nil 132 | } 133 | -------------------------------------------------------------------------------- /internal/runtime/cmd/delete.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package cmd 18 | 19 | import ( 20 | "context" 21 | "fmt" 22 | "os" 23 | 24 | "github.com/kevinswiber/postmanctl/pkg/sdk/resources" 25 | "github.com/spf13/cobra" 26 | ) 27 | 28 | func init() { 29 | deleteCmd := &cobra.Command{ 30 | Use: "delete", 31 | Short: "Delete existing Postman resources.", 32 | } 33 | 34 | deleteCmd.AddCommand( 35 | generateDeleteSubcommand(resources.CollectionType, "collection", []string{"co"}), 36 | generateDeleteSubcommand(resources.EnvironmentType, "environment", []string{"env"}), 37 | generateDeleteSubcommand(resources.MonitorType, "monitor", []string{"mon"}), 38 | generateDeleteSubcommand(resources.MockType, "mock", []string{}), 39 | generateDeleteSubcommand(resources.WorkspaceType, "workspace", []string{"ws"}), 40 | generateDeleteSubcommand(resources.APIType, "api", []string{}), 41 | generateDeleteSubcommand(resources.APIVersionType, "api-version", []string{}), 42 | generateDeleteSubcommand(resources.SchemaType, "schema", []string{}), 43 | ) 44 | 45 | rootCmd.AddCommand(deleteCmd) 46 | } 47 | 48 | func generateDeleteSubcommand(t resources.ResourceType, use string, aliases []string) *cobra.Command { 49 | cmd := cobra.Command{ 50 | Use: use, 51 | Aliases: aliases, 52 | Args: cobra.MinimumNArgs(1), 53 | RunE: func(cmd *cobra.Command, args []string) error { 54 | return deleteResource(t, args[0]) 55 | }, 56 | } 57 | 58 | if t == resources.APIVersionType || t == resources.SchemaType { 59 | cmd.Flags().StringVar(&forAPI, "for-api", "", "the associated API ID (required)") 60 | cmd.MarkFlagRequired("for-api") 61 | } 62 | 63 | if t == resources.SchemaType { 64 | cmd.Flags().StringVar(&forAPIVersion, "for-api-version", "", "the associated API Version ID (required)") 65 | cmd.MarkFlagRequired("for-api-version") 66 | } 67 | 68 | return &cmd 69 | } 70 | 71 | func deleteResource(t resources.ResourceType, resourceID string) error { 72 | var ( 73 | id string 74 | err error 75 | ) 76 | 77 | ctx := context.Background() 78 | switch t { 79 | case resources.CollectionType: 80 | id, err = service.DeleteCollection(ctx, resourceID) 81 | case resources.EnvironmentType: 82 | id, err = service.DeleteEnvironment(ctx, resourceID) 83 | case resources.MockType: 84 | id, err = service.DeleteMock(ctx, resourceID) 85 | case resources.MonitorType: 86 | id, err = service.DeleteMonitor(ctx, resourceID) 87 | case resources.APIType: 88 | id, err = service.DeleteAPI(ctx, resourceID) 89 | case resources.APIVersionType: 90 | id, err = service.DeleteAPIVersion(ctx, forAPI, resourceID) 91 | case resources.SchemaType: 92 | id, err = service.DeleteSchema(ctx, forAPI, forAPIVersion, resourceID) 93 | } 94 | 95 | if err != nil { 96 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 97 | os.Exit(1) 98 | } 99 | 100 | fmt.Println(id) 101 | 102 | return nil 103 | } 104 | -------------------------------------------------------------------------------- /internal/runtime/cmd/fork.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package cmd 18 | 19 | import ( 20 | "context" 21 | "fmt" 22 | "os" 23 | 24 | "github.com/spf13/cobra" 25 | ) 26 | 27 | func init() { 28 | var cmd = &cobra.Command{ 29 | Use: "fork", 30 | Short: "Create a fork of a Postman resource.", 31 | } 32 | 33 | var forkCollectionCmd = &cobra.Command{ 34 | Use: "collection", 35 | Aliases: []string{"co"}, 36 | Args: cobra.MinimumNArgs(1), 37 | Run: func(cmd *cobra.Command, args []string) { 38 | id, err := service.ForkCollection(context.Background(), args[0], usingWorkspace, forkLabel) 39 | if err != nil { 40 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 41 | os.Exit(1) 42 | } 43 | 44 | fmt.Println(id) 45 | }, 46 | } 47 | 48 | forkCollectionCmd.Flags().StringVarP(&usingWorkspace, "workspace", "w", "", "workspace for fork operation") 49 | forkCollectionCmd.Flags().StringVarP(&forkLabel, "label", "l", "", "label to associate with the forked collection (required)") 50 | forkCollectionCmd.MarkFlagRequired("label") 51 | 52 | cmd.AddCommand(forkCollectionCmd) 53 | rootCmd.AddCommand(cmd) 54 | } 55 | -------------------------------------------------------------------------------- /internal/runtime/cmd/merge.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package cmd 18 | 19 | import ( 20 | "context" 21 | "fmt" 22 | "os" 23 | 24 | "github.com/spf13/cobra" 25 | ) 26 | 27 | func init() { 28 | var cmd = &cobra.Command{ 29 | Use: "merge", 30 | Short: "Merge a fork of a Postman resource.", 31 | } 32 | 33 | var mergeCollectionCmd = &cobra.Command{ 34 | Use: "collection", 35 | Aliases: []string{"co"}, 36 | Args: cobra.MinimumNArgs(1), 37 | Run: func(cmd *cobra.Command, args []string) { 38 | id, err := service.MergeCollection(context.Background(), args[0], mergeCollection, mergeStrategy) 39 | if err != nil { 40 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 41 | os.Exit(1) 42 | } 43 | 44 | fmt.Println(id) 45 | }, 46 | } 47 | 48 | mergeCollectionCmd.Flags().StringVar(&mergeCollection, "to", "", "the destination collection to receive the merged changes") 49 | mergeCollectionCmd.MarkFlagRequired("to") 50 | 51 | mergeCollectionCmd.Flags().StringVarP(&mergeStrategy, "strategy", "s", "", "strategy for merging fork (optional, values: deleteSource, updateSourceWithDestination)") 52 | 53 | cmd.AddCommand(mergeCollectionCmd) 54 | rootCmd.AddCommand(cmd) 55 | } 56 | -------------------------------------------------------------------------------- /internal/runtime/cmd/replace.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package cmd 18 | 19 | import ( 20 | "context" 21 | "errors" 22 | "fmt" 23 | "os" 24 | 25 | "github.com/kevinswiber/postmanctl/pkg/sdk/resources" 26 | "github.com/spf13/cobra" 27 | ) 28 | 29 | func init() { 30 | replaceCmd := &cobra.Command{ 31 | Use: "replace", 32 | Short: "Replace existing Postman resources.", 33 | PersistentPreRunE: func(cmd *cobra.Command, args []string) error { 34 | stat, _ := os.Stdin.Stat() 35 | if (stat.Mode() & os.ModeCharDevice) == 0 { 36 | inputReader = os.Stdin 37 | } else { 38 | if inputFile == "" { 39 | return errors.New("flag \"filename\" not set, use \"--filename\" or stdin") 40 | } 41 | } 42 | 43 | return nil 44 | }, 45 | } 46 | replaceCmd.PersistentFlags().StringVarP(&inputFile, "filename", "f", "", "the filename used to replace the resource (required when not using data from stdin)") 47 | 48 | replaceCmd.AddCommand( 49 | generateReplaceSubcommand(resources.CollectionType, "collection", []string{"co"}), 50 | generateReplaceSubcommand(resources.EnvironmentType, "environment", []string{"env"}), 51 | generateReplaceSubcommand(resources.MonitorType, "monitor", []string{"mon"}), 52 | generateReplaceSubcommand(resources.MockType, "mock", []string{}), 53 | generateReplaceSubcommand(resources.WorkspaceType, "workspace", []string{"ws"}), 54 | generateReplaceSubcommand(resources.APIType, "api", []string{}), 55 | generateReplaceSubcommand(resources.APIVersionType, "api-version", []string{}), 56 | generateReplaceSubcommand(resources.SchemaType, "schema", []string{}), 57 | ) 58 | 59 | rootCmd.AddCommand(replaceCmd) 60 | } 61 | 62 | func generateReplaceSubcommand(t resources.ResourceType, use string, aliases []string) *cobra.Command { 63 | cmd := cobra.Command{ 64 | Use: use, 65 | Aliases: aliases, 66 | Args: cobra.MinimumNArgs(1), 67 | RunE: func(cmd *cobra.Command, args []string) error { 68 | return replaceResource(t, args[0]) 69 | }, 70 | } 71 | 72 | if t == resources.APIVersionType || t == resources.SchemaType { 73 | cmd.Flags().StringVar(&forAPI, "for-api", "", "the associated API ID (required)") 74 | cmd.MarkFlagRequired("for-api") 75 | } 76 | 77 | if t == resources.SchemaType { 78 | cmd.Flags().StringVar(&forAPIVersion, "for-api-version", "", "the associated API Version ID (required)") 79 | cmd.MarkFlagRequired("for-api-version") 80 | } 81 | 82 | return &cmd 83 | } 84 | 85 | func replaceResource(t resources.ResourceType, resourceID string) error { 86 | if inputReader == nil { 87 | r, err := os.Open(inputFile) 88 | 89 | if err != nil { 90 | return err 91 | } 92 | 93 | defer r.Close() 94 | 95 | inputReader = r 96 | } 97 | 98 | var ( 99 | id string 100 | err error 101 | ) 102 | 103 | ctx := context.Background() 104 | switch t { 105 | case resources.CollectionType: 106 | id, err = service.ReplaceCollectionFromReader(ctx, inputReader, resourceID) 107 | case resources.EnvironmentType: 108 | id, err = service.ReplaceEnvironmentFromReader(ctx, inputReader, resourceID) 109 | case resources.MockType: 110 | id, err = service.ReplaceMockFromReader(ctx, inputReader, resourceID) 111 | case resources.MonitorType: 112 | id, err = service.ReplaceMonitorFromReader(ctx, inputReader, resourceID) 113 | case resources.WorkspaceType: 114 | id, err = service.ReplaceWorkspaceFromReader(ctx, inputReader, resourceID) 115 | case resources.APIType: 116 | id, err = service.ReplaceAPIFromReader(ctx, inputReader, resourceID) 117 | case resources.APIVersionType: 118 | id, err = service.ReplaceAPIVersionFromReader(ctx, inputReader, forAPI, resourceID) 119 | case resources.SchemaType: 120 | id, err = service.ReplaceSchemaFromReader(ctx, inputReader, resourceID, forAPI, forAPIVersion) 121 | } 122 | 123 | if err != nil { 124 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 125 | os.Exit(1) 126 | } 127 | 128 | fmt.Println(id) 129 | 130 | return nil 131 | } 132 | -------------------------------------------------------------------------------- /internal/runtime/cmd/root.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package cmd 18 | 19 | import ( 20 | "fmt" 21 | "io" 22 | "net/http" 23 | "net/url" 24 | "os" 25 | "strings" 26 | 27 | "github.com/kevinswiber/postmanctl/internal/runtime/config" 28 | "github.com/kevinswiber/postmanctl/pkg/sdk" 29 | "github.com/kevinswiber/postmanctl/pkg/sdk/client" 30 | "github.com/spf13/cobra" 31 | "github.com/spf13/cobra/doc" 32 | 33 | homedir "github.com/mitchellh/go-homedir" 34 | "github.com/spf13/viper" 35 | ) 36 | 37 | var ( 38 | cfgFile string 39 | cfg *config.Config 40 | configContext config.Context 41 | configContextKey string 42 | options *client.Options 43 | service *sdk.Service 44 | forAPI string 45 | forAPIVersion string 46 | inputFile string 47 | inputReader io.Reader 48 | usingWorkspace string 49 | forkLabel string 50 | mergeStrategy string 51 | mergeCollection string 52 | ) 53 | 54 | var configContextFound = true 55 | var configFileFound = true 56 | var configContextSet = true 57 | 58 | var rootCmd = &cobra.Command{ 59 | Use: "postmanctl", 60 | Short: "Controls the Postman API", 61 | PersistentPreRun: func(cmd *cobra.Command, args []string) { 62 | if !configFileFound || !configContextFound { 63 | processArgs := os.Args 64 | if len(processArgs) > 2 { 65 | command := processArgs[1] 66 | subcommand := processArgs[2] 67 | 68 | if command == "config" && subcommand != "current-context" && subcommand != "get-contexts" { 69 | return 70 | } 71 | } 72 | 73 | if !configContextSet { 74 | fmt.Fprintln(os.Stderr, "error: context is not set, run: postmanctl config use-context --help") 75 | } else if !configContextFound { 76 | fmt.Fprintf(os.Stderr, "error: context '%s' is not configured, run: postmanctl config set-context --help\n", configContextKey) 77 | } else if !configFileFound { 78 | fmt.Fprintln(os.Stderr, "error: config file not found at $HOME/.postmanctl.yaml, run: postmanctl config set-context --help") 79 | } 80 | 81 | os.Exit(1) 82 | } 83 | }, 84 | } 85 | 86 | // Execute adds all child commands to the root command and sets flags appropriately. 87 | // This is called by main.main(). It only needs to happen once to the rootCmd. 88 | func Execute() { 89 | if err := rootCmd.Execute(); err != nil { 90 | fmt.Println(err) 91 | os.Exit(1) 92 | } 93 | } 94 | 95 | // GenMarkdownTree generates Markdown documentation for postmanctl. 96 | func GenMarkdownTree(path string) error { 97 | return doc.GenMarkdownTree(rootCmd, path) 98 | } 99 | 100 | func init() { 101 | cobra.OnInitialize(initConfig) 102 | cobra.OnInitialize(initAPIClientConfig) 103 | rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.postmanctl.yaml)") 104 | rootCmd.PersistentFlags().StringVar(&configContextKey, "context", "", "context to use, overrides the current context in the config file") 105 | } 106 | 107 | // initConfig reads in config file and ENV variables if set. 108 | func initConfig() { 109 | if cfgFile != "" { 110 | // Use config file from the flag. 111 | viper.SetConfigFile(cfgFile) 112 | } else { 113 | // Find home directory. 114 | home, err := homedir.Dir() 115 | if err != nil { 116 | fmt.Println(err) 117 | os.Exit(1) 118 | } 119 | 120 | // Search config in home directory with name ".postmanctl" (without extension). 121 | viper.AddConfigPath(home) 122 | viper.SetConfigName(".postmanctl") 123 | } 124 | 125 | viper.SetEnvPrefix("POSTMANCTL_") 126 | viper.AutomaticEnv() // read in environment variables that match 127 | 128 | // If a config file is found, read it in. 129 | if err := viper.ReadInConfig(); err != nil { 130 | if _, ok := err.(viper.ConfigFileNotFoundError); ok { 131 | configFileFound = false 132 | } else { 133 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 134 | os.Exit(1) 135 | } 136 | } 137 | 138 | cfg = &config.Config{} 139 | if err := viper.Unmarshal(cfg); err != nil { 140 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 141 | os.Exit(1) 142 | } 143 | 144 | if !configFileFound { 145 | return 146 | } 147 | 148 | if configContextKey == "" { 149 | configContextKey = cfg.CurrentContext 150 | } 151 | 152 | // viper keys are case-insensitive 153 | if val, ok := cfg.Contexts[strings.ToLower(configContextKey)]; ok { 154 | configContext = val 155 | if len(configContext.APIRoot) == 0 { 156 | configContext.APIRoot = "https://api.postman.com" 157 | } 158 | } else { 159 | context := cfg.CurrentContext 160 | configContextFound = false 161 | 162 | if context == "" { 163 | configContextSet = false 164 | return 165 | } 166 | } 167 | } 168 | 169 | func initAPIClientConfig() { 170 | u, err := url.Parse(configContext.APIRoot) 171 | if err != nil { 172 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 173 | os.Exit(1) 174 | } 175 | 176 | options = client.NewOptions(u, configContext.APIKey, http.DefaultClient) 177 | service = sdk.NewService(options) 178 | } 179 | -------------------------------------------------------------------------------- /internal/runtime/cmd/run.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package cmd 18 | 19 | import ( 20 | "context" 21 | "encoding/json" 22 | "fmt" 23 | "os" 24 | 25 | "github.com/spf13/cobra" 26 | ) 27 | 28 | func init() { 29 | var cmd = &cobra.Command{ 30 | Use: "run", 31 | Short: "Execute runnable Postman resources.", 32 | } 33 | 34 | var runMonitorCmd = &cobra.Command{ 35 | Use: "monitor", 36 | Aliases: []string{"mon"}, 37 | Args: cobra.MinimumNArgs(1), 38 | Run: func(cmd *cobra.Command, args []string) { 39 | msg, err := service.RunMonitor(context.Background(), args[0]) 40 | if err != nil { 41 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 42 | os.Exit(1) 43 | } 44 | 45 | b, err := json.MarshalIndent(&msg, "", " ") 46 | if err != nil { 47 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 48 | os.Exit(1) 49 | } 50 | 51 | fmt.Println(string(b)) 52 | }, 53 | } 54 | 55 | cmd.AddCommand(runMonitorCmd) 56 | rootCmd.AddCommand(cmd) 57 | } 58 | -------------------------------------------------------------------------------- /internal/runtime/cmd/util.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package cmd 18 | 19 | import ( 20 | "bytes" 21 | "encoding/json" 22 | "fmt" 23 | "io/ioutil" 24 | "os" 25 | "strings" 26 | "text/template" 27 | 28 | sprig "github.com/Masterminds/sprig/v3" 29 | "github.com/kevinswiber/postmanctl/pkg/sdk/client" 30 | "github.com/kevinswiber/postmanctl/pkg/sdk/printers" 31 | "github.com/kevinswiber/postmanctl/pkg/sdk/resources" 32 | "k8s.io/client-go/util/jsonpath" 33 | ) 34 | 35 | func handleResponseError(err error) error { 36 | if err, ok := err.(*client.RequestError); ok { 37 | fmt.Fprintln(os.Stderr, err.Error()) 38 | os.Exit(1) 39 | return nil 40 | } 41 | 42 | return err 43 | } 44 | 45 | func printGetOutput(r interface{}) { 46 | if r == nil { 47 | return 48 | } 49 | 50 | if outputFormat.value == "json" { 51 | t, err := json.MarshalIndent(&r, "", " ") 52 | if err != nil { 53 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 54 | } 55 | fmt.Println(string(t)) 56 | } else if strings.HasPrefix(outputFormat.value, "jsonpath=") { 57 | tmpl := outputFormat.value[9:] 58 | j := jsonpath.New("out") 59 | if err := j.Parse(tmpl); err != nil { 60 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 61 | os.Exit(1) 62 | } 63 | 64 | t, err := json.Marshal(&r) 65 | if err != nil { 66 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 67 | os.Exit(1) 68 | } 69 | 70 | var queryObj interface{} = map[string]interface{}{} 71 | if err := json.Unmarshal(t, &queryObj); err != nil { 72 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 73 | os.Exit(1) 74 | } 75 | 76 | buf := bytes.NewBuffer(nil) 77 | err = j.Execute(buf, queryObj) 78 | if err != nil { 79 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 80 | } 81 | 82 | fmt.Println(buf) 83 | } else if strings.HasPrefix(outputFormat.value, "go-template-file=") { 84 | templateFile := outputFormat.value[17:] 85 | tmpl, err := ioutil.ReadFile(templateFile) 86 | if err != nil { 87 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 88 | os.Exit(1) 89 | } 90 | 91 | h, err := template.New("Text Template").Funcs(sprig.TxtFuncMap()).Parse(string(tmpl)) 92 | if err != nil { 93 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 94 | os.Exit(1) 95 | } 96 | 97 | t, err := json.Marshal(&r) 98 | if err != nil { 99 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 100 | os.Exit(1) 101 | } 102 | 103 | var queryObj interface{} = map[string]interface{}{} 104 | if err := json.Unmarshal(t, &queryObj); err != nil { 105 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 106 | os.Exit(1) 107 | } 108 | 109 | var buf bytes.Buffer 110 | if err := h.Execute(&buf, queryObj); err != nil { 111 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 112 | os.Exit(1) 113 | } 114 | 115 | fmt.Println(buf.String()) 116 | } else { 117 | var f resources.Formatter = r.(resources.Formatter) 118 | printTable(f) 119 | } 120 | } 121 | 122 | func printTable(f resources.Formatter) { 123 | w := printers.GetNewTabWriter(os.Stdout) 124 | printer := printers.NewTablePrinter(printers.PrintOptions{}) 125 | printer.PrintResource(f, w) 126 | } 127 | -------------------------------------------------------------------------------- /internal/runtime/cmd/version.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package cmd 18 | 19 | import ( 20 | "encoding/json" 21 | "errors" 22 | "fmt" 23 | "os" 24 | 25 | "github.com/spf13/cobra" 26 | ) 27 | 28 | var ( 29 | version = "0.1.0" 30 | commit = "snapshot" 31 | date = "" 32 | ) 33 | 34 | type versionInfo struct { 35 | Version string `json:"version"` 36 | Commit string `json:"commit"` 37 | Date string `json:"date"` 38 | } 39 | 40 | var versionOutputFormat VersionOutputFormatValue 41 | 42 | // VersionOutputFormatValue is a custom Value for the output flag that validates. 43 | type VersionOutputFormatValue struct { 44 | value string 45 | } 46 | 47 | // String returns a string representation of this flag. 48 | func (o *VersionOutputFormatValue) String() string { 49 | return o.value 50 | } 51 | 52 | // Set creates the flag value. 53 | func (o *VersionOutputFormatValue) Set(v string) error { 54 | if v == "json" || v == "short" { 55 | o.value = v 56 | return nil 57 | } 58 | 59 | return errors.New("output format must be json or short") 60 | } 61 | 62 | // Type returns the type of this value. 63 | func (o *VersionOutputFormatValue) Type() string { 64 | return "string" 65 | } 66 | 67 | func init() { 68 | var cmd = &cobra.Command{ 69 | Use: "version", 70 | Short: "Print version information for postmanctl.", 71 | Run: func(cmd *cobra.Command, args []string) { 72 | v := versionInfo{ 73 | Version: version, 74 | Commit: commit, 75 | Date: date, 76 | } 77 | 78 | f := versionOutputFormat.value 79 | if f == "short" { 80 | fmt.Printf("Version: %s\n", v.Version) 81 | fmt.Printf("Commit: %s\n", v.Commit) 82 | fmt.Printf("Date: %s\n", v.Date) 83 | } else if f == "json" { 84 | p, err := json.MarshalIndent(&v, "", " ") 85 | 86 | if err != nil { 87 | fmt.Fprintf(os.Stderr, "error: %s\n", err) 88 | os.Exit(1) 89 | return 90 | } 91 | 92 | fmt.Println(string(p)) 93 | } else { 94 | fmt.Printf("%#v\n", v) 95 | } 96 | }, 97 | } 98 | 99 | cmd.Flags().VarP(&versionOutputFormat, "output", "o", "output format (json, short)") 100 | rootCmd.AddCommand(cmd) 101 | } 102 | -------------------------------------------------------------------------------- /internal/runtime/config/config.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package config 18 | 19 | // Config is a struct representation of a postmanctl config file. 20 | type Config struct { 21 | CurrentContext string `mapstructure:"currentContext"` 22 | Contexts map[string]Context `mapstructure:"contexts"` 23 | } 24 | 25 | // Context models the current Postman API context as a struct. 26 | type Context struct { 27 | APIKey string `mapstructure:"apiKey"` 28 | APIRoot string `mapstructure:"apiRoot"` 29 | } 30 | -------------------------------------------------------------------------------- /output/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kevinswiber/postmanctl/a5b28e7fa52d269682181510d67e090cbd70ff0f/output/.gitkeep -------------------------------------------------------------------------------- /pkg/sdk/client/options.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package client 18 | 19 | import ( 20 | "net/http" 21 | "net/url" 22 | "strings" 23 | ) 24 | 25 | // Options allows for storing a base URL and containing common functionality. 26 | type Options struct { 27 | base *url.URL 28 | APIKey string 29 | Client *http.Client 30 | } 31 | 32 | // NewOptions creates a new instance of the Postman API client options. 33 | func NewOptions(baseURL *url.URL, apiKey string, client *http.Client) *Options { 34 | base := *baseURL 35 | if !strings.HasSuffix(base.Path, "/") { 36 | base.Path += "/" 37 | } 38 | base.RawQuery = "" 39 | base.Fragment = "" 40 | 41 | return &Options{ 42 | base: &base, 43 | APIKey: apiKey, 44 | Client: client, 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /pkg/sdk/client/request.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package client 18 | 19 | import ( 20 | "context" 21 | "encoding/json" 22 | "fmt" 23 | "io" 24 | "io/ioutil" 25 | "net/http" 26 | "net/url" 27 | "path" 28 | "strings" 29 | 30 | "github.com/kevinswiber/postmanctl/pkg/sdk/resources" 31 | ) 32 | 33 | // RequestError represents an error from the Postman API. 34 | type RequestError struct { 35 | StatusCode int 36 | Name string 37 | Message string 38 | Details map[string]interface{} 39 | } 40 | 41 | // NewRequestError creates a new RequestError for Postman API responses. 42 | func NewRequestError(code int, name string, message string, details map[string]interface{}) *RequestError { 43 | return &RequestError{ 44 | StatusCode: code, 45 | Name: name, 46 | Message: message, 47 | Details: details, 48 | } 49 | } 50 | 51 | func (e *RequestError) Error() string { 52 | return fmt.Sprintf("status code: %d, name: %s, message: %s, details %s", e.StatusCode, 53 | e.Name, e.Message, e.Details) 54 | } 55 | 56 | // Request holds state for a Postman API request. 57 | type Request struct { 58 | ctx context.Context 59 | options *Options 60 | method string 61 | path string 62 | requestReader io.Reader 63 | result interface{} 64 | headers http.Header 65 | params url.Values 66 | err error 67 | } 68 | 69 | // NewRequest initializes a Postman API Request. 70 | func NewRequest(c *Options) *Request { 71 | return NewRequestWithContext(context.Background(), c) 72 | } 73 | 74 | // NewRequestWithContext intiializes a Postman API Request with a 75 | // given context. 76 | func NewRequestWithContext(ctx context.Context, c *Options) *Request { 77 | r := &Request{ 78 | ctx: ctx, 79 | options: c, 80 | } 81 | 82 | if r.headers == nil { 83 | r.headers = http.Header{} 84 | } 85 | r.headers.Add("X-API-Key", c.APIKey) 86 | 87 | return r 88 | } 89 | 90 | // AddHeader adds a header to the request. 91 | func (r *Request) AddHeader(key string, value string) *Request { 92 | r.headers.Add(key, value) 93 | return r 94 | } 95 | 96 | // Param sets a query parameter. 97 | func (r *Request) Param(k, v string) *Request { 98 | if r.params == nil { 99 | r.params = make(url.Values) 100 | } 101 | 102 | r.params.Add(k, v) 103 | 104 | return r 105 | } 106 | 107 | // Params sets all query parameters. 108 | func (r *Request) Params(params map[string]string) *Request { 109 | if r.params == nil { 110 | r.params = make(url.Values) 111 | } 112 | 113 | for k, v := range params { 114 | r.params.Add(k, v) 115 | } 116 | 117 | return r 118 | } 119 | 120 | // Method sets the HTTP method of the request. 121 | func (r *Request) Method(m string) *Request { 122 | r.method = m 123 | return r 124 | } 125 | 126 | // Get sets the HTTP method to GET 127 | func (r *Request) Get() *Request { 128 | r.method = "GET" 129 | return r 130 | } 131 | 132 | // Post sets the HTTP method to POST 133 | func (r *Request) Post() *Request { 134 | r.method = "POST" 135 | return r 136 | } 137 | 138 | // Put sets the HTTP method to PUT 139 | func (r *Request) Put() *Request { 140 | r.method = "PUT" 141 | return r 142 | } 143 | 144 | // Delete sets the HTTP method to DELETE 145 | func (r *Request) Delete() *Request { 146 | r.method = "DELETE" 147 | return r 148 | } 149 | 150 | // Path sets the path of the HTTP request. 151 | func (r *Request) Path(p ...string) *Request { 152 | r.path = path.Join(p...) 153 | return r 154 | } 155 | 156 | // Body sets an input resource for the request 157 | func (r *Request) Body(reader io.Reader) *Request { 158 | r.requestReader = reader 159 | return r 160 | } 161 | 162 | // Into sets a destination resource for the output response 163 | func (r *Request) Into(o interface{}) *Request { 164 | r.result = o 165 | return r 166 | } 167 | 168 | // URL returns a complete URL for the current request. 169 | func (r *Request) URL() *url.URL { 170 | finalURL := &url.URL{} 171 | if r.options.base != nil { 172 | *finalURL = *r.options.base 173 | } 174 | finalURL.Path = r.path 175 | finalURL.RawQuery = r.params.Encode() 176 | 177 | return finalURL 178 | } 179 | 180 | // Do executes the HTTP request. 181 | func (r *Request) Do() (*http.Response, error) { 182 | url := r.URL().String() 183 | 184 | req, err := http.NewRequestWithContext(r.ctx, r.method, url, r.requestReader) 185 | if err != nil { 186 | return nil, err 187 | } 188 | req.Header = r.headers 189 | client := r.options.Client 190 | if client == nil { 191 | client = http.DefaultClient 192 | } 193 | 194 | resp, err := client.Do(req) 195 | if err != nil { 196 | return nil, err 197 | } 198 | 199 | if resp.StatusCode != http.StatusOK { 200 | defer resp.Body.Close() 201 | body, err := ioutil.ReadAll(resp.Body) 202 | 203 | if err != nil { 204 | return resp, err 205 | } 206 | 207 | var e resources.ErrorResponse 208 | if len(body) > 0 { 209 | err = json.Unmarshal(body, &e) 210 | } 211 | 212 | var errorMessage *RequestError 213 | if err == nil { 214 | errorMessage = NewRequestError(resp.StatusCode, e.Error.Name, e.Error.Message, e.Error.Details) 215 | } else { 216 | msg := []string{err.Error(), e.Error.Message} 217 | errorMessage = NewRequestError(resp.StatusCode, e.Error.Name, strings.Join(msg, " | "), e.Error.Details) 218 | } 219 | r.err = errorMessage 220 | return nil, errorMessage 221 | } 222 | 223 | if r.result != nil { 224 | defer resp.Body.Close() 225 | body, err := ioutil.ReadAll(resp.Body) 226 | 227 | if err != nil { 228 | return resp, err 229 | } 230 | 231 | if err := json.Unmarshal(body, &r.result); err != nil { 232 | return nil, err 233 | } 234 | } 235 | 236 | return resp, nil 237 | } 238 | -------------------------------------------------------------------------------- /pkg/sdk/helpers_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package sdk_test 18 | 19 | import ( 20 | "errors" 21 | "net/http" 22 | "net/http/httptest" 23 | "net/url" 24 | "testing" 25 | 26 | "github.com/kevinswiber/postmanctl/pkg/sdk" 27 | "github.com/kevinswiber/postmanctl/pkg/sdk/client" 28 | ) 29 | 30 | func NewTestService(server *httptest.Server) *sdk.Service { 31 | u, _ := url.Parse(server.URL) 32 | options := client.NewOptions(u, "", http.DefaultClient) 33 | 34 | return sdk.NewService(options) 35 | } 36 | 37 | func ensurePath(t *testing.T, mux *http.ServeMux, path string) { 38 | mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 39 | t.Errorf("API call path is incorrect, have: %s, want: %s", r.URL, path) 40 | }) 41 | } 42 | 43 | func setupService(mux **http.ServeMux, service **sdk.Service) func() { 44 | *mux = http.NewServeMux() 45 | server := httptest.NewServer(*mux) 46 | *service = NewTestService(server) 47 | 48 | return func() { 49 | server.Close() 50 | } 51 | } 52 | 53 | type errReader string 54 | 55 | func (errReader) Read(p []byte) (n int, err error) { 56 | return 0, errors.New("errReader") 57 | } 58 | -------------------------------------------------------------------------------- /pkg/sdk/printers/printers.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package printers 18 | 19 | import ( 20 | "io" 21 | 22 | "github.com/kevinswiber/postmanctl/pkg/sdk/resources" 23 | ) 24 | 25 | // ResourcePrinter writes an output of API resources. 26 | type ResourcePrinter interface { 27 | PrintResource(resources.Formatter, io.Writer) 28 | } 29 | 30 | // PrintOptions holds various options used in ResourcePrinters. 31 | type PrintOptions struct { 32 | NoHeaders bool 33 | } 34 | -------------------------------------------------------------------------------- /pkg/sdk/printers/tableprinter.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package printers 18 | 19 | import ( 20 | "fmt" 21 | "io" 22 | "reflect" 23 | "strings" 24 | 25 | "github.com/kevinswiber/postmanctl/pkg/sdk/resources" 26 | "github.com/liggitt/tabwriter" 27 | ) 28 | 29 | const ( 30 | tabwriterMinWidth = 6 31 | tabwriterWidth = 4 32 | tabwriterPadding = 3 33 | tabwriterPadChar = ' ' 34 | tabwriterFlags = tabwriter.RememberWidths 35 | ) 36 | 37 | // TablePrinter prints human-readable table structures. 38 | type TablePrinter struct { 39 | options PrintOptions 40 | } 41 | 42 | // NewTablePrinter creates a new human-readable table printer. 43 | func NewTablePrinter(o PrintOptions) *TablePrinter { 44 | return &TablePrinter{ 45 | options: o, 46 | } 47 | } 48 | 49 | // PrintResource executes the printer and creates an output. 50 | func (p *TablePrinter) PrintResource(r resources.Formatter, output io.Writer) { 51 | w, found := output.(*tabwriter.Writer) 52 | if !found { 53 | w = GetNewTabWriter(output) 54 | } 55 | 56 | defer w.Flush() 57 | 58 | cols, objs := r.Format() 59 | 60 | if !p.options.NoHeaders { 61 | printCols := make([]string, len(cols)) 62 | for i, c := range cols { 63 | if c == "PostmanID" { 64 | printCols[i] = "ID" 65 | } else { 66 | printCols[i] = strings.ToUpper(c) 67 | } 68 | } 69 | fmt.Fprintln(w, strings.Join(printCols, "\t")) 70 | } 71 | 72 | for _, obj := range objs { 73 | vals := make([]string, len(cols)) 74 | for i, c := range cols { 75 | rVal := reflect.ValueOf(obj) 76 | f := reflect.Indirect(rVal).FieldByName(c).String() 77 | vals[i] = f 78 | } 79 | 80 | fmt.Fprintln(w, strings.Join(vals, "\t")) 81 | } 82 | } 83 | 84 | // GetNewTabWriter returns a new formatted tabwriter.Writer. 85 | func GetNewTabWriter(output io.Writer) *tabwriter.Writer { 86 | return tabwriter.NewWriter(output, tabwriterMinWidth, tabwriterWidth, 87 | tabwriterPadding, tabwriterPadChar, tabwriterFlags) 88 | } 89 | -------------------------------------------------------------------------------- /pkg/sdk/printers/tableprinter_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package printers_test 18 | 19 | import ( 20 | "bytes" 21 | "testing" 22 | 23 | "github.com/kevinswiber/postmanctl/pkg/sdk/printers" 24 | "github.com/kevinswiber/postmanctl/pkg/sdk/resources" 25 | "github.com/kevinswiber/postmanctl/pkg/sdk/resources/gen" 26 | ) 27 | 28 | func TestTablePrinterPrintsCollectionListItems(t *testing.T) { 29 | options := printers.PrintOptions{ 30 | NoHeaders: false, 31 | } 32 | printer := printers.NewTablePrinter(options) 33 | 34 | var collections resources.CollectionListItems = []resources.CollectionListItem{ 35 | { 36 | ID: "abcdef", 37 | Name: "test collection", 38 | Owner: "12345", 39 | UID: "12345-abcdef", 40 | }, 41 | } 42 | 43 | var formatter resources.Formatter = collections 44 | 45 | var b bytes.Buffer 46 | 47 | printer.PrintResource(formatter, &b) 48 | 49 | expected := `UID NAME 50 | 12345-abcdef test collection 51 | ` 52 | 53 | actual := b.String() 54 | if expected != actual { 55 | t.Errorf("Unexpected output, have: \"%s\", want: \"%s\"", actual, expected) 56 | } 57 | } 58 | 59 | func TestTablePrinterPrintsCollection(t *testing.T) { 60 | options := printers.PrintOptions{ 61 | NoHeaders: false, 62 | } 63 | printer := printers.NewTablePrinter(options) 64 | 65 | collection := resources.Collection{ 66 | Collection: &gen.Collection{ 67 | Info: &gen.Info{ 68 | PostmanID: "abcdef", 69 | Name: "test collection", 70 | }, 71 | }, 72 | } 73 | 74 | var formatter resources.Formatter = collection 75 | 76 | var b bytes.Buffer 77 | 78 | printer.PrintResource(formatter, &b) 79 | 80 | expected := `ID NAME 81 | abcdef test collection 82 | ` 83 | 84 | actual := b.String() 85 | if expected != actual { 86 | t.Errorf("Unexpected output, have: \"%s\", want: \"%s\"", actual, expected) 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /pkg/sdk/resources/apirelations.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package resources 18 | 19 | import ( 20 | "time" 21 | ) 22 | 23 | // FormattedAPIRelationItems is a slice of FormattedAPIRelationItem 24 | type FormattedAPIRelationItems []FormattedAPIRelationItem 25 | 26 | // FormattedAPIRelationItem returns a list item version of an APIRelation. 27 | type FormattedAPIRelationItem struct { 28 | ID string 29 | Name string 30 | Type string 31 | } 32 | 33 | // NewFormattedAPIRelationItems returns a new human-readable view of API Relations. 34 | func NewFormattedAPIRelationItems(r *APIRelations) FormattedAPIRelationItems { 35 | totalLen := len(r.Documentation) + len(r.ContractTest) + len(r.TestSuite) + 36 | len(r.IntegrationTest) + len(r.Mock) + len(r.Monitor) 37 | 38 | i := 0 39 | ret := make([]FormattedAPIRelationItem, totalLen) 40 | 41 | for _, s := range r.Documentation { 42 | ret[i] = FormattedAPIRelationItem{ 43 | ID: s.ID, 44 | Name: s.Name, 45 | Type: "documentation", 46 | } 47 | i++ 48 | } 49 | 50 | for _, s := range r.Environment { 51 | ret[i] = FormattedAPIRelationItem{ 52 | ID: s.ID, 53 | Name: s.Name, 54 | Type: "environment", 55 | } 56 | i++ 57 | } 58 | 59 | for _, s := range r.ContractTest { 60 | ret[i] = FormattedAPIRelationItem{ 61 | ID: s.ID, 62 | Name: s.Name, 63 | Type: "contracttest", 64 | } 65 | i++ 66 | } 67 | 68 | for _, s := range r.TestSuite { 69 | ret[i] = FormattedAPIRelationItem{ 70 | ID: s.ID, 71 | Name: s.Name, 72 | Type: "testsuite", 73 | } 74 | i++ 75 | } 76 | 77 | for _, s := range r.IntegrationTest { 78 | ret[i] = FormattedAPIRelationItem{ 79 | ID: s.ID, 80 | Name: s.Name, 81 | Type: "integrationtest", 82 | } 83 | i++ 84 | } 85 | 86 | for _, s := range r.Mock { 87 | ret[i] = FormattedAPIRelationItem{ 88 | ID: s.ID, 89 | Name: s.Name, 90 | Type: "mock", 91 | } 92 | i++ 93 | } 94 | 95 | for _, s := range r.Monitor { 96 | ret[i] = FormattedAPIRelationItem{ 97 | ID: s.ID, 98 | Name: s.Name, 99 | Type: "monitor", 100 | } 101 | i++ 102 | } 103 | 104 | return ret 105 | } 106 | 107 | // Format returns column headers and values for the resource. 108 | func (r FormattedAPIRelationItems) Format() ([]string, []interface{}) { 109 | s := make([]interface{}, len(r)) 110 | for i, v := range r { 111 | s[i] = v 112 | } 113 | 114 | return []string{"ID", "Name", "Type"}, s 115 | } 116 | 117 | // APIRelationsResource provides the top-level wrapper for API Relations. 118 | type APIRelationsResource struct { 119 | Relations APIRelations `json:"relations"` 120 | } 121 | 122 | // APIRelations provides the top-level relations representation for APIs. 123 | type APIRelations struct { 124 | Documentation map[string]LinkedCollection `json:"documentation,omitempty"` 125 | Environment map[string]LinkedEnvironment `json:"environment,omitempty"` 126 | ContractTest map[string]LinkedCollection `json:"contracttest,omitempty"` 127 | TestSuite map[string]LinkedCollection `json:"testsuite,omitempty"` 128 | IntegrationTest map[string]LinkedCollection `json:"integrationtest,omitempty"` 129 | Mock map[string]LinkedMock `json:"mock,omitempty"` 130 | Monitor map[string]LinkedMonitor `json:"monitor,omitempty"` 131 | } 132 | 133 | // LinkedCollection describes a single linked collection representation. 134 | type LinkedCollection struct { 135 | ID string `json:"id"` 136 | Name string `json:"name"` 137 | CreatedAt time.Time `json:"createdAt"` 138 | UpdatedAt time.Time `json:"updatedAt"` 139 | } 140 | 141 | // LinkedEnvironment describes a single linked collection representation. 142 | type LinkedEnvironment struct { 143 | ID string `json:"id"` 144 | Name string `json:"name"` 145 | CreatedAt time.Time `json:"createdAt"` 146 | UpdatedAt time.Time `json:"updatedAt"` 147 | } 148 | 149 | // LinkedMock describes a single linked collection representation. 150 | type LinkedMock struct { 151 | ID string `json:"id"` 152 | Name string `json:"name"` 153 | CreatedAt time.Time `json:"createdAt"` 154 | UpdatedAt time.Time `json:"updatedAt"` 155 | URL string `json:"url"` 156 | } 157 | 158 | // LinkedMonitor describes a single linked collection representation. 159 | type LinkedMonitor struct { 160 | ID string `json:"id"` 161 | Name string `json:"name"` 162 | CreatedAt time.Time `json:"createdAt"` 163 | UpdatedAt time.Time `json:"updatedAt"` 164 | } 165 | -------------------------------------------------------------------------------- /pkg/sdk/resources/apis.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package resources 18 | 19 | import "time" 20 | 21 | // APIListResponse represents the top-level APIs response from the Postman API. 22 | type APIListResponse struct { 23 | APIs APIListItems `json:"apis"` 24 | } 25 | 26 | // APIListItems is a slice of APIListItem 27 | type APIListItems []APIListItem 28 | 29 | // Format returns column headers and values for the resource. 30 | func (r APIListItems) Format() ([]string, []interface{}) { 31 | s := make([]interface{}, len(r)) 32 | for i, v := range r { 33 | s[i] = v 34 | } 35 | 36 | return []string{"ID", "Name"}, s 37 | } 38 | 39 | // APIListItem represents a single item in an APIListResponse. 40 | type APIListItem struct { 41 | CreatedBy string `json:"createdBy"` 42 | UpdatedBy string `json:"updatedBy"` 43 | Team string `json:"team"` 44 | ID string `json:"id"` 45 | Name string `json:"name"` 46 | Summary string `json:"summary"` 47 | Description string `json:"description"` 48 | CreatedAt time.Time `json:"createdAt"` 49 | UpdatedAt time.Time `json:"updatedAt"` 50 | } 51 | 52 | // APIResponse is a single API representation in the Postman API. 53 | type APIResponse struct { 54 | API API `json:"api"` 55 | } 56 | 57 | // API represents a single item in an APIListResponse. 58 | type API struct { 59 | CreatedBy string `json:"createdBy"` 60 | UpdatedBy string `json:"updatedBy"` 61 | Team string `json:"team"` 62 | ID string `json:"id"` 63 | Name string `json:"name"` 64 | Summary string `json:"summary"` 65 | Description string `json:"description"` 66 | CreatedAt time.Time `json:"createdAt"` 67 | UpdatedAt time.Time `json:"updatedAt"` 68 | } 69 | 70 | // Format returns column headers and values for the resource. 71 | func (r API) Format() ([]string, []interface{}) { 72 | s := make([]interface{}, 1) 73 | s[0] = r 74 | 75 | return []string{"ID", "Name"}, s 76 | } 77 | 78 | // APISlice is a slice of API 79 | type APISlice []*API 80 | 81 | // Format returns column headers and values for the resource. 82 | func (r APISlice) Format() ([]string, []interface{}) { 83 | s := make([]interface{}, len(r)) 84 | for i, v := range r { 85 | s[i] = v 86 | } 87 | 88 | return []string{"ID", "Name"}, s 89 | } 90 | -------------------------------------------------------------------------------- /pkg/sdk/resources/apiversions.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package resources 18 | 19 | import "time" 20 | 21 | // APIVersionListResponse represents the top-level API Versions response from the Postman API. 22 | type APIVersionListResponse struct { 23 | APIVersions APIVersionListItems `json:"versions"` 24 | } 25 | 26 | // APIVersionListItems is a slice of APIVersionListItem 27 | type APIVersionListItems []APIVersionListItem 28 | 29 | // Format returns column headers and values for the resource. 30 | func (r APIVersionListItems) Format() ([]string, []interface{}) { 31 | s := make([]interface{}, len(r)) 32 | for i, v := range r { 33 | s[i] = v 34 | } 35 | 36 | return []string{"ID", "Name"}, s 37 | } 38 | 39 | // APIVersionListItem represents a single item in an APIVersionListResponse. 40 | type APIVersionListItem struct { 41 | ID string `json:"id"` 42 | Name string `json:"name"` 43 | TransactionID string `json:"transactionId"` 44 | CreatedAt time.Time `json:"createdAt"` 45 | UpdatedAt time.Time `json:"updatedAt"` 46 | API string `json:"api"` 47 | CreatedBy string `json:"createdBy"` 48 | UpdatedBy string `json:"updatedBy"` 49 | LastRevision int64 `json:"lastRevision"` 50 | } 51 | 52 | // APIVersionResponse is a single APIVersion representation in the Postman APIVersion. 53 | type APIVersionResponse struct { 54 | APIVersion APIVersion `json:"version"` 55 | } 56 | 57 | // APIVersion represents a single item in an APIVersionListResponse. 58 | type APIVersion struct { 59 | ID string `json:"id"` 60 | Name string `json:"name"` 61 | TransactionID string `json:"transactionId"` 62 | CreatedAt time.Time `json:"createdAt"` 63 | UpdatedAt time.Time `json:"updatedAt"` 64 | API string `json:"api"` 65 | CreatedBy string `json:"createdBy"` 66 | UpdatedBy string `json:"updatedBy"` 67 | LastRevision int64 `json:"lastRevision"` 68 | Schema []string `json:"schema"` 69 | } 70 | 71 | // Format returns column headers and values for the resource. 72 | func (r APIVersion) Format() ([]string, []interface{}) { 73 | s := make([]interface{}, 1) 74 | s[0] = r 75 | 76 | return []string{"ID", "Name"}, s 77 | } 78 | 79 | // APIVersionSlice is a slice of APIVersion. 80 | type APIVersionSlice []*APIVersion 81 | 82 | // Format returns column headers and values for the resource. 83 | func (r APIVersionSlice) Format() ([]string, []interface{}) { 84 | s := make([]interface{}, len(r)) 85 | for i, v := range r { 86 | s[i] = v 87 | } 88 | 89 | return []string{"ID", "Name"}, s 90 | } 91 | -------------------------------------------------------------------------------- /pkg/sdk/resources/collections.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package resources 18 | 19 | import ( 20 | "encoding/json" 21 | "time" 22 | 23 | "github.com/kevinswiber/postmanctl/pkg/sdk/resources/gen" 24 | ) 25 | 26 | //go:generate sh -c "schema-generate -p gen ../../../schema/collection.schema.json | sed 's/Id/ID/g' > ./gen/collection.go" 27 | 28 | // Collection represents a Postman Collection. 29 | type Collection struct { 30 | *gen.Collection 31 | Items *ItemTree 32 | } 33 | 34 | // UnmarshalJSON converts JSON to a struct. 35 | func (c *Collection) UnmarshalJSON(b []byte) error { 36 | var genC gen.Collection 37 | if err := json.Unmarshal(b, &genC); err != nil { 38 | return err 39 | } 40 | 41 | c.Collection = &genC 42 | node := ItemTreeNode{} 43 | if err := populateItemGroup(&node, c.Collection.Item); err != nil { 44 | return err 45 | } 46 | 47 | c.Items = &ItemTree{ 48 | Root: node, 49 | } 50 | 51 | return nil 52 | } 53 | 54 | // CollectionListResponse is the top-level struct representation of a collection 55 | // list response in the Postman API. 56 | type CollectionListResponse struct { 57 | Collections CollectionListItems `json:"collections"` 58 | } 59 | 60 | // CollectionListItems is a slice of CollectionListItem 61 | type CollectionListItems []CollectionListItem 62 | 63 | // Format returns column headers and values for the resource. 64 | func (r CollectionListItems) Format() ([]string, []interface{}) { 65 | s := make([]interface{}, len(r)) 66 | for i, v := range r { 67 | s[i] = v 68 | } 69 | 70 | return []string{"UID", "Name"}, s 71 | } 72 | 73 | // CollectionListItem represents a single item in a CollectionListResponse. 74 | type CollectionListItem struct { 75 | ID string `json:"id"` 76 | Name string `json:"name"` 77 | Owner string `json:"owner"` 78 | UID string `json:"uid"` 79 | Fork *Fork `json:"fork,omitempty"` 80 | } 81 | 82 | // Fork represents fork metadata for a collection. 83 | type Fork struct { 84 | Label string `json:"label"` 85 | CreatedAt time.Time `json:"createdAt"` 86 | From string `json:"from"` 87 | } 88 | 89 | // CollectionResponse is the top-level struct representation of a collection 90 | // response from the Postman API. 91 | type CollectionResponse struct { 92 | Collection Collection `json:"collection"` 93 | } 94 | 95 | // Format returns column headers and values for the resource. 96 | func (c Collection) Format() ([]string, []interface{}) { 97 | s := make([]interface{}, 1) 98 | s[0] = c.Info 99 | 100 | return []string{"PostmanID", "Name"}, s 101 | } 102 | 103 | // CollectionSlice is a slice of Collection. 104 | type CollectionSlice []*Collection 105 | 106 | // Format returns column headers and values for the resource. 107 | func (r CollectionSlice) Format() ([]string, []interface{}) { 108 | s := make([]interface{}, len(r)) 109 | for i, v := range r { 110 | s[i] = v.Info 111 | } 112 | 113 | return []string{"PostmanID", "Name"}, s 114 | } 115 | 116 | // Item represents an item (request) in a Collection. 117 | type Item struct { 118 | *gen.Item 119 | Events []Event 120 | } 121 | 122 | // ItemGroup represents a folder in a Collection. 123 | type ItemGroup struct { 124 | *gen.ItemGroup 125 | Events []Event 126 | } 127 | 128 | // Event represents an item event. 129 | type Event struct { 130 | *gen.Event 131 | } 132 | 133 | // UnmarshalJSON converts JSON to a struct. 134 | func (item *Item) UnmarshalJSON(b []byte) error { 135 | var genItem gen.Item 136 | if err := json.Unmarshal(b, &genItem); err != nil { 137 | return err 138 | } 139 | 140 | item.Item = &genItem 141 | item.Events = make([]Event, len(item.Item.Event)) 142 | 143 | for i, genEvent := range item.Item.Event { 144 | item.Events[i] = Event{Event: genEvent} 145 | } 146 | 147 | return nil 148 | } 149 | 150 | func populateItemGroup(b *ItemTreeNode, item []interface{}) error { 151 | if len(item) == 0 { 152 | return nil 153 | } 154 | 155 | for _, v := range item { 156 | var m map[string]interface{} = v.(map[string]interface{}) 157 | 158 | if v2, ok := m["item"]; ok { 159 | branch := ItemTreeNode{} 160 | 161 | if _, ok := m["name"]; ok { 162 | data, err := json.Marshal(m) 163 | if err != nil { 164 | return err 165 | } 166 | 167 | var ig gen.ItemGroup 168 | if err := json.Unmarshal(data, &ig); err != nil { 169 | return err 170 | } 171 | 172 | branch.MakeGroup(ItemGroup{ 173 | ItemGroup: &ig, 174 | }) 175 | } 176 | 177 | if err := populateItemGroup(&branch, v2.([]interface{})); err != nil { 178 | return err 179 | } 180 | 181 | b.AddBranch(branch) 182 | } else { 183 | it, err := populateItem(m["name"].(string), m) 184 | 185 | if err != nil { 186 | return err 187 | } 188 | 189 | b.AddItem(*it) 190 | } 191 | } 192 | 193 | return nil 194 | } 195 | 196 | func populateItem(name string, item map[string]interface{}) (*Item, error) { 197 | data, err := json.Marshal(item) 198 | if err != nil { 199 | return nil, err 200 | } 201 | 202 | var it Item 203 | if err := json.Unmarshal(data, &it); err != nil { 204 | return nil, err 205 | } 206 | 207 | return &it, nil 208 | } 209 | -------------------------------------------------------------------------------- /pkg/sdk/resources/environments.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package resources 18 | 19 | // EnvironmentListResponse represents the top-level environments response from the 20 | // Postman API. 21 | type EnvironmentListResponse struct { 22 | Environments EnvironmentListItems `json:"environments"` 23 | } 24 | 25 | // EnvironmentListItems is a slice of EnvironmentListItem. 26 | type EnvironmentListItems []EnvironmentListItem 27 | 28 | // Format returns column headers and values for the resource. 29 | func (r EnvironmentListItems) Format() ([]string, []interface{}) { 30 | s := make([]interface{}, len(r)) 31 | for i, v := range r { 32 | s[i] = v 33 | } 34 | 35 | return []string{"UID", "Name"}, s 36 | } 37 | 38 | // EnvironmentListItem represents a single item in an EnvironmentListResponse. 39 | type EnvironmentListItem struct { 40 | ID string `json:"id"` 41 | Name string `json:"name"` 42 | Owner string `json:"owner"` 43 | UID string `json:"uid"` 44 | } 45 | 46 | // EnvironmentResponse is the top-level environment response from the 47 | // Postman API. 48 | type EnvironmentResponse struct { 49 | Environment Environment `json:"environment"` 50 | } 51 | 52 | // Environment represents the single environment response from the 53 | // Postman API 54 | type Environment struct { 55 | ID string `json:"id"` 56 | Name string `json:"name"` 57 | Values []KeyValuePair `json:"values"` 58 | } 59 | 60 | // Format returns column headers and values for the resource. 61 | func (r Environment) Format() ([]string, []interface{}) { 62 | s := make([]interface{}, 1) 63 | s[0] = r 64 | 65 | return []string{"ID", "Name"}, s 66 | } 67 | 68 | // EnvironmentSlice is a slice of Environment. 69 | type EnvironmentSlice []*Environment 70 | 71 | // Format returns column headers and values for the resource. 72 | func (r EnvironmentSlice) Format() ([]string, []interface{}) { 73 | s := make([]interface{}, len(r)) 74 | for i, v := range r { 75 | s[i] = v 76 | } 77 | 78 | return []string{"ID", "Name"}, s 79 | } 80 | 81 | // KeyValuePair represents a key and value in the Postman API. 82 | type KeyValuePair struct { 83 | Key string `json:"key"` 84 | Value string `json:"value"` 85 | Enabled bool `json:"enabled"` 86 | } 87 | -------------------------------------------------------------------------------- /pkg/sdk/resources/error.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package resources 18 | 19 | import ( 20 | "fmt" 21 | ) 22 | 23 | // ErrorResponse is the struct representation of a Postman API error. 24 | type ErrorResponse struct { 25 | Error Error `json:"error"` 26 | } 27 | 28 | // Error is a struct representation of error details from a Postman API error. 29 | type Error struct { 30 | Name string `json:"name"` 31 | Message string `json:"message"` 32 | Details map[string]interface{} `json:"details"` 33 | } 34 | 35 | func (e *Error) String() string { 36 | return fmt.Sprintf("name: %s, message: %s", e.Name, e.Message) 37 | } 38 | -------------------------------------------------------------------------------- /pkg/sdk/resources/itemtree.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package resources 18 | 19 | // ItemTree represents a folder/request structure in a Collection 20 | type ItemTree struct { 21 | Root ItemTreeNode 22 | } 23 | 24 | // AddBranch adds a branch to a tree. 25 | func (b *ItemTreeNode) AddBranch(br ItemTreeNode) ItemTreeNode { 26 | if b.Branches == nil { 27 | b.Branches = &[]ItemTreeNode{br} 28 | } else { 29 | branch := append(*b.Branches, br) 30 | b.Branches = &branch 31 | } 32 | 33 | return br 34 | } 35 | 36 | // AddItem adds a single item to a tree node. 37 | func (b *ItemTreeNode) AddItem(item Item) Item { 38 | if b.Items == nil { 39 | b.Items = &[]Item{item} 40 | } else { 41 | items := append(*b.Items, item) 42 | b.Items = &items 43 | } 44 | 45 | return item 46 | } 47 | 48 | // MakeGroup makes the current node an item group. 49 | func (b *ItemTreeNode) MakeGroup(group ItemGroup) ItemGroup { 50 | b.ItemGroup = &group 51 | return *b.ItemGroup 52 | } 53 | 54 | // NewItemTree creates a new tree for storing items. 55 | func NewItemTree() *ItemTree { 56 | tree := &ItemTree{} 57 | return tree 58 | } 59 | 60 | // ItemTreeNode represents a group of items or a single item in a tree. 61 | type ItemTreeNode struct { 62 | *ItemGroup 63 | Branches *[]ItemTreeNode 64 | Items *[]Item 65 | } 66 | -------------------------------------------------------------------------------- /pkg/sdk/resources/mocks.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package resources 18 | 19 | // MockListResponse represents the top-level mocks response from the 20 | // Postman API. 21 | type MockListResponse struct { 22 | Mocks MockListItems `json:"mocks"` 23 | } 24 | 25 | // MockListItems is a slice of MockListItem. 26 | type MockListItems []MockListItem 27 | 28 | // Format returns column headers and values for the resource. 29 | func (r MockListItems) Format() ([]string, []interface{}) { 30 | s := make([]interface{}, len(r)) 31 | for i, v := range r { 32 | s[i] = v 33 | } 34 | 35 | return []string{"UID", "Name"}, s 36 | } 37 | 38 | // MockListItem represents a mock in a list of all mocks. 39 | type MockListItem struct { 40 | ID string `json:"id"` 41 | Owner string `json:"owner"` 42 | UID string `json:"uid"` 43 | Collection string `json:"collection"` 44 | MockURL string `json:"mockUrl"` 45 | Name string `json:"name"` 46 | Config MockConfig `json:"config"` 47 | Environment string `json:"environment"` 48 | } 49 | 50 | // MockResponse is the top-level mock response from the 51 | // Postman API. 52 | type MockResponse struct { 53 | Mock Mock `json:"mock"` 54 | } 55 | 56 | // Mock represents a representation of a mock server from the Postman API. 57 | type Mock struct { 58 | ID string `json:"id"` 59 | Owner string `json:"owner"` 60 | UID string `json:"uid"` 61 | Collection string `json:"collection"` 62 | MockURL string `json:"mockUrl"` 63 | Name string `json:"name"` 64 | Config MockConfig `json:"config"` 65 | Environment string `json:"environment"` 66 | } 67 | 68 | // MockConfig represents the configuration of a mock server. 69 | type MockConfig struct { 70 | Headers []interface{} `json:"headers"` 71 | MatchBody bool `json:"matchBody"` 72 | MatchQueryParams bool `json:"matchQueryParams"` 73 | MatchWildcards bool `json:"matchWildcards"` 74 | } 75 | 76 | // Format returns column headers and values for the resource. 77 | func (r Mock) Format() ([]string, []interface{}) { 78 | s := make([]interface{}, 1) 79 | s[0] = r 80 | 81 | return []string{"UID", "Name"}, s 82 | } 83 | 84 | // MockSlice is a slice of Mock. 85 | type MockSlice []*Mock 86 | 87 | // Format returns column headers and values for the resource. 88 | func (r MockSlice) Format() ([]string, []interface{}) { 89 | s := make([]interface{}, len(r)) 90 | for i, v := range r { 91 | s[i] = v 92 | } 93 | 94 | return []string{"UID", "Name"}, s 95 | } 96 | -------------------------------------------------------------------------------- /pkg/sdk/resources/monitors.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package resources 18 | 19 | import ( 20 | "encoding/json" 21 | "strconv" 22 | "time" 23 | ) 24 | 25 | // MonitorListResponse represents the top-level monitors response from the 26 | // Postman API. 27 | type MonitorListResponse struct { 28 | Monitors MonitorListItems `json:"monitors"` 29 | } 30 | 31 | // MonitorListItems is a slice of MonitorListItem. 32 | type MonitorListItems []MonitorListItem 33 | 34 | // Format returns column headers and values for the resource. 35 | func (r MonitorListItems) Format() ([]string, []interface{}) { 36 | s := make([]interface{}, len(r)) 37 | for i, v := range r { 38 | s[i] = v 39 | } 40 | 41 | return []string{"UID", "Name"}, s 42 | } 43 | 44 | // MonitorListItem represents a single item in an MonitorListResponse. 45 | type MonitorListItem struct { 46 | ID string `json:"id"` 47 | Name string `json:"name"` 48 | UID string `json:"uid"` 49 | Owner string `json:"owner"` 50 | } 51 | 52 | // UnmarshalJSON sets the receiver to a copy of data. 53 | func (m *MonitorListItem) UnmarshalJSON(data []byte) error { 54 | var v map[string]interface{} 55 | if err := json.Unmarshal(data, &v); err != nil { 56 | return err 57 | } 58 | 59 | if val, ok := v["id"]; ok { 60 | m.ID = val.(string) 61 | } 62 | 63 | if val, ok := v["name"]; ok { 64 | m.Name = val.(string) 65 | } 66 | 67 | if val, ok := v["uid"]; ok { 68 | m.UID = val.(string) 69 | } 70 | 71 | if val, ok := v["owner"]; ok { 72 | m.Owner = strconv.Itoa(int(val.(float64))) 73 | } 74 | 75 | return nil 76 | } 77 | 78 | // MonitorResponse is the top-level monitor response from the 79 | // Postman API. 80 | type MonitorResponse struct { 81 | Monitor Monitor `json:"monitor"` 82 | } 83 | 84 | // Monitor represents the single monitor response from the 85 | // Postman API 86 | type Monitor struct { 87 | ID string `json:"id"` 88 | Name string `json:"name"` 89 | UID string `json:"uid"` 90 | Owner string `json:"owner"` 91 | CollectionUID string `json:"collectionUid"` 92 | EnvironmentUID string `json:"environmentUid"` 93 | Options MonitorOptions `json:"options"` 94 | Notifications Notifications `json:"notifications"` 95 | Distribution []interface{} `json:"distribution"` 96 | Schedule Schedule `json:"schedule"` 97 | } 98 | 99 | type monitor struct { 100 | ID string `json:"id"` 101 | Name string `json:"name"` 102 | UID string `json:"uid"` 103 | Owner int `json:"owner"` 104 | CollectionUID string `json:"collectionUid"` 105 | EnvironmentUID string `json:"environmentUid"` 106 | Options MonitorOptions `json:"options"` 107 | Notifications Notifications `json:"notifications"` 108 | Distribution []interface{} `json:"distribution"` 109 | Schedule Schedule `json:"schedule"` 110 | } 111 | 112 | // Format returns column headers and values for the resource. 113 | func (r Monitor) Format() ([]string, []interface{}) { 114 | s := make([]interface{}, 1) 115 | s[0] = r 116 | 117 | return []string{"UID", "Name"}, s 118 | } 119 | 120 | // UnmarshalJSON sets the receiver to a copy of data. 121 | func (r *Monitor) UnmarshalJSON(data []byte) error { 122 | var m monitor 123 | if err := json.Unmarshal(data, &m); err != nil { 124 | return err 125 | } 126 | 127 | r.ID = m.ID 128 | r.Name = m.Name 129 | r.UID = m.UID 130 | r.Owner = strconv.Itoa(m.Owner) 131 | r.CollectionUID = m.CollectionUID 132 | r.EnvironmentUID = m.EnvironmentUID 133 | r.Options = m.Options 134 | r.Notifications = m.Notifications 135 | r.Distribution = m.Distribution 136 | r.Schedule = m.Schedule 137 | 138 | return nil 139 | } 140 | 141 | // MonitorSlice is a slice of Monitor. 142 | type MonitorSlice []*Monitor 143 | 144 | // Format returns column headers and values for the resource. 145 | func (r MonitorSlice) Format() ([]string, []interface{}) { 146 | s := make([]interface{}, len(r)) 147 | for i, v := range r { 148 | s[i] = v 149 | } 150 | 151 | return []string{"UID", "Name"}, s 152 | } 153 | 154 | // MonitorOptions list options for a monitor. 155 | type MonitorOptions struct { 156 | StrictSSL bool `json:"strictSSL"` 157 | FollowRedirects bool `json:"followRedirects"` 158 | RequestTimeout *int `json:"requestTimeout"` 159 | RequestDelay int `json:"requestDelay"` 160 | } 161 | 162 | // OnError represents a communication mechanism for errors. 163 | type OnError struct { 164 | Email string `json:"email"` 165 | } 166 | 167 | // OnFailure represents a communication mechanism for failures. 168 | type OnFailure struct { 169 | Email string `json:"email"` 170 | } 171 | 172 | // Notifications represents a communication structure for notifications. 173 | type Notifications struct { 174 | OnError []OnError `json:"onError"` 175 | OnFailure []OnFailure `json:"onFailure"` 176 | } 177 | 178 | // Schedule represents when the monitor is scheduled to run. 179 | type Schedule struct { 180 | Cron string `json:"cron"` 181 | Timezone string `json:"timezone"` 182 | NextRun time.Time `json:"nextRun"` 183 | } 184 | -------------------------------------------------------------------------------- /pkg/sdk/resources/resources.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package resources 18 | 19 | // Formatter represents a resource that provides print formatting information. 20 | type Formatter interface { 21 | // Format returns column headers and values for the resource. 22 | Format() ([]string, []interface{}) 23 | } 24 | 25 | // ResourceType represents the resource type. 26 | type ResourceType int 27 | 28 | // Resource types. 29 | const ( 30 | CollectionType ResourceType = iota 31 | EnvironmentType 32 | MockType 33 | MonitorType 34 | APIType 35 | APIVersionType 36 | APIRelationsType 37 | SchemaType 38 | WorkspaceType 39 | UserType 40 | ) 41 | 42 | // String returns a string version of the ResourceType. 43 | func (r ResourceType) String() string { 44 | switch r { 45 | case CollectionType: 46 | return "Collection" 47 | case EnvironmentType: 48 | return "Environment" 49 | case MockType: 50 | return "Mock" 51 | case MonitorType: 52 | return "Monitor" 53 | case APIType: 54 | return "API" 55 | case APIVersionType: 56 | return "APIVersion" 57 | case APIRelationsType: 58 | return "APIRelations" 59 | case SchemaType: 60 | return "Schema" 61 | case WorkspaceType: 62 | return "Workspace" 63 | case UserType: 64 | return "User" 65 | } 66 | 67 | return "" 68 | } 69 | -------------------------------------------------------------------------------- /pkg/sdk/resources/schema.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package resources 18 | 19 | import "time" 20 | 21 | // SchemaResponse represents the top-level schema response in the Postman API. 22 | type SchemaResponse struct { 23 | Schema Schema `json:"schema"` 24 | } 25 | 26 | // Schema represents an API schema from the Postman API 27 | type Schema struct { 28 | APIVersion string `json:"apiVersion"` 29 | CreatedBy string `json:"createdBy"` 30 | UpdatedBy string `json:"updatedBy"` 31 | ID string `json:"id"` 32 | Type string `json:"type"` 33 | Language string `json:"language"` 34 | CreatedAt time.Time `json:"createdAt"` 35 | UpdatedAt time.Time `json:"updatedAt"` 36 | Schema string `json:"schema"` 37 | } 38 | 39 | // Format returns column headers and values for the resource. 40 | func (r Schema) Format() ([]string, []interface{}) { 41 | s := make([]interface{}, 1) 42 | s[0] = r 43 | 44 | return []string{"ID", "Type", "Language"}, s 45 | } 46 | -------------------------------------------------------------------------------- /pkg/sdk/resources/user.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package resources 18 | 19 | import ( 20 | "encoding/json" 21 | "strconv" 22 | ) 23 | 24 | // UserResponse represents the top-level struct of a user response in the 25 | // Postman API. 26 | type UserResponse struct { 27 | User User `json:"user"` 28 | } 29 | 30 | // User represents the user info associated with a user request in the 31 | // Postman API. 32 | type User struct { 33 | ID string `json:"id"` 34 | } 35 | 36 | // UnmarshalJSON sets the receiver to a copy of data. 37 | func (r *User) UnmarshalJSON(data []byte) error { 38 | var v map[string]interface{} 39 | if err := json.Unmarshal(data, &v); err != nil { 40 | return err 41 | } 42 | 43 | r.ID = strconv.Itoa(int(v["id"].(float64))) 44 | 45 | return nil 46 | } 47 | 48 | // Format returns column headers and values for the resource. 49 | func (r User) Format() ([]string, []interface{}) { 50 | s := make([]interface{}, 1) 51 | s[0] = r 52 | 53 | return []string{"ID"}, s 54 | } 55 | -------------------------------------------------------------------------------- /pkg/sdk/resources/workspaces.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package resources 18 | 19 | // WorkspaceListResponse represents the top-level workspaces response from the 20 | // Postman API. 21 | type WorkspaceListResponse struct { 22 | Workspaces WorkspaceListItems `json:"workspaces"` 23 | } 24 | 25 | // WorkspaceListItems is a slice of WorkspaceListItem. 26 | type WorkspaceListItems []WorkspaceListItem 27 | 28 | // Format returns column headers and values for the resource. 29 | func (r WorkspaceListItems) Format() ([]string, []interface{}) { 30 | s := make([]interface{}, len(r)) 31 | for i, v := range r { 32 | s[i] = v 33 | } 34 | 35 | return []string{"ID", "Name", "Type"}, s 36 | } 37 | 38 | // WorkspaceListItem represents a single item in an WorkspaceListResponse. 39 | type WorkspaceListItem struct { 40 | ID string `json:"id"` 41 | Name string `json:"name"` 42 | Type string `json:"type"` 43 | } 44 | 45 | // WorkspaceResponse is the top-level workspace response from the 46 | // Postman API. 47 | type WorkspaceResponse struct { 48 | Workspace Workspace `json:"workspace"` 49 | } 50 | 51 | // Workspace represents the single workspace response from the 52 | // Postman API 53 | type Workspace struct { 54 | ID string `json:"id"` 55 | Name string `json:"name"` 56 | Type string `json:"type"` 57 | Description string `json:"description"` 58 | Collections []WorkspaceCollectionListItem `json:"collections"` 59 | Environments []WorkspaceEnvironmentListItem `json:"environments"` 60 | Mocks []WorkspaceMockListItem `json:"mocks"` 61 | Monitors []WorkspaceMonitorListItem `json:"monitors"` 62 | } 63 | 64 | // Format returns column headers and values for the resource. 65 | func (r Workspace) Format() ([]string, []interface{}) { 66 | s := make([]interface{}, 1) 67 | s[0] = r 68 | 69 | return []string{"ID", "Name", "Type"}, s 70 | } 71 | 72 | // WorkspaceSlice is a slice of Workspace. 73 | type WorkspaceSlice []*Workspace 74 | 75 | // Format returns column headers and values for the resource. 76 | func (r WorkspaceSlice) Format() ([]string, []interface{}) { 77 | s := make([]interface{}, len(r)) 78 | for i, v := range r { 79 | s[i] = v 80 | } 81 | 82 | return []string{"ID", "Name", "Type"}, s 83 | } 84 | 85 | // WorkspaceCollectionListItem represents a single collection item in a Workspace. 86 | type WorkspaceCollectionListItem struct { 87 | ID string `json:"id"` 88 | Name string `json:"name"` 89 | UID string `json:"uid"` 90 | } 91 | 92 | // WorkspaceEnvironmentListItem represents a single environment item in a Workspace. 93 | type WorkspaceEnvironmentListItem struct { 94 | ID string `json:"id"` 95 | Name string `json:"name"` 96 | UID string `json:"uid"` 97 | } 98 | 99 | // WorkspaceMockListItem represents a single mock item in a Workspace. 100 | type WorkspaceMockListItem struct { 101 | ID string `json:"id"` 102 | } 103 | 104 | // WorkspaceMonitorListItem represents a single monitor item in a Workspace. 105 | type WorkspaceMonitorListItem struct { 106 | ID string `json:"id"` 107 | } 108 | -------------------------------------------------------------------------------- /pkg/sdk/service.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package sdk 18 | 19 | import ( 20 | "bytes" 21 | "context" 22 | "net/http" 23 | 24 | "github.com/kevinswiber/postmanctl/pkg/sdk/client" 25 | ) 26 | 27 | // Service is used by Postman API consumers. 28 | type Service struct { 29 | Options *client.Options 30 | } 31 | 32 | // NewService returns a new instance of the Postman API service client. 33 | func NewService(options *client.Options) *Service { 34 | return &Service{ 35 | Options: options, 36 | } 37 | } 38 | 39 | func (s *Service) get(ctx context.Context, r interface{}, queryParams map[string]string, path ...string) (*http.Response, error) { 40 | req := client.NewRequestWithContext(ctx, s.Options) 41 | res, err := req.Get(). 42 | Path(path...). 43 | Params(queryParams). 44 | Into(&r). 45 | Do() 46 | 47 | return res, err 48 | } 49 | 50 | func (s *Service) post(ctx context.Context, input []byte, output interface{}, queryParams map[string]string, path ...string) (*http.Response, error) { 51 | req := client.NewRequestWithContext(ctx, s.Options) 52 | res, err := req.Post(). 53 | Path(path...). 54 | Params(queryParams). 55 | AddHeader("Content-Type", "application/json"). 56 | Body(bytes.NewReader(input)). 57 | Into(&output). 58 | Do() 59 | 60 | return res, err 61 | } 62 | 63 | func (s *Service) put(ctx context.Context, input []byte, output interface{}, path ...string) (*http.Response, error) { 64 | req := client.NewRequestWithContext(ctx, s.Options) 65 | res, err := req.Put(). 66 | Path(path...). 67 | AddHeader("Content-Type", "application/json"). 68 | Body(bytes.NewReader(input)). 69 | Into(&output). 70 | Do() 71 | 72 | return res, err 73 | } 74 | 75 | func (s *Service) delete(ctx context.Context, output interface{}, path ...string) (*http.Response, error) { 76 | req := client.NewRequestWithContext(ctx, s.Options) 77 | res, err := req.Delete(). 78 | Path(path...). 79 | AddHeader("Content-Type", "application/json"). 80 | Into(&output). 81 | Do() 82 | 83 | return res, err 84 | } 85 | -------------------------------------------------------------------------------- /pkg/sdk/servicecreate.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package sdk 18 | 19 | import ( 20 | "context" 21 | "encoding/json" 22 | "errors" 23 | "fmt" 24 | "io" 25 | "io/ioutil" 26 | 27 | "github.com/kevinswiber/postmanctl/pkg/sdk/resources" 28 | ) 29 | 30 | // CreateCollectionFromReader creates a new collection. 31 | func (s *Service) CreateCollectionFromReader(ctx context.Context, reader io.Reader, workspace string) (string, error) { 32 | var params map[string]string 33 | if workspace != "" { 34 | params = make(map[string]string) 35 | params["workspace"] = workspace 36 | } 37 | 38 | return s.CreateFromReader(ctx, resources.CollectionType, reader, params, nil) 39 | } 40 | 41 | // CreateEnvironmentFromReader creates a new environment. 42 | func (s *Service) CreateEnvironmentFromReader(ctx context.Context, reader io.Reader, workspace string) (string, error) { 43 | var params map[string]string 44 | if workspace != "" { 45 | params = make(map[string]string) 46 | params["workspace"] = workspace 47 | } 48 | 49 | return s.CreateFromReader(ctx, resources.EnvironmentType, reader, params, nil) 50 | } 51 | 52 | // CreateMockFromReader creates a new mock. 53 | func (s *Service) CreateMockFromReader(ctx context.Context, reader io.Reader, workspace string) (string, error) { 54 | var params map[string]string 55 | if workspace != "" { 56 | params = make(map[string]string) 57 | params["workspace"] = workspace 58 | } 59 | 60 | return s.CreateFromReader(ctx, resources.MockType, reader, params, nil) 61 | } 62 | 63 | // CreateMonitorFromReader creates a new monitor. 64 | func (s *Service) CreateMonitorFromReader(ctx context.Context, reader io.Reader, workspace string) (string, error) { 65 | var params map[string]string 66 | if workspace != "" { 67 | params = make(map[string]string) 68 | params["workspace"] = workspace 69 | } 70 | 71 | return s.CreateFromReader(ctx, resources.MonitorType, reader, params, nil) 72 | } 73 | 74 | // CreateWorkspaceFromReader creates a new API. 75 | func (s *Service) CreateWorkspaceFromReader(ctx context.Context, reader io.Reader, workspace string) (string, error) { 76 | return s.CreateFromReader(ctx, resources.WorkspaceType, reader, nil, nil) 77 | } 78 | 79 | // CreateAPIFromReader creates a new API. 80 | func (s *Service) CreateAPIFromReader(ctx context.Context, reader io.Reader, workspace string) (string, error) { 81 | var params map[string]string 82 | if workspace != "" { 83 | params = make(map[string]string) 84 | params["workspace"] = workspace 85 | } 86 | 87 | return s.CreateFromReader(ctx, resources.APIType, reader, params, nil) 88 | } 89 | 90 | // CreateAPIVersionFromReader creates a new API Version. 91 | func (s *Service) CreateAPIVersionFromReader(ctx context.Context, reader io.Reader, workspace, apiID string) (string, error) { 92 | var queryParams map[string]string 93 | if workspace != "" { 94 | queryParams = make(map[string]string) 95 | queryParams["workspace"] = workspace 96 | } 97 | 98 | if apiID == "" { 99 | return "", errors.New("an API ID is required for creating a new API version") 100 | } 101 | 102 | urlParams := make(map[string]string) 103 | urlParams["apiID"] = apiID 104 | 105 | return s.CreateFromReader(ctx, resources.APIVersionType, reader, queryParams, urlParams) 106 | } 107 | 108 | // CreateSchemaFromReader creates a new API Version. 109 | func (s *Service) CreateSchemaFromReader(ctx context.Context, reader io.Reader, workspace, apiID, apiVersionID string) (string, error) { 110 | var queryParams map[string]string 111 | if workspace != "" { 112 | queryParams = make(map[string]string) 113 | queryParams["workspace"] = workspace 114 | } 115 | 116 | if apiID == "" { 117 | return "", errors.New("an API ID is required for creating a new schema") 118 | } 119 | 120 | if apiVersionID == "" { 121 | return "", errors.New("an API Version ID is required for creating a new schema") 122 | } 123 | 124 | urlParams := make(map[string]string) 125 | urlParams["apiID"] = apiID 126 | urlParams["apiVersionID"] = apiVersionID 127 | 128 | return s.CreateFromReader(ctx, resources.SchemaType, reader, queryParams, urlParams) 129 | } 130 | 131 | // CreateFromReader posts a new resource to the Postman API. 132 | func (s *Service) CreateFromReader(ctx context.Context, t resources.ResourceType, reader io.Reader, queryParams, urlParams map[string]string) (string, error) { 133 | b, err := ioutil.ReadAll(reader) 134 | 135 | if err != nil { 136 | return "", err 137 | } 138 | 139 | var v map[string]interface{} 140 | if err := json.Unmarshal(b, &v); err != nil { 141 | return "", err 142 | } 143 | 144 | var ( 145 | path []string 146 | requestBody []byte 147 | responseValueKey string 148 | ) 149 | 150 | switch t { 151 | case resources.CollectionType: 152 | path = []string{"collections"} 153 | responseValueKey = "collection" 154 | 155 | c := struct { 156 | Collection map[string]interface{} `json:"collection"` 157 | }{ 158 | Collection: v, 159 | } 160 | requestBody, _ = json.Marshal(c) // already been unmarshalled, no error 161 | case resources.EnvironmentType: 162 | path = []string{"environments"} 163 | responseValueKey = "environment" 164 | 165 | c := struct { 166 | Environment map[string]interface{} `json:"environment"` 167 | }{ 168 | Environment: v, 169 | } 170 | requestBody, _ = json.Marshal(c) 171 | case resources.MockType: 172 | path = []string{"mocks"} 173 | responseValueKey = "mock" 174 | 175 | c := struct { 176 | Mock map[string]interface{} `json:"mock"` 177 | }{ 178 | Mock: v, 179 | } 180 | requestBody, _ = json.Marshal(c) 181 | case resources.MonitorType: 182 | path = []string{"monitors"} 183 | responseValueKey = "monitor" 184 | 185 | c := struct { 186 | Monitor map[string]interface{} `json:"monitor"` 187 | }{ 188 | Monitor: v, 189 | } 190 | requestBody, _ = json.Marshal(c) 191 | case resources.WorkspaceType: 192 | path = []string{"workspaces"} 193 | responseValueKey = "workspace" 194 | 195 | c := struct { 196 | Workspace map[string]interface{} `json:"workspace"` 197 | }{ 198 | Workspace: v, 199 | } 200 | requestBody, _ = json.Marshal(c) 201 | case resources.APIType: 202 | path = []string{"apis"} 203 | responseValueKey = "api" 204 | 205 | c := struct { 206 | API map[string]interface{} `json:"api"` 207 | }{ 208 | API: v, 209 | } 210 | requestBody, _ = json.Marshal(c) 211 | case resources.APIVersionType: 212 | path = []string{"apis", urlParams["apiID"], "versions"} 213 | responseValueKey = "version" 214 | 215 | c := struct { 216 | Version map[string]interface{} `json:"version"` 217 | }{ 218 | Version: v, 219 | } 220 | requestBody, _ = json.Marshal(c) 221 | case resources.SchemaType: 222 | path = []string{"apis", urlParams["apiID"], "versions", urlParams["apiVersionID"], "schemas"} 223 | responseValueKey = "schema" 224 | 225 | c := struct { 226 | Schema map[string]interface{} `json:"schema"` 227 | }{ 228 | Schema: v, 229 | } 230 | requestBody, _ = json.Marshal(c) 231 | default: 232 | return "", fmt.Errorf("unable to create resource, %+v not supported", t) 233 | } 234 | 235 | var responseBody interface{} 236 | if _, err := s.post(ctx, requestBody, &responseBody, queryParams, path...); err != nil { 237 | return "", err 238 | } 239 | 240 | // Try a best attempt at returning the ID value. 241 | responseValue := responseBody.(map[string]interface{}) 242 | if v, ok := responseValue[responseValueKey]; ok { 243 | vMap := v.(map[string]interface{}) 244 | if v2, ok := vMap["uid"]; ok { 245 | return v2.(string), nil 246 | } 247 | if v2, ok := vMap["id"]; ok { 248 | return v2.(string), nil 249 | } 250 | return "", nil 251 | } 252 | return "", nil 253 | } 254 | -------------------------------------------------------------------------------- /pkg/sdk/servicedelete.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package sdk 18 | 19 | import ( 20 | "context" 21 | "errors" 22 | "fmt" 23 | 24 | "github.com/kevinswiber/postmanctl/pkg/sdk/resources" 25 | ) 26 | 27 | // DeleteCollection deletes a collection. 28 | func (s *Service) DeleteCollection(ctx context.Context, resourceID string) (string, error) { 29 | urlParams := make(map[string]string) 30 | urlParams["ID"] = resourceID 31 | 32 | return s.Delete(ctx, resources.CollectionType, urlParams) 33 | } 34 | 35 | // DeleteEnvironment deletes a environment. 36 | func (s *Service) DeleteEnvironment(ctx context.Context, resourceID string) (string, error) { 37 | urlParams := make(map[string]string) 38 | urlParams["ID"] = resourceID 39 | 40 | return s.Delete(ctx, resources.EnvironmentType, urlParams) 41 | } 42 | 43 | // DeleteMock deletes a mock. 44 | func (s *Service) DeleteMock(ctx context.Context, resourceID string) (string, error) { 45 | urlParams := make(map[string]string) 46 | urlParams["ID"] = resourceID 47 | 48 | return s.Delete(ctx, resources.MockType, urlParams) 49 | } 50 | 51 | // DeleteMonitor deletes a monitor. 52 | func (s *Service) DeleteMonitor(ctx context.Context, resourceID string) (string, error) { 53 | urlParams := make(map[string]string) 54 | urlParams["ID"] = resourceID 55 | 56 | return s.Delete(ctx, resources.MonitorType, urlParams) 57 | } 58 | 59 | // DeleteWorkspace deletes a API. 60 | func (s *Service) DeleteWorkspace(ctx context.Context, resourceID string) (string, error) { 61 | urlParams := make(map[string]string) 62 | urlParams["ID"] = resourceID 63 | 64 | return s.Delete(ctx, resources.WorkspaceType, urlParams) 65 | } 66 | 67 | // DeleteAPI deletes a API. 68 | func (s *Service) DeleteAPI(ctx context.Context, resourceID string) (string, error) { 69 | urlParams := make(map[string]string) 70 | urlParams["ID"] = resourceID 71 | 72 | return s.Delete(ctx, resources.APIType, urlParams) 73 | } 74 | 75 | // DeleteAPIVersion deletes a API Version. 76 | func (s *Service) DeleteAPIVersion(ctx context.Context, resourceID, apiID string) (string, error) { 77 | if apiID == "" { 78 | return "", errors.New("an API ID is required for creating a new API version") 79 | } 80 | 81 | urlParams := make(map[string]string) 82 | urlParams["ID"] = resourceID 83 | urlParams["apiID"] = apiID 84 | 85 | return s.Delete(ctx, resources.APIVersionType, urlParams) 86 | } 87 | 88 | // DeleteSchema deletes a API Version. 89 | func (s *Service) DeleteSchema(ctx context.Context, resourceID, apiID, apiVersionID string) (string, error) { 90 | if apiID == "" { 91 | return "", errors.New("an API ID is required for creating a new schema") 92 | } 93 | 94 | if apiVersionID == "" { 95 | return "", errors.New("an API Version ID is required for creating a new schema") 96 | } 97 | 98 | urlParams := make(map[string]string) 99 | urlParams["ID"] = resourceID 100 | urlParams["apiID"] = apiID 101 | urlParams["apiVersionID"] = apiVersionID 102 | 103 | return s.Delete(ctx, resources.SchemaType, urlParams) 104 | } 105 | 106 | // Delete posts a new resource to the Postman API. 107 | func (s *Service) Delete(ctx context.Context, t resources.ResourceType, urlParams map[string]string) (string, error) { 108 | var ( 109 | path []string 110 | responseValueKey string 111 | ) 112 | 113 | switch t { 114 | case resources.CollectionType: 115 | path = []string{"collections", urlParams["ID"]} 116 | responseValueKey = "collection" 117 | case resources.EnvironmentType: 118 | path = []string{"environments", urlParams["ID"]} 119 | responseValueKey = "environment" 120 | case resources.MockType: 121 | path = []string{"mocks", urlParams["ID"]} 122 | responseValueKey = "mock" 123 | case resources.MonitorType: 124 | path = []string{"monitors", urlParams["ID"]} 125 | responseValueKey = "monitor" 126 | case resources.WorkspaceType: 127 | path = []string{"workspaces", urlParams["ID"]} 128 | responseValueKey = "workspace" 129 | case resources.APIType: 130 | path = []string{"apis", urlParams["ID"]} 131 | responseValueKey = "api" 132 | case resources.APIVersionType: 133 | path = []string{"apis", urlParams["apiID"], "versions", urlParams["ID"]} 134 | responseValueKey = "version" 135 | case resources.SchemaType: 136 | path = []string{"apis", urlParams["apiID"], "versions", urlParams["apiVersionID"], "schemas", urlParams["ID"]} 137 | responseValueKey = "schema" 138 | default: 139 | return "", fmt.Errorf("unable to delete resource, %+v not supported", t) 140 | } 141 | 142 | var responseBody interface{} 143 | if _, err := s.delete(ctx, &responseBody, path...); err != nil { 144 | return "", err 145 | } 146 | 147 | // Try a best attempt at returning the ID value. 148 | responseValue := responseBody.(map[string]interface{}) 149 | if v, ok := responseValue[responseValueKey]; ok { 150 | vMap := v.(map[string]interface{}) 151 | if v2, ok := vMap["uid"]; ok { 152 | return v2.(string), nil 153 | } 154 | if v2, ok := vMap["id"]; ok { 155 | return v2.(string), nil 156 | } 157 | return "", nil 158 | } 159 | return "", nil 160 | } 161 | -------------------------------------------------------------------------------- /pkg/sdk/servicefork.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package sdk 18 | 19 | import ( 20 | "context" 21 | "encoding/json" 22 | ) 23 | 24 | // ForkCollection makes a fork of an existing collection. 25 | func (s *Service) ForkCollection(ctx context.Context, id, workspace, label string) (string, error) { 26 | responseValueKey := "collection" 27 | queryParams := make(map[string]string) 28 | queryParams["workspace"] = workspace 29 | 30 | input := struct { 31 | Label string `json:"label"` 32 | }{ 33 | Label: label, 34 | } 35 | 36 | // swallow error here, strings will always marshal 37 | requestBody, _ := json.Marshal(input) 38 | 39 | var responseBody interface{} 40 | if _, err := s.post(ctx, requestBody, &responseBody, queryParams, "collections", "fork", id); err != nil { 41 | return "", err 42 | } 43 | 44 | // Try a best attempt at returning the ID value. 45 | responseValue := responseBody.(map[string]interface{}) 46 | if v, ok := responseValue[responseValueKey]; ok { 47 | vMap := v.(map[string]interface{}) 48 | if v2, ok := vMap["uid"]; ok { 49 | return v2.(string), nil 50 | } 51 | 52 | return "", nil 53 | } 54 | return "", nil 55 | } 56 | 57 | // MergeCollection makes a fork of an existing collection. 58 | func (s *Service) MergeCollection(ctx context.Context, id, destination, strategy string) (string, error) { 59 | responseValueKey := "collection" 60 | 61 | input := struct { 62 | Source string `json:"source"` 63 | Destination string `json:"destination"` 64 | Strategy string `json:"strategy"` 65 | }{ 66 | Source: id, 67 | Destination: destination, 68 | Strategy: strategy, 69 | } 70 | 71 | // swallow error here, strings will always marshal 72 | requestBody, _ := json.Marshal(input) 73 | 74 | var responseBody interface{} 75 | if _, err := s.post(ctx, requestBody, &responseBody, nil, "collections", "merge"); err != nil { 76 | return "", err 77 | } 78 | 79 | // Try a best attempt at returning the ID value. 80 | responseValue := responseBody.(map[string]interface{}) 81 | if v, ok := responseValue[responseValueKey]; ok { 82 | vMap := v.(map[string]interface{}) 83 | if v2, ok := vMap["uid"]; ok { 84 | return v2.(string), nil 85 | } 86 | 87 | return "", nil 88 | } 89 | return "", nil 90 | } 91 | -------------------------------------------------------------------------------- /pkg/sdk/servicefork_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package sdk_test 18 | 19 | import ( 20 | "context" 21 | "net/http" 22 | "testing" 23 | 24 | "github.com/kevinswiber/postmanctl/pkg/sdk" 25 | ) 26 | 27 | var ( 28 | forkMux *http.ServeMux 29 | forkService *sdk.Service 30 | ) 31 | 32 | func setupForkTest() func() { 33 | teardown := setupService(&forkMux, &forkService) 34 | 35 | return teardown 36 | } 37 | 38 | func TestForkCollection(t *testing.T) { 39 | teardown := setupForkTest() 40 | defer teardown() 41 | 42 | path := "/collections/fork/abcdef" 43 | subject := "{\"collection\":{\"uid\":\"abcdef\"}}" 44 | 45 | forkMux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { 46 | if r.Method != http.MethodPost { 47 | t.Errorf("Method is incorrect, have: %s, want: %s", r.Method, http.MethodPost) 48 | } 49 | w.WriteHeader(http.StatusOK) 50 | if _, err := w.Write([]byte(subject)); err != nil { 51 | t.Error(err) 52 | } 53 | }) 54 | 55 | ensurePath(t, forkMux, path) 56 | 57 | r, err := forkService.ForkCollection(context.Background(), "abcdef", "12345", "forkd") 58 | if err != nil { 59 | t.Fatal(err) 60 | } 61 | 62 | if r != "abcdef" { 63 | t.Errorf("Resource ID is incorrect, have: %s, want: %s", r, "abcdef") 64 | } 65 | } 66 | 67 | func TestForkCollectionMissingIDCondition(t *testing.T) { 68 | teardown := setupForkTest() 69 | defer teardown() 70 | 71 | path := "/collections/fork/abcdef" 72 | subject := `{"collection": {}}` 73 | 74 | forkMux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { 75 | if r.Method != http.MethodPost { 76 | t.Errorf("Method is incorrect, have: %s, want: %s", r.Method, http.MethodPost) 77 | } 78 | w.WriteHeader(http.StatusOK) 79 | if _, err := w.Write([]byte(subject)); err != nil { 80 | t.Error(err) 81 | } 82 | }) 83 | 84 | ensurePath(t, forkMux, path) 85 | 86 | r, err := forkService.ForkCollection(context.Background(), "abcdef", "12345", "forkd") 87 | if err != nil { 88 | t.Fatal(err) 89 | } 90 | 91 | if r != "" { 92 | t.Errorf("Resource ID is incorrect, have: %s, want: %s", r, "") 93 | } 94 | } 95 | 96 | func TestForkCollectionMissingResponseValueKeyCondition(t *testing.T) { 97 | teardown := setupForkTest() 98 | defer teardown() 99 | 100 | path := "/collections/fork/abcdef" 101 | subject := `{"blah":{"uid":"abcdef"}}` 102 | 103 | forkMux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { 104 | if r.Method != http.MethodPost { 105 | t.Errorf("Method is incorrect, have: %s, want: %s", r.Method, http.MethodPost) 106 | } 107 | w.WriteHeader(http.StatusOK) 108 | if _, err := w.Write([]byte(subject)); err != nil { 109 | t.Error(err) 110 | } 111 | }) 112 | 113 | ensurePath(t, forkMux, path) 114 | 115 | r, err := forkService.ForkCollection(context.Background(), "abcdef", "12345", "forkd") 116 | if err != nil { 117 | t.Fatal(err) 118 | } 119 | 120 | if r != "" { 121 | t.Errorf("Resource ID is incorrect, have: %s, want: %s", r, "") 122 | } 123 | } 124 | 125 | func TestForkCollectionError(t *testing.T) { 126 | teardown := setupForkTest() 127 | defer teardown() 128 | 129 | path := "/collections/fork/abcdef" 130 | forkMux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { 131 | if r.Method != http.MethodPost { 132 | t.Errorf("Method is incorrect, have: %s, want: %s", r.Method, http.MethodPost) 133 | } 134 | w.WriteHeader(http.StatusInternalServerError) 135 | }) 136 | 137 | ensurePath(t, forkMux, path) 138 | 139 | _, err := forkService.ForkCollection(context.Background(), "abcdef", "12345", "forkd") 140 | if err == nil { 141 | t.Error("Expected error.") 142 | } 143 | } 144 | 145 | func TestMergeCollection(t *testing.T) { 146 | teardown := setupForkTest() 147 | defer teardown() 148 | 149 | path := "/collections/merge" 150 | subject := "{\"collection\":{\"uid\":\"abcdef\"}}" 151 | 152 | forkMux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { 153 | if r.Method != http.MethodPost { 154 | t.Errorf("Method is incorrect, have: %s, want: %s", r.Method, http.MethodPost) 155 | } 156 | w.WriteHeader(http.StatusOK) 157 | if _, err := w.Write([]byte(subject)); err != nil { 158 | t.Error(err) 159 | } 160 | }) 161 | 162 | ensurePath(t, forkMux, path) 163 | 164 | r, err := forkService.MergeCollection(context.Background(), "abcdef", "ghijkl", "") 165 | if err != nil { 166 | t.Fatal(err) 167 | } 168 | 169 | if r != "abcdef" { 170 | t.Errorf("Resource ID is incorrect, have: %s, want: %s", r, "abcdef") 171 | } 172 | } 173 | 174 | func TestMergeCollectionMissingIDCondition(t *testing.T) { 175 | teardown := setupForkTest() 176 | defer teardown() 177 | 178 | path := "/collections/merge" 179 | subject := `{"collection":{}}` 180 | 181 | forkMux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { 182 | if r.Method != http.MethodPost { 183 | t.Errorf("Method is incorrect, have: %s, want: %s", r.Method, http.MethodPost) 184 | } 185 | w.WriteHeader(http.StatusOK) 186 | if _, err := w.Write([]byte(subject)); err != nil { 187 | t.Error(err) 188 | } 189 | }) 190 | 191 | ensurePath(t, forkMux, path) 192 | 193 | r, err := forkService.MergeCollection(context.Background(), "abcdef", "ghijkl", "") 194 | if err != nil { 195 | t.Fatal(err) 196 | } 197 | 198 | if r != "" { 199 | t.Errorf("Resource ID is incorrect, have: %s, want: %s", r, "") 200 | } 201 | } 202 | 203 | func TestMergeCollectionMissingResponseValueKeyCondition(t *testing.T) { 204 | teardown := setupForkTest() 205 | defer teardown() 206 | 207 | path := "/collections/merge" 208 | subject := `{"blah":{}}` 209 | 210 | forkMux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { 211 | if r.Method != http.MethodPost { 212 | t.Errorf("Method is incorrect, have: %s, want: %s", r.Method, http.MethodPost) 213 | } 214 | w.WriteHeader(http.StatusOK) 215 | if _, err := w.Write([]byte(subject)); err != nil { 216 | t.Error(err) 217 | } 218 | }) 219 | 220 | ensurePath(t, forkMux, path) 221 | 222 | r, err := forkService.MergeCollection(context.Background(), "abcdef", "ghijkl", "") 223 | if err != nil { 224 | t.Fatal(err) 225 | } 226 | 227 | if r != "" { 228 | t.Errorf("Resource ID is incorrect, have: %s, want: %s", r, "") 229 | } 230 | } 231 | 232 | func TestMergeCollectionError(t *testing.T) { 233 | teardown := setupForkTest() 234 | defer teardown() 235 | 236 | path := "/collections/merge" 237 | forkMux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { 238 | if r.Method != http.MethodPost { 239 | t.Errorf("Method is incorrect, have: %s, want: %s", r.Method, http.MethodPost) 240 | } 241 | w.WriteHeader(http.StatusInternalServerError) 242 | }) 243 | 244 | ensurePath(t, forkMux, path) 245 | 246 | _, err := forkService.MergeCollection(context.Background(), "abcdef", "ghijkl", "") 247 | if err == nil { 248 | t.Error("Expected error.") 249 | } 250 | } 251 | -------------------------------------------------------------------------------- /pkg/sdk/serviceget.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package sdk 18 | 19 | import ( 20 | "context" 21 | 22 | "github.com/kevinswiber/postmanctl/pkg/sdk/resources" 23 | ) 24 | 25 | // Collections returns all collections. 26 | func (s *Service) Collections(ctx context.Context) (*resources.CollectionListItems, error) { 27 | var resource resources.CollectionListResponse 28 | if _, err := s.get(ctx, &resource, nil, "collections"); err != nil { 29 | return nil, err 30 | } 31 | 32 | return &resource.Collections, nil 33 | } 34 | 35 | // Collection returns a single collection. 36 | func (s *Service) Collection(ctx context.Context, id string) (*resources.Collection, error) { 37 | var resource resources.CollectionResponse 38 | if _, err := s.get(ctx, &resource, nil, "collections", id); err != nil { 39 | return nil, err 40 | } 41 | 42 | return &resource.Collection, nil 43 | } 44 | 45 | // Environments returns all environments. 46 | func (s *Service) Environments(ctx context.Context) (*resources.EnvironmentListItems, error) { 47 | var resource resources.EnvironmentListResponse 48 | if _, err := s.get(ctx, &resource, nil, "environments"); err != nil { 49 | return nil, err 50 | } 51 | 52 | return &resource.Environments, nil 53 | } 54 | 55 | // Environment returns a single environment. 56 | func (s *Service) Environment(ctx context.Context, id string) (*resources.Environment, error) { 57 | var resource resources.EnvironmentResponse 58 | if _, err := s.get(ctx, &resource, nil, "environments", id); err != nil { 59 | return nil, err 60 | } 61 | 62 | return &resource.Environment, nil 63 | } 64 | 65 | // APIs returns all APIs. 66 | func (s *Service) APIs(ctx context.Context, workspace string) (*resources.APIListItems, error) { 67 | var resource resources.APIListResponse 68 | var params map[string]string 69 | if workspace != "" { 70 | params = make(map[string]string) 71 | params["workspace"] = workspace 72 | } 73 | 74 | if _, err := s.get(ctx, &resource, params, "apis"); err != nil { 75 | return nil, err 76 | } 77 | 78 | return &resource.APIs, nil 79 | } 80 | 81 | // API returns a single API. 82 | func (s *Service) API(ctx context.Context, id string) (*resources.API, error) { 83 | var resource resources.APIResponse 84 | if _, err := s.get(ctx, &resource, nil, "apis", id); err != nil { 85 | return nil, err 86 | } 87 | 88 | return &resource.API, nil 89 | } 90 | 91 | // APIVersions returns all API Versions. 92 | func (s *Service) APIVersions(ctx context.Context, apiID string) (*resources.APIVersionListItems, error) { 93 | var resource resources.APIVersionListResponse 94 | if _, err := s.get(ctx, &resource, nil, "apis", apiID, "versions"); err != nil { 95 | return nil, err 96 | } 97 | 98 | return &resource.APIVersions, nil 99 | } 100 | 101 | // APIVersion returns a single API Version. 102 | func (s *Service) APIVersion(ctx context.Context, apiID, id string) (*resources.APIVersion, error) { 103 | var resource resources.APIVersionResponse 104 | if _, err := s.get(ctx, &resource, nil, "apis", apiID, "versions", id); err != nil { 105 | return nil, err 106 | } 107 | 108 | return &resource.APIVersion, nil 109 | } 110 | 111 | // Schema returns a single schema for an API version. 112 | func (s *Service) Schema(ctx context.Context, apiID, apiVersionID, id string) (*resources.Schema, error) { 113 | var resource resources.SchemaResponse 114 | if _, err := s.get(ctx, &resource, nil, "apis", apiID, "versions", apiVersionID, "schemas", id); err != nil { 115 | return nil, err 116 | } 117 | 118 | return &resource.Schema, nil 119 | } 120 | 121 | // APIRelations returns the linked relations of an API 122 | func (s *Service) APIRelations(ctx context.Context, apiID, apiVersionID string) (*resources.APIRelations, error) { 123 | var resource resources.APIRelationsResource 124 | if _, err := s.get(ctx, &resource, nil, "apis", apiID, "versions", apiVersionID, "relations"); err != nil { 125 | return nil, err 126 | } 127 | 128 | return &resource.Relations, nil 129 | } 130 | 131 | // FormattedAPIRelationItems returns the formatted linked relations of an API 132 | func (s *Service) FormattedAPIRelationItems(ctx context.Context, apiID, apiVersionID string) (*resources.FormattedAPIRelationItems, error) { 133 | r, err := s.APIRelations(ctx, apiID, apiVersionID) 134 | if err != nil { 135 | return nil, err 136 | } 137 | 138 | f := resources.NewFormattedAPIRelationItems(r) 139 | return &f, nil 140 | } 141 | 142 | // User returns the current user. 143 | func (s *Service) User(ctx context.Context) (*resources.User, error) { 144 | var resource resources.UserResponse 145 | if _, err := s.get(ctx, &resource, nil, "me"); err != nil { 146 | return nil, err 147 | } 148 | 149 | return &resource.User, nil 150 | } 151 | 152 | // Workspaces returns the workspaces for the current user. 153 | func (s *Service) Workspaces(ctx context.Context) (*resources.WorkspaceListItems, error) { 154 | var resource resources.WorkspaceListResponse 155 | if _, err := s.get(ctx, &resource, nil, "workspaces"); err != nil { 156 | return nil, err 157 | } 158 | 159 | return &resource.Workspaces, nil 160 | } 161 | 162 | // Workspace returns a single workspace for the current user. 163 | func (s *Service) Workspace(ctx context.Context, id string) (*resources.Workspace, error) { 164 | var resource resources.WorkspaceResponse 165 | if _, err := s.get(ctx, &resource, nil, "workspaces", id); err != nil { 166 | return nil, err 167 | } 168 | 169 | return &resource.Workspace, nil 170 | } 171 | 172 | // Monitors returns the monitors for the current user. 173 | func (s *Service) Monitors(ctx context.Context) (*resources.MonitorListItems, error) { 174 | var resource resources.MonitorListResponse 175 | if _, err := s.get(ctx, &resource, nil, "monitors"); err != nil { 176 | return nil, err 177 | } 178 | 179 | return &resource.Monitors, nil 180 | } 181 | 182 | // Monitor returns a single monitor for the current user. 183 | func (s *Service) Monitor(ctx context.Context, id string) (*resources.Monitor, error) { 184 | var resource resources.MonitorResponse 185 | if _, err := s.get(ctx, &resource, nil, "monitors", id); err != nil { 186 | return nil, err 187 | } 188 | 189 | return &resource.Monitor, nil 190 | } 191 | 192 | // Mocks returns the mocks for the current user. 193 | func (s *Service) Mocks(ctx context.Context) (*resources.MockListItems, error) { 194 | var resource resources.MockListResponse 195 | if _, err := s.get(ctx, &resource, nil, "mocks"); err != nil { 196 | return nil, err 197 | } 198 | 199 | return &resource.Mocks, nil 200 | } 201 | 202 | // Mock returns a single mock for the current user. 203 | func (s *Service) Mock(ctx context.Context, id string) (*resources.Mock, error) { 204 | var resource resources.MockResponse 205 | if _, err := s.get(ctx, &resource, nil, "mocks", id); err != nil { 206 | return nil, err 207 | } 208 | 209 | return &resource.Mock, nil 210 | } 211 | -------------------------------------------------------------------------------- /pkg/sdk/servicereplace.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package sdk 18 | 19 | import ( 20 | "context" 21 | "encoding/json" 22 | "errors" 23 | "fmt" 24 | "io" 25 | "io/ioutil" 26 | 27 | "github.com/kevinswiber/postmanctl/pkg/sdk/resources" 28 | ) 29 | 30 | // ReplaceCollectionFromReader replaces a collection. 31 | func (s *Service) ReplaceCollectionFromReader(ctx context.Context, reader io.Reader, resourceID string) (string, error) { 32 | urlParams := make(map[string]string) 33 | urlParams["ID"] = resourceID 34 | 35 | return s.ReplaceFromReader(ctx, resources.CollectionType, reader, urlParams) 36 | } 37 | 38 | // ReplaceEnvironmentFromReader replaces an existing environment. 39 | func (s *Service) ReplaceEnvironmentFromReader(ctx context.Context, reader io.Reader, resourceID string) (string, error) { 40 | urlParams := make(map[string]string) 41 | urlParams["ID"] = resourceID 42 | 43 | return s.ReplaceFromReader(ctx, resources.EnvironmentType, reader, urlParams) 44 | } 45 | 46 | // ReplaceMockFromReader replaces an existing mock. 47 | func (s *Service) ReplaceMockFromReader(ctx context.Context, reader io.Reader, resourceID string) (string, error) { 48 | urlParams := make(map[string]string) 49 | urlParams["ID"] = resourceID 50 | 51 | return s.ReplaceFromReader(ctx, resources.MockType, reader, urlParams) 52 | } 53 | 54 | // ReplaceMonitorFromReader replaces an existing monitor. 55 | func (s *Service) ReplaceMonitorFromReader(ctx context.Context, reader io.Reader, resourceID string) (string, error) { 56 | urlParams := make(map[string]string) 57 | urlParams["ID"] = resourceID 58 | 59 | return s.ReplaceFromReader(ctx, resources.MonitorType, reader, urlParams) 60 | } 61 | 62 | // ReplaceWorkspaceFromReader replaces an existing API. 63 | func (s *Service) ReplaceWorkspaceFromReader(ctx context.Context, reader io.Reader, resourceID string) (string, error) { 64 | urlParams := make(map[string]string) 65 | urlParams["ID"] = resourceID 66 | 67 | return s.ReplaceFromReader(ctx, resources.WorkspaceType, reader, urlParams) 68 | } 69 | 70 | // ReplaceAPIFromReader replaces an existing API. 71 | func (s *Service) ReplaceAPIFromReader(ctx context.Context, reader io.Reader, resourceID string) (string, error) { 72 | urlParams := make(map[string]string) 73 | urlParams["ID"] = resourceID 74 | 75 | return s.ReplaceFromReader(ctx, resources.APIType, reader, urlParams) 76 | } 77 | 78 | // ReplaceAPIVersionFromReader replaces an existing API Version. 79 | func (s *Service) ReplaceAPIVersionFromReader(ctx context.Context, reader io.Reader, resourceID, apiID string) (string, error) { 80 | if apiID == "" { 81 | return "", errors.New("an API ID is required for creating a new API version") 82 | } 83 | 84 | urlParams := make(map[string]string) 85 | urlParams["ID"] = resourceID 86 | urlParams["apiID"] = apiID 87 | 88 | return s.ReplaceFromReader(ctx, resources.APIVersionType, reader, urlParams) 89 | } 90 | 91 | // ReplaceSchemaFromReader replaces an existing API Version. 92 | func (s *Service) ReplaceSchemaFromReader(ctx context.Context, reader io.Reader, resourceID, apiID, apiVersionID string) (string, error) { 93 | if apiID == "" { 94 | return "", errors.New("an API ID is required for creating a new schema") 95 | } 96 | 97 | if apiVersionID == "" { 98 | return "", errors.New("an API Version ID is required for creating a new schema") 99 | } 100 | 101 | urlParams := make(map[string]string) 102 | urlParams["ID"] = resourceID 103 | urlParams["apiID"] = apiID 104 | urlParams["apiVersionID"] = apiVersionID 105 | 106 | return s.ReplaceFromReader(ctx, resources.SchemaType, reader, urlParams) 107 | } 108 | 109 | // ReplaceFromReader posts a new resource to the Postman API. 110 | func (s *Service) ReplaceFromReader(ctx context.Context, t resources.ResourceType, reader io.Reader, urlParams map[string]string) (string, error) { 111 | b, err := ioutil.ReadAll(reader) 112 | 113 | if err != nil { 114 | return "", err 115 | } 116 | 117 | var v map[string]interface{} 118 | if err := json.Unmarshal(b, &v); err != nil { 119 | return "", err 120 | } 121 | 122 | var ( 123 | path []string 124 | requestBody []byte 125 | responseValueKey string 126 | ) 127 | 128 | switch t { 129 | case resources.CollectionType: 130 | path = []string{"collections", urlParams["ID"]} 131 | responseValueKey = "collection" 132 | 133 | c := struct { 134 | Collection map[string]interface{} `json:"collection"` 135 | }{ 136 | Collection: v, 137 | } 138 | requestBody, _ = json.Marshal(c) // already been unmarshalled, no error 139 | case resources.EnvironmentType: 140 | path = []string{"environments", urlParams["ID"]} 141 | responseValueKey = "environment" 142 | 143 | c := struct { 144 | Environment map[string]interface{} `json:"environment"` 145 | }{ 146 | Environment: v, 147 | } 148 | requestBody, _ = json.Marshal(c) 149 | case resources.MockType: 150 | path = []string{"mocks", urlParams["ID"]} 151 | responseValueKey = "mock" 152 | 153 | c := struct { 154 | Mock map[string]interface{} `json:"mock"` 155 | }{ 156 | Mock: v, 157 | } 158 | requestBody, _ = json.Marshal(c) 159 | case resources.MonitorType: 160 | path = []string{"monitors", urlParams["ID"]} 161 | responseValueKey = "monitor" 162 | 163 | c := struct { 164 | Monitor map[string]interface{} `json:"monitor"` 165 | }{ 166 | Monitor: v, 167 | } 168 | requestBody, _ = json.Marshal(c) 169 | case resources.WorkspaceType: 170 | path = []string{"workspaces", urlParams["ID"]} 171 | responseValueKey = "workspace" 172 | 173 | c := struct { 174 | Workspace map[string]interface{} `json:"workspace"` 175 | }{ 176 | Workspace: v, 177 | } 178 | requestBody, _ = json.Marshal(c) 179 | case resources.APIType: 180 | path = []string{"apis", urlParams["ID"]} 181 | responseValueKey = "api" 182 | 183 | c := struct { 184 | API map[string]interface{} `json:"api"` 185 | }{ 186 | API: v, 187 | } 188 | requestBody, _ = json.Marshal(c) 189 | case resources.APIVersionType: 190 | path = []string{"apis", urlParams["apiID"], "versions", urlParams["ID"]} 191 | responseValueKey = "version" 192 | 193 | c := struct { 194 | Version map[string]interface{} `json:"version"` 195 | }{ 196 | Version: v, 197 | } 198 | requestBody, _ = json.Marshal(c) 199 | case resources.SchemaType: 200 | path = []string{"apis", urlParams["apiID"], "versions", urlParams["apiVersionID"], "schemas", urlParams["ID"]} 201 | responseValueKey = "schema" 202 | 203 | c := struct { 204 | Schema map[string]interface{} `json:"schema"` 205 | }{ 206 | Schema: v, 207 | } 208 | requestBody, _ = json.Marshal(c) 209 | default: 210 | return "", fmt.Errorf("unable to replace resource, %+v not supported", t) 211 | } 212 | 213 | var responseBody interface{} 214 | if _, err := s.put(ctx, requestBody, &responseBody, path...); err != nil { 215 | return "", err 216 | } 217 | 218 | // Try a best attempt at returning the ID value. 219 | responseValue := responseBody.(map[string]interface{}) 220 | if v, ok := responseValue[responseValueKey]; ok { 221 | vMap := v.(map[string]interface{}) 222 | if v2, ok := vMap["uid"]; ok { 223 | return v2.(string), nil 224 | } 225 | if v2, ok := vMap["id"]; ok { 226 | return v2.(string), nil 227 | } 228 | return "", nil 229 | } 230 | return "", nil 231 | } 232 | -------------------------------------------------------------------------------- /pkg/sdk/servicerun.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package sdk 18 | 19 | import ( 20 | "context" 21 | "encoding/json" 22 | ) 23 | 24 | // RunMonitor runs a Postman monitor. 25 | func (s *Service) RunMonitor(ctx context.Context, id string) (json.RawMessage, error) { 26 | var responseBody json.RawMessage 27 | if _, err := s.post(ctx, nil, &responseBody, nil, "monitors", id, "run"); err != nil { 28 | return nil, err 29 | } 30 | 31 | return responseBody, nil 32 | } 33 | -------------------------------------------------------------------------------- /pkg/sdk/servicerun_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright © 2020 Kevin Swiber 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package sdk_test 18 | 19 | import ( 20 | "context" 21 | "net/http" 22 | "testing" 23 | 24 | "github.com/kevinswiber/postmanctl/pkg/sdk" 25 | ) 26 | 27 | func TestServiceRunMonitor(t *testing.T) { 28 | var ( 29 | mux *http.ServeMux 30 | service *sdk.Service 31 | ) 32 | 33 | teardown := setupService(&mux, &service) 34 | defer teardown() 35 | 36 | path := "/monitors/3/run" 37 | mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { 38 | if r.Method != http.MethodPost { 39 | t.Errorf("Method is incorrect, have: %s, want: %s", r.Method, http.MethodPost) 40 | } 41 | w.WriteHeader(http.StatusOK) 42 | if _, err := w.Write([]byte(`{"run":{}}`)); err != nil { 43 | t.Error(err) 44 | } 45 | }) 46 | 47 | ensurePath(t, mux, path) 48 | 49 | msg, err := service.RunMonitor(context.Background(), "3") 50 | if err != nil { 51 | t.Fatal(err) 52 | } 53 | 54 | b, err := msg.MarshalJSON() 55 | 56 | if err != nil { 57 | t.Fatal(err) 58 | } 59 | 60 | subject := "{\"run\":{}}" 61 | 62 | if string(b) != subject { 63 | t.Errorf("Response body is incorrect, have: %s, want: %s", string(b), subject) 64 | } 65 | } 66 | 67 | func TestServiceRunMonitorError(t *testing.T) { 68 | var ( 69 | mux *http.ServeMux 70 | service *sdk.Service 71 | ) 72 | 73 | teardown := setupService(&mux, &service) 74 | defer teardown() 75 | 76 | path := "/monitors/3/run" 77 | mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) { 78 | if r.Method != http.MethodPost { 79 | t.Errorf("Method is incorrect, have: %s, want: %s", r.Method, http.MethodPost) 80 | } 81 | w.WriteHeader(http.StatusInternalServerError) 82 | }) 83 | 84 | ensurePath(t, mux, path) 85 | 86 | _, err := service.RunMonitor(context.Background(), "3") 87 | if err == nil { 88 | t.Error("Expected error") 89 | } 90 | } 91 | --------------------------------------------------------------------------------