├── .github
├── PULL_REQUEST_TEMPLATE.md
├── dependabot.yml
├── ISSUE_TEMPLATE
│ ├── feature_request.md
│ └── bug_report.md
├── workflows
│ ├── test.yml
│ └── release.yml
└── CODEOWNERS
├── .dockerignore
├── _image
└── logo.png
├── .mergify.yml
├── providers
├── gcp
│ ├── testdata
│ │ └── gcloud
│ ├── gcp_test.go
│ └── gcp.go
├── providers.go
├── google
│ └── google.go
├── youtube
│ └── youtube.go
├── pagerduty
│ └── pagerduty.go
├── aws
│ └── aws.go
├── jira
│ └── jira.go
├── circleci
│ └── circleci.go
├── firebase
│ └── firebase.go
├── github
│ └── github.go
├── azure
│ └── azure.go
├── datadog
│ └── datadog.go
└── googleworkspace
│ └── googleworkspace.go
├── Makefile
├── cli
├── consts.go
├── version.go
├── root.go
├── google.go
├── youtube.go
├── github.go
├── circleci.go
├── pagerduty.go
├── azure.go
├── googleworkspace.go
├── datadog.go
├── jira.go
├── firebase.go
├── aws.go
└── gcp.go
├── go.mod
├── .gitignore
├── alias
├── testdata
│ └── config.toml
├── alias_test.go
└── alias.go
├── Dockerfile
├── .config
└── default.toml
├── .goreleaser.yml
├── cmd
└── biko
│ └── main.go
├── browser
└── browser.go
├── .golangci.yml
├── go.sum
├── LICENSE
└── README.md
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | ## What
2 |
3 | ## Why
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | /.git
2 | /bin
3 | /_image
4 | /.circleci
5 | /.github
--------------------------------------------------------------------------------
/_image/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KeisukeYamashita/biko/HEAD/_image/logo.png
--------------------------------------------------------------------------------
/.mergify.yml:
--------------------------------------------------------------------------------
1 | pull_request_rules:
2 | - name: Automatic merge on approval
3 | conditions:
4 | - "#approved-reviews-by>=1"
5 | actions:
6 | merge:
7 | method: merge
8 |
--------------------------------------------------------------------------------
/providers/gcp/testdata/gcloud:
--------------------------------------------------------------------------------
1 | [core]
2 | account = biko.is.nice.tool@maybe.com
3 | project = i-am-biko
4 |
5 | [compute]
6 | zone = asia-roppongi-c
7 | region = asia-minatoku
8 |
9 | [container]
10 | cluster = biko-cluster
11 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: gomod
4 | directory: "/"
5 | schedule:
6 | interval: weekly
7 | - package-ecosystem: "github-actions"
8 | directory: "/"
9 | schedule:
10 | interval: "weekly"
11 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | .PHONY: build
2 | build:
3 | go build -o bin/biko \
4 | ./cmd/biko
5 |
6 | .PHONY: dockerbuild
7 | dockerbuild:
8 | docker build . -t biko
9 |
10 | .PHONY: install
11 | install: build
12 | mkdir -p ${HOME}/.biko
13 | cp .config/default.toml ${HOME}/.biko/config.toml
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | ## What
11 |
12 |
13 | ## Why
14 |
15 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 |
3 | on:
4 | push:
5 | branches-ignore:
6 | - "master"
7 |
8 | jobs:
9 | test:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v2
13 | - uses: actions/setup-go@v2
14 | with:
15 | go-version: 1.16
16 | - run: go test -v ./...
17 |
--------------------------------------------------------------------------------
/cli/consts.go:
--------------------------------------------------------------------------------
1 | package cli
2 |
3 | const (
4 | categoryCloudProvider = "Cloud Provider"
5 | categoryContinousIntegration = "Continous Integration"
6 | categoryIncidentManagement = "Incident Management"
7 | categoryMonitor = "Monitor"
8 | categoryWebService = "Web service"
9 | categoryVersioning = "Versioning"
10 | )
11 |
--------------------------------------------------------------------------------
/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/KeisukeYamashita/biko
2 |
3 | require (
4 | github.com/BurntSushi/toml v0.3.1
5 | github.com/go-ini/ini v1.62.0
6 | github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect
7 | github.com/stretchr/testify v1.7.0
8 | github.com/urfave/cli v1.22.5
9 | gopkg.in/ini.v1 v1.48.0 // indirect
10 | )
11 |
12 | go 1.16
13 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | ## What's happening
11 |
12 |
13 | ## How should it be
14 |
15 |
16 | ## Additional context
17 |
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ### https://raw.github.com/github/gitignore/c1b7904af6689bd01646f008b0561d4f19a0e972/Go.gitignore
2 |
3 | # Binaries for programs and plugins
4 | *.exe
5 | *.exe~
6 | *.dll
7 | *.so
8 | *.dylib
9 |
10 | # Test binary, built with `go test -c`
11 | *.test
12 |
13 | # Output of the go coverage tool, specifically when used with LiteIDE
14 | *.out
15 |
16 | # Build artifact
17 | bin/
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # This is a CODEOWNERS file to define individuals or teams that are responsible
2 | # for code in a repository.
3 | #
4 | # For more detail about CODEOWNERS, refer to following articles:
5 | # - https://help.github.com/articles/about-codeowners/
6 | # - https://blog.github.com/2017-07-06-introducing-code-owners/
7 |
8 | # Allow KeisukeYamashita to approve the modification of all code.
9 | * 19yamashita15@gmail.com
10 |
--------------------------------------------------------------------------------
/alias/testdata/config.toml:
--------------------------------------------------------------------------------
1 | [aws]
2 | [aws.alias]
3 |
4 | [azure]
5 | [azure.alias]
6 |
7 | [gcp]
8 | [gcp.alias]
9 | myalias = "Hello"
10 |
11 | [datadog]
12 | [datadog.alias]
13 |
14 | [google]
15 | [google.alias]
16 |
17 | [youtube]
18 | [youtube.alias]
19 |
20 | [pagerduty]
21 | [pagerduty.alias]
22 |
23 | [github]
24 | [github.alias]
25 |
26 | [firebase]
27 | [firebase.alias]
28 |
29 | [jira]
30 | [jira.alias]
31 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # Build Go Server Binary
2 | FROM golang:1.16
3 | LABEL MAINTAINER=KeisukeYamashita
4 |
5 | ENV GO111MODULE on
6 |
7 | ARG SERVICE_NAME
8 | ARG VERSION
9 |
10 | WORKDIR /project
11 |
12 | COPY . ./
13 | RUN CGO_ENABLED=0 GOOS=linux go install -v \
14 | -ldflags="-w -s -X main.version=${VERSION} -X main.serviceName=${SERVICE_NAME}" \
15 | ./cmd/biko
16 |
17 | FROM alpine:latest
18 | COPY --from=0 /go/bin/biko /bin/biko
19 | ENTRYPOINT ["/bin/biko"]
--------------------------------------------------------------------------------
/.config/default.toml:
--------------------------------------------------------------------------------
1 | [aws]
2 | [aws.alias]
3 |
4 | [azure]
5 | [azure.alias]
6 |
7 | [gcp]
8 | [gcp.alias]
9 |
10 | [datadog]
11 | [datadog.alias]
12 |
13 | [google]
14 | [google.alias]
15 |
16 | [googleworkspace]
17 | [googleworkspace.alias]
18 |
19 | [youtube]
20 | [youtube.alias]
21 |
22 | [pagerduty]
23 | [pagerduty.alias]
24 |
25 | [github]
26 | [github.alias]
27 |
28 | [circleci]
29 | [circleci.alias]
30 |
31 | [firebase]
32 | [firebase.alias]
33 |
34 | [jira]
35 | [jira.alias]
36 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release
2 |
3 | on:
4 | push:
5 | tags:
6 | - "v[0-9]+.[0-9]+.[0-9]+"
7 |
8 | jobs:
9 | release:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v2
13 | with:
14 | fetch-depth: 0
15 | - uses: actions/setup-go@v2
16 | with:
17 | go-version: 1.16
18 | - uses: goreleaser/goreleaser-action@v2
19 | with:
20 | version: latest
21 | args: release --rm-dist
22 | env:
23 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
24 | HOMEBREW_TAP_GITHUB_TOKEN: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
25 |
--------------------------------------------------------------------------------
/.goreleaser.yml:
--------------------------------------------------------------------------------
1 | builds:
2 | - main: ./cmd/biko/main.go
3 | ldflags:
4 | - -s -w
5 | - -X github.com/KeisukeYamashita/biko/cli.Version={{.Tag}}
6 | goos:
7 | - linux
8 | - darwin
9 | - windows
10 | brews:
11 | - tap:
12 | owner: KeisukeYamashita
13 | name: homebrew-tap
14 | token: "{{ .Env.HOMEBREW_TAP_GITHUB_TOKEN }}"
15 | url_template: "http://github.com/KeisukeYamashita/biko/releases/download/{{ .Tag }}/{{ .ArtifactName }}"
16 | commit_author:
17 | name: goreleaserbot
18 | email: goreleaser@carlosbecker.com
19 | folder: Formula
20 | description: "CLI tool to jump to your browser directly"
21 | homepage: "https://github.com/KeisukeYamashita/biko"
22 | test: |
23 | system "#{bin}/biko --version"
24 |
--------------------------------------------------------------------------------
/cmd/biko/main.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package main
16 |
17 | import (
18 | "log"
19 |
20 | "github.com/KeisukeYamashita/biko/cli"
21 | )
22 |
23 | func main() {
24 | if err := cli.Run(); err != nil {
25 | log.Fatal(err)
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/providers/providers.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package providers
16 |
17 | import "github.com/urfave/cli"
18 |
19 | // Provider are interfaces ...
20 | type Provider interface {
21 | Init(c *cli.Context) error
22 | GetTargetURL() (string, error)
23 | }
24 |
--------------------------------------------------------------------------------
/cli/version.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package cli
16 |
17 | import (
18 | "fmt"
19 |
20 | "github.com/urfave/cli"
21 | )
22 |
23 | const (
24 | // Version is injected by goreleaser.
25 | Version = ""
26 | )
27 |
28 | func newVersionCmd() cli.Command {
29 | return cli.Command{
30 | Name: "version",
31 | Usage: "Show biko version",
32 | Aliases: []string{"v"},
33 | Action: func(c *cli.Context) error {
34 | fmt.Printf("Biko %s\n", Version)
35 | return nil
36 | },
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/cli/root.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package cli
16 |
17 | import (
18 | "os"
19 |
20 | "github.com/urfave/cli"
21 | )
22 |
23 | // Run creates command and run the command
24 | func Run() error {
25 | cmd := NewCmdRoot()
26 | return cmd.Run(os.Args)
27 | }
28 |
29 | // NewCmdRoot will create root command
30 | func NewCmdRoot() *cli.App {
31 | cmd := cli.NewApp()
32 | cmd.Version = Version
33 | cmd.Commands = rootSubCommands()
34 | return cmd
35 | }
36 |
37 | func rootSubCommands() []cli.Command {
38 | return []cli.Command{
39 | newAWSCmd(),
40 | newAzureCmd(),
41 | newCircleCICmd(),
42 | newDatadaogCmd(),
43 | newFirebaseCmd(),
44 | newGCPCmd(),
45 | newGithubCmd(),
46 | newGoogleCmd(),
47 | newGoogleWorkspaceCmd(),
48 | newJIRACmd(),
49 | newPagerDutyCmd(),
50 | newVersionCmd(),
51 | newYoutubeCmd(),
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/browser/browser.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package browser
16 |
17 | import (
18 | "fmt"
19 | "os/exec"
20 | "runtime"
21 |
22 | "github.com/KeisukeYamashita/biko/providers"
23 | "github.com/urfave/cli"
24 | )
25 |
26 | // Open wraps the browser opener
27 | func Open(c *cli.Context, provider providers.Provider) error {
28 | if err := provider.Init(c); err != nil {
29 | return err
30 | }
31 | url, err := provider.GetTargetURL()
32 | if err != nil {
33 | return err
34 | }
35 | return openbrowser(url)
36 | }
37 |
38 | func openbrowser(url string) error {
39 | var err error
40 | switch runtime.GOOS {
41 | case "linux":
42 | err = exec.Command("xdg-open", url).Start()
43 | case "windows":
44 | err = exec.Command("rundll32", "url.dll,FileProtocolHandler", url).Start()
45 | case "darwin":
46 | err = exec.Command("open", url).Start()
47 | default:
48 | err = fmt.Errorf("unsupported platform")
49 | }
50 | if err != nil {
51 | return err
52 | }
53 |
54 | return nil
55 | }
56 |
--------------------------------------------------------------------------------
/alias/alias_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package alias
16 |
17 | import (
18 | "reflect"
19 | "testing"
20 | )
21 |
22 | func TestGetConfig(t *testing.T) {
23 | // This should be same in the testdata/config.toml
24 | wantConf := &TomlConfig{
25 | GCP: map[string]interface{}{
26 | "alias": map[string]interface{}{
27 | "myalias": "biko",
28 | },
29 | },
30 | }
31 |
32 | testCases := map[string]struct {
33 | path string
34 | wantConf *TomlConfig
35 | wantResult bool
36 | }{
37 | "ok": {
38 | path: "./testdata/config.toml",
39 | wantConf: wantConf,
40 | wantResult: true,
41 | },
42 | "bad path": {
43 | path: "bad/path",
44 | wantConf: nil,
45 | wantResult: false,
46 | },
47 | }
48 |
49 | for n, tc := range testCases {
50 | defaultConfigPath = tc.path
51 | conf, err := GetConfig()
52 | if err != nil {
53 | if tc.wantResult {
54 | t.Fatalf("GetConfig fail testCase => %s, error:%v", n, err)
55 | continue
56 | }
57 | continue
58 | }
59 |
60 | if conf == nil {
61 | t.Fatalf("GetConfig fail with nil conf testCase => %s", n)
62 | }
63 |
64 | if reflect.DeepEqual(conf, wantConf) {
65 | t.Fatalf("GetConfig fail not get config, want:%v, got:%v", wantConf, conf)
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/cli/google.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package cli
16 |
17 | import (
18 | "github.com/KeisukeYamashita/biko/browser"
19 | "github.com/KeisukeYamashita/biko/providers/google"
20 | "github.com/urfave/cli"
21 | )
22 |
23 | func newGoogleCmd() cli.Command {
24 | return cli.Command{
25 | Name: "google",
26 | Aliases: []string{"g"},
27 | Usage: "Open Google source",
28 | Category: categoryWebService,
29 | Flags: []cli.Flag{
30 | cli.StringFlag{
31 | Name: "project",
32 | Usage: "Specify the project to open",
33 | },
34 | },
35 | Action: func(c *cli.Context) error {
36 | g, err := google.GetProvider()
37 | if err != nil {
38 | return err
39 | }
40 | return browser.Open(c, g)
41 | },
42 | Subcommands: []cli.Command{
43 | newGoogleSearchCmd(),
44 | },
45 | }
46 | }
47 |
48 | func newGoogleSearchCmd() cli.Command {
49 | return cli.Command{
50 | Name: "search",
51 | Aliases: []string{"s"},
52 | Usage: "Search a page",
53 | Flags: []cli.Flag{
54 | cli.StringFlag{
55 | Name: "query, q",
56 | Usage: "Query a page",
57 | },
58 | },
59 | Action: func(c *cli.Context) error {
60 | g, err := google.GetProvider()
61 | if err != nil {
62 | return err
63 | }
64 | return browser.Open(c, g)
65 | },
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/cli/youtube.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package cli
16 |
17 | import (
18 | "github.com/KeisukeYamashita/biko/browser"
19 | "github.com/KeisukeYamashita/biko/providers/youtube"
20 | "github.com/urfave/cli"
21 | )
22 |
23 | func newYoutubeCmd() cli.Command {
24 | return cli.Command{
25 | Name: "youtube",
26 | Aliases: []string{"yt"},
27 | Usage: "Open Youtube source",
28 | Category: categoryWebService,
29 | Flags: []cli.Flag{
30 | cli.StringFlag{
31 | Name: "project",
32 | Usage: "Specify the project to open",
33 | },
34 | },
35 | Action: func(c *cli.Context) error {
36 | yt, err := youtube.GetProvider()
37 | if err != nil {
38 | return err
39 | }
40 | return browser.Open(c, yt)
41 | },
42 | Subcommands: []cli.Command{
43 | newYoutubeSearchCmd(),
44 | },
45 | }
46 | }
47 |
48 | func newYoutubeSearchCmd() cli.Command {
49 | return cli.Command{
50 | Name: "search",
51 | Aliases: []string{"s"},
52 | Usage: "Search a page",
53 | Flags: []cli.Flag{
54 | cli.StringFlag{
55 | Name: "query, q",
56 | Usage: "Query a page",
57 | },
58 | },
59 | Action: func(c *cli.Context) error {
60 | yt, err := youtube.GetProvider()
61 | if err != nil {
62 | return err
63 | }
64 | return browser.Open(c, yt)
65 | },
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/.golangci.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2019 The Biko Authors.
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | service:
16 | golangci-lint-version: 1.17.x
17 | run:
18 | deadline: 5m
19 |
20 | skip-dirs:
21 | - vendor$
22 |
23 | skip-files:
24 | - ".*\\.pb\\.go"
25 | - ".*\\.mock\\.go"
26 | - ".*(.|_)gen\\.go"
27 |
28 | linters:
29 | enable-all: true
30 | disable:
31 | - depguard
32 | - dupl
33 | - gochecknoglobals
34 | - gochecknoinits
35 | - goconst
36 | - gocyclo
37 | - gosec
38 | - nakedret
39 | - prealloc
40 | - scopelint
41 | fast: false
42 |
43 | linters-settings:
44 | errcheck:
45 | check-type-assertions: false
46 | check-blank: true
47 | exclude: .errcheckignore
48 | govet:
49 | check-shadowing: false
50 | golint:
51 | min-confidence: 0.8
52 | gofmt:
53 | simplify: true
54 | goimports:
55 | local-prefixes: github.com/micnncim/protocol-buffers-language-server
56 | maligned:
57 | suggest-new: true
58 | misspell:
59 | locale: US
60 | lll:
61 | line-length: 160
62 | tab-width: 1
63 | unused:
64 | check-exported: false
65 | unparam:
66 | algo: cha
67 | check-exported: false
68 | gocritic:
69 | disabled-checks:
70 | - regexpMust
71 | enabled-tags:
72 | - performance
73 | settings:
74 | captLocal:
75 | paramsOnly: true
76 | hugeParam:
77 | sizeThreshold: 80
78 | rangeExprCopy:
79 | sizeThreshold: 512
80 | rangeValCopy:
81 | sizeThreshold: 128
82 | issues:
83 | exclude-rules:
84 | - path: _test\.go$
85 | linters:
86 | - errcheck
87 | - maligned
--------------------------------------------------------------------------------
/providers/gcp/gcp_test.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package gcp
16 |
17 | import (
18 | "reflect"
19 | "testing"
20 |
21 | "github.com/stretchr/testify/assert"
22 | )
23 |
24 | const (
25 | testDataPath = "./testdata/gcloud"
26 | )
27 |
28 | func TestGetSDKConfig(t *testing.T) {
29 | defaultGoogleSDKConfigPath = testDataPath
30 |
31 | conf, err := getSDKConfig()
32 | want := &SDKConfig{
33 | &Core{
34 | Account: "biko.is.nice.tool@maybe.com",
35 | Project: "i-am-biko",
36 | },
37 | &Compute{
38 | Zone: "asia-roppongi-c",
39 | Region: "asia-minatoku",
40 | },
41 | &Container{
42 | Cluster: "biko-cluster",
43 | },
44 | }
45 | if err != nil {
46 | t.Fatalf("getSDKConfig failed error:%v", err)
47 | }
48 |
49 | if !reflect.DeepEqual(conf, want) {
50 | t.Fatalf("getSDKConfig failed not deep equal got:%v, want:%v", conf, want)
51 | }
52 | }
53 |
54 | func TestConstructPageStateParam(t *testing.T) {
55 | tests := map[string]struct {
56 | namespace string
57 | want string
58 | }{
59 | "single namespace": {
60 | namespace: "abc",
61 | want: "(\"savedViews\":(\"n\":[\"abc\"]))",
62 | },
63 | "two namespaces": {
64 | namespace: "test1,test2",
65 | want: "(\"savedViews\":(\"n\":[\"test1\",\"test2\"]))",
66 | },
67 | "three namespaces": {
68 | namespace: "test1,test2,test3",
69 | want: "(\"savedViews\":(\"n\":[\"test1\",\"test2\",\"test3\"]))",
70 | },
71 | }
72 |
73 | for name, tt := range tests {
74 | t.Run(name, func(t *testing.T) {
75 | assert.Equal(t, tt.want, constructPageStateParam(tt.namespace))
76 | })
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/providers/google/google.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package google
16 |
17 | import (
18 | "net/url"
19 | "path"
20 |
21 | "github.com/KeisukeYamashita/biko/alias"
22 | "github.com/urfave/cli"
23 | )
24 |
25 | // Provider ...
26 | type Provider struct {
27 | baseURL *url.URL
28 | URL *url.URL
29 | Ctx *cli.Context
30 | Aliases map[string]interface{}
31 | }
32 |
33 | // GetProvider ...
34 | func GetProvider() (*Provider, error) {
35 | conf, err := alias.GetConfig()
36 | if err != nil {
37 | return nil, err
38 | }
39 |
40 | return &Provider{
41 | Aliases: conf.Github["alias"].(map[string]interface{}),
42 | }, nil
43 | }
44 |
45 | // Init ...
46 | func (p *Provider) Init(c *cli.Context) error {
47 | p.Ctx = c
48 | return nil
49 | }
50 |
51 | // GetTargetURL ...
52 | func (p *Provider) GetTargetURL() (string, error) {
53 | const baseURL = "https://google.com"
54 | var err error
55 | if p.baseURL, err = url.Parse(baseURL); err != nil {
56 | return "", err
57 | }
58 | p.addProductPath(p.Ctx.Command.Name)
59 | return p.URL.String(), nil
60 | }
61 |
62 | func (p *Provider) addProductPath(product string) {
63 | p.URL = p.baseURL
64 | switch product {
65 | case "search":
66 | p.join("search")
67 | param := url.Values{}
68 | var query string
69 | if query = p.GetCtxString("query"); query != "" {
70 | param.Add("q", query)
71 | p.URL.RawQuery = param.Encode()
72 | }
73 | }
74 | }
75 |
76 | func (p *Provider) join(additionPath string) {
77 | if p.URL == nil {
78 | p.URL = p.baseURL
79 | }
80 | p.URL.Path = path.Join(p.URL.Path, additionPath)
81 | }
82 |
83 | // GetCtxString ...
84 | func (p *Provider) GetCtxString(str string) string {
85 | key := p.Ctx.String(str)
86 | if key == "" {
87 | return ""
88 | }
89 | value, ok := p.Aliases[key].(string)
90 | if !ok {
91 | return key
92 | }
93 | if value == "" {
94 | return key
95 | }
96 | return value
97 | }
98 |
--------------------------------------------------------------------------------
/providers/youtube/youtube.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package youtube
16 |
17 | import (
18 | "net/url"
19 | "path"
20 |
21 | "github.com/KeisukeYamashita/biko/alias"
22 | "github.com/urfave/cli"
23 | )
24 |
25 | // Provider ...
26 | type Provider struct {
27 | baseURL *url.URL
28 | URL *url.URL
29 | Ctx *cli.Context
30 | Aliases map[string]interface{}
31 | }
32 |
33 | // GetProvider ...
34 | func GetProvider() (*Provider, error) {
35 | conf, err := alias.GetConfig()
36 | if err != nil {
37 | return nil, err
38 | }
39 |
40 | return &Provider{
41 | Aliases: conf.Youtube["alias"].(map[string]interface{}),
42 | }, nil
43 | }
44 |
45 | // Init ...
46 | func (p *Provider) Init(c *cli.Context) error {
47 | p.Ctx = c
48 | return nil
49 | }
50 |
51 | // GetTargetURL ...
52 | func (p *Provider) GetTargetURL() (string, error) {
53 | const baseURL = "https://youtube.com"
54 | var err error
55 | if p.baseURL, err = url.Parse(baseURL); err != nil {
56 | return "", err
57 | }
58 |
59 | p.addProductPath(p.Ctx.Command.Name)
60 | return p.URL.String(), nil
61 | }
62 |
63 | func (p *Provider) addProductPath(product string) {
64 | switch product {
65 | case "search":
66 | p.join("results")
67 | param := url.Values{}
68 | var query string
69 | if query = p.Ctx.String("query"); query != "" {
70 | param.Add("search_query", query)
71 | p.URL.RawQuery = param.Encode()
72 | }
73 | }
74 | }
75 |
76 | // GetCtxString ...
77 | func (p *Provider) GetCtxString(str string) string {
78 | key := p.Ctx.String(str)
79 | if key == "" {
80 | return ""
81 | }
82 | value, ok := p.Aliases[key].(string)
83 | if !ok {
84 | return key
85 | }
86 | if value == "" {
87 | return key
88 | }
89 | return value
90 | }
91 |
92 | func (p *Provider) join(additionPath string) {
93 | if p.URL == nil {
94 | p.URL = p.baseURL
95 | }
96 | p.URL.Path = path.Join(p.URL.Path, additionPath)
97 | }
98 |
--------------------------------------------------------------------------------
/alias/alias.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package alias
16 |
17 | import (
18 | "fmt"
19 | "os"
20 |
21 | "github.com/BurntSushi/toml"
22 | )
23 |
24 | var (
25 | defaultConfigPath = os.Getenv("HOME") + "/.biko/config.toml"
26 | )
27 |
28 | // TomlConfig ...
29 | type TomlConfig struct {
30 | AWS map[string]interface{} `toml:"aws"`
31 | Azure map[string]interface{} `toml:"azure"`
32 | GCP map[string]interface{} `toml:"gcp"`
33 | Datadog map[string]interface{} `toml:"datadog"`
34 | Google map[string]interface{} `toml:"google"`
35 | GoogleWorkspace map[string]interface{} `toml:"googleworkspace"`
36 | Youtube map[string]interface{} `toml:"youtube"`
37 | PagerDuty map[string]interface{} `toml:"pagerduty"`
38 | Github map[string]interface{} `toml:"github"`
39 | CircleCI map[string]interface{} `toml:"circleci"`
40 | Firebase map[string]interface{} `toml:"firebase"`
41 | JIRA map[string]interface{} `toml:"jira"`
42 | }
43 |
44 | // GetConfig ...
45 | func GetConfig() (*TomlConfig, error) {
46 | confPath, err := getConfigPath()
47 | if err != nil {
48 | return nil, err
49 | }
50 |
51 | conf, err := getConfig(confPath)
52 | if err != nil {
53 | return nil, err
54 | }
55 |
56 | return conf, nil
57 | }
58 |
59 | func getConfigPath() (string, error) {
60 | var confPath string
61 | if confPath = os.Getenv("BIKO_CONFIG_PATH"); confPath == "" {
62 | confPath = defaultConfigPath
63 | }
64 |
65 | if !configFileExists(confPath) {
66 | return "", fmt.Errorf("config file doesn't exists in %s", confPath)
67 | }
68 |
69 | return confPath, nil
70 | }
71 |
72 | func configFileExists(path string) bool {
73 | _, err := os.Stat(path)
74 | return err == nil
75 | }
76 |
77 | func getConfig(loadPath string) (*TomlConfig, error) {
78 | var conf TomlConfig
79 | if _, err := toml.DecodeFile(loadPath, &conf); err != nil {
80 | return nil, err
81 | }
82 |
83 | return &conf, nil
84 | }
85 |
--------------------------------------------------------------------------------
/providers/pagerduty/pagerduty.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package pagerduty
16 |
17 | import (
18 | "fmt"
19 | "net/url"
20 | "path"
21 |
22 | "github.com/KeisukeYamashita/biko/alias"
23 | "github.com/urfave/cli"
24 | )
25 |
26 | // Provider ...
27 | type Provider struct {
28 | baseURL *url.URL
29 | URL *url.URL
30 | Ctx *cli.Context
31 | Org string
32 | Aliases map[string]interface{}
33 | }
34 |
35 | // GetProvider ...
36 | func GetProvider() (*Provider, error) {
37 | conf, err := alias.GetConfig()
38 | if err != nil {
39 | return nil, err
40 | }
41 |
42 | return &Provider{
43 | Aliases: conf.PagerDuty["alias"].(map[string]interface{}),
44 | }, nil
45 | }
46 |
47 | // Init ...
48 | func (p *Provider) Init(c *cli.Context) error {
49 | p.Ctx = c
50 | return nil
51 | }
52 |
53 | // GetTargetURL ...
54 | func (p *Provider) GetTargetURL() (string, error) {
55 | var baseURL = fmt.Sprintf("https://%s.pagerduty.com", p.Org)
56 | var err error
57 | if p.baseURL, err = url.Parse(baseURL); err != nil {
58 | return "", err
59 | }
60 |
61 | p.addProductPath(p.Ctx.Command.Name)
62 | return p.URL.String(), nil
63 | }
64 |
65 | func (p *Provider) addProductPath(product string) {
66 | switch product {
67 | case "incidents":
68 | p.join("incidents")
69 | case "alerts":
70 | p.join("alerts")
71 | case "schedules":
72 | p.join("schedules")
73 | default:
74 | p.join("incidents")
75 | }
76 |
77 | return
78 | }
79 |
80 | func (p *Provider) join(additionPath string) {
81 | if p.URL == nil {
82 | p.URL = p.baseURL
83 | }
84 | p.URL.Path = path.Join(p.URL.Path, additionPath)
85 | }
86 |
87 | // GetCtxString ...
88 | func (p *Provider) GetCtxString(str string) string {
89 | key := p.Ctx.String(str)
90 | if key == "" {
91 | return ""
92 | }
93 | value, ok := p.Aliases[key].(string)
94 | if !ok {
95 | return key
96 | }
97 | if value == "" {
98 | return key
99 | }
100 | return value
101 | }
102 |
--------------------------------------------------------------------------------
/providers/aws/aws.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package aws
16 |
17 | import (
18 | "net/url"
19 | "path"
20 |
21 | "github.com/KeisukeYamashita/biko/alias"
22 | "github.com/urfave/cli"
23 | )
24 |
25 | // Provider ...
26 | type Provider struct {
27 | baseURL *url.URL
28 | URL *url.URL
29 | Ctx *cli.Context
30 | Aliases map[string]interface{}
31 | }
32 |
33 | // GetProvider ...
34 | func GetProvider() (*Provider, error) {
35 | conf, err := alias.GetConfig()
36 | if err != nil {
37 | return nil, err
38 | }
39 |
40 | return &Provider{
41 | Aliases: conf.AWS["alias"].(map[string]interface{}),
42 | }, nil
43 | }
44 |
45 | // Init ...
46 | func (p *Provider) Init(c *cli.Context) error {
47 | p.Ctx = c
48 | return nil
49 | }
50 |
51 | // GetTargetURL ...
52 | func (p *Provider) GetTargetURL() (string, error) {
53 | const baseURL = "https://console.aws.amazon.com"
54 | var err error
55 | if p.baseURL, err = url.Parse(baseURL); err != nil {
56 | return "", err
57 | }
58 | p.addProductPath(p.Ctx.Command.Name)
59 | return p.URL.String(), nil
60 | }
61 |
62 | func (p *Provider) addProductPath(product string) {
63 | p.join(product)
64 | switch product {
65 | case "ec2":
66 | p.join("v2")
67 | case "s3":
68 | p.URL, _ = url.Parse("https://s3.console.aws.amazon.com/s3")
69 | default:
70 | return
71 | }
72 |
73 | var region string
74 | if region = p.GetCtxString("region"); region != "" {
75 | params := url.Values{}
76 | params.Add("region", region)
77 | p.URL.RawQuery = params.Encode()
78 | }
79 | }
80 |
81 | // GetCtxString ...
82 | func (p *Provider) GetCtxString(str string) string {
83 | key := p.Ctx.String(str)
84 | if key == "" {
85 | return ""
86 | }
87 | value, ok := p.Aliases[key].(string)
88 | if !ok {
89 | return key
90 | }
91 | if value == "" {
92 | return key
93 | }
94 | return value
95 | }
96 |
97 | func (p *Provider) join(additionPath string) {
98 | if p.URL == nil {
99 | p.URL = p.baseURL
100 | }
101 | p.URL.Path = path.Join(p.URL.Path, additionPath)
102 | }
103 |
--------------------------------------------------------------------------------
/providers/jira/jira.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package jira
16 |
17 | import (
18 | "fmt"
19 | "net/url"
20 | "path"
21 |
22 | "github.com/KeisukeYamashita/biko/alias"
23 | "github.com/urfave/cli"
24 | )
25 |
26 | // Provider ...
27 | type Provider struct {
28 | BaseURL *url.URL
29 | URL *url.URL
30 | Ctx *cli.Context
31 | Aliases map[string]interface{}
32 | }
33 |
34 | // GetProvider ...
35 | func GetProvider() (*Provider, error) {
36 | conf, err := alias.GetConfig()
37 | if err != nil {
38 | return nil, err
39 | }
40 |
41 | return &Provider{
42 | Aliases: conf.JIRA["alias"].(map[string]interface{}),
43 | }, nil
44 | }
45 |
46 | // Init ...
47 | func (p *Provider) Init(c *cli.Context) error {
48 | p.Ctx = c
49 | return nil
50 | }
51 |
52 | // GetTargetURL ...
53 | func (p *Provider) GetTargetURL() (string, error) {
54 | p.addProductPath(p.Ctx.Command.Name)
55 | return p.URL.String(), nil
56 | }
57 |
58 | func (p *Provider) addProductPath(product string) {
59 | switch product {
60 | case "dashboard":
61 | p.join("secure/Dashboard.jspa")
62 | case "projects":
63 | p.join("secure/BrowseProjects.jspa")
64 | case "people":
65 | p.join(fmt.Sprintf("jira/%s", product))
66 | case "issues":
67 | p.join(product)
68 | case "backlog":
69 | p.join("browse")
70 | if project := p.GetCtxString("project"); project != "" {
71 | p.join(project)
72 | }
73 | case "reports":
74 | project := p.GetCtxString("project")
75 | p.join(fmt.Sprintf("projects/%s?selectedItem=com.atlassian.jira.jira-projects-plugin%%3Areport-page", project))
76 | default:
77 | p.join("secure/Dashboard.jspa")
78 | }
79 |
80 | return
81 | }
82 |
83 | func (p *Provider) join(additionPath string) {
84 | if p.URL == nil {
85 | p.URL = p.BaseURL
86 | }
87 | p.URL.Path = path.Join(p.URL.Path, additionPath)
88 | }
89 |
90 | // GetCtxString ...
91 | func (p *Provider) GetCtxString(str string) string {
92 | key := p.Ctx.String(str)
93 | if key == "" {
94 | return ""
95 | }
96 | value, ok := p.Aliases[key].(string)
97 | if !ok {
98 | return key
99 | }
100 | if value == "" {
101 | return key
102 | }
103 | return value
104 | }
105 |
--------------------------------------------------------------------------------
/providers/circleci/circleci.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package circleci
16 |
17 | import (
18 | "fmt"
19 | "net/url"
20 | "path"
21 |
22 | "github.com/KeisukeYamashita/biko/alias"
23 | "github.com/urfave/cli"
24 | )
25 |
26 | // Provider ...
27 | type Provider struct {
28 | baseURL *url.URL
29 | URL *url.URL
30 | Ctx *cli.Context
31 | Org string
32 | Aliases map[string]interface{}
33 | }
34 |
35 | // GetProvider ...
36 | func GetProvider(org string) (*Provider, error) {
37 | conf, err := alias.GetConfig()
38 | if err != nil {
39 | return nil, err
40 | }
41 |
42 | return &Provider{
43 | Aliases: conf.CircleCI["alias"].(map[string]interface{}),
44 | Org: org,
45 | }, nil
46 | }
47 |
48 | // Init ...
49 | func (p *Provider) Init(c *cli.Context) error {
50 | p.Ctx = c
51 | return nil
52 | }
53 |
54 | // GetTargetURL ...
55 | func (p *Provider) GetTargetURL() (string, error) {
56 | const baseURL = "https://circleci.com/"
57 | var err error
58 | if p.baseURL, err = url.Parse(baseURL); err != nil {
59 | return "", err
60 | }
61 | p.addProductPath(p.Ctx.Command.Name)
62 | return p.URL.String(), nil
63 | }
64 |
65 | func (p *Provider) addProductPath(product string) {
66 | p.URL = p.baseURL
67 | switch product {
68 | case "jobs":
69 | p.join(fmt.Sprintf("gh/%s", p.Org))
70 | var project string
71 | if project = p.GetCtxString("project"); project != "" {
72 | p.join(fmt.Sprintf("gh/%s/%s/", p.Org, project))
73 | return
74 | }
75 | return
76 | case "workflows":
77 | p.join(fmt.Sprintf("gh/%s/workflows", p.Org))
78 | var project string
79 | if project = p.GetCtxString("project"); project != "" {
80 | p.join(project)
81 | return
82 | }
83 | return
84 | default:
85 | return
86 | }
87 | }
88 |
89 | // GetCtxString ...
90 | func (p *Provider) GetCtxString(str string) string {
91 | key := p.Ctx.String(str)
92 | if key == "" {
93 | return ""
94 | }
95 | value, ok := p.Aliases[key].(string)
96 | if !ok {
97 | return key
98 | }
99 | if value == "" {
100 | return key
101 | }
102 | return value
103 | }
104 |
105 | func (p *Provider) join(additionPath string) {
106 | if p.URL == nil {
107 | p.URL = p.baseURL
108 | }
109 | p.URL.Path = path.Join(p.URL.Path, additionPath)
110 | }
111 |
--------------------------------------------------------------------------------
/providers/firebase/firebase.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package firebase
16 |
17 | import (
18 | "fmt"
19 | "net/url"
20 | "path"
21 |
22 | "github.com/KeisukeYamashita/biko/alias"
23 | "github.com/urfave/cli"
24 | )
25 |
26 | // Provider ...
27 | type Provider struct {
28 | baseURL *url.URL
29 | URL *url.URL
30 | Ctx *cli.Context
31 | Aliases map[string]interface{}
32 | }
33 |
34 | // GetProvider ...
35 | func GetProvider() (*Provider, error) {
36 | conf, err := alias.GetConfig()
37 | if err != nil {
38 | return nil, err
39 | }
40 |
41 | return &Provider{
42 | Aliases: conf.Firebase["alias"].(map[string]interface{}),
43 | }, nil
44 | }
45 |
46 | // Init ...
47 | func (p *Provider) Init(c *cli.Context) error {
48 | p.Ctx = c
49 | return nil
50 | }
51 |
52 | // GetTargetURL ...
53 | func (p *Provider) GetTargetURL() (string, error) {
54 | const baseURL = "https://console.firebase.google.com/u/0"
55 | var err error
56 | if p.baseURL, err = url.Parse(baseURL); err != nil {
57 | return "", err
58 | }
59 | p.addProductPath(p.Ctx.Command.Name)
60 | return p.URL.String(), nil
61 | }
62 |
63 | func (p *Provider) addProductPath(product string) {
64 | p.URL = p.baseURL
65 | if product == "" {
66 | return
67 | }
68 |
69 | var project string
70 | if project = p.GetCtxString("project"); project != "" {
71 | p.join(fmt.Sprintf("project/%s", project))
72 | switch product {
73 | case "retention":
74 | p.join("cohort")
75 | case "ab":
76 | p.join("experiments/list")
77 | case "notification":
78 | // This is "Cloud Messaging"
79 | p.join("notification")
80 | case "inappmessaging":
81 | p.join("inappmessaging/onboarding")
82 | case "dynamicLinks":
83 | p.join("durablelinks")
84 | default:
85 | p.join(product)
86 | }
87 |
88 | return
89 | }
90 |
91 | p.join("overview")
92 | return
93 | }
94 |
95 | // GetCtxString ...
96 | func (p *Provider) GetCtxString(str string) string {
97 | key := p.Ctx.String(str)
98 | if key == "" {
99 | return ""
100 | }
101 | value, ok := p.Aliases[key].(string)
102 | if !ok {
103 | return key
104 | }
105 | if value == "" {
106 | return key
107 | }
108 | return value
109 | }
110 |
111 | func (p *Provider) join(additionPath string) {
112 | if p.URL == nil {
113 | p.URL = p.baseURL
114 | }
115 | p.URL.Path = path.Join(p.URL.Path, additionPath)
116 | }
117 |
--------------------------------------------------------------------------------
/providers/github/github.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package github
16 |
17 | import (
18 | "fmt"
19 | "net/url"
20 | "path"
21 |
22 | "github.com/urfave/cli"
23 | )
24 |
25 | // Provider ...
26 | type Provider struct {
27 | baseURL *url.URL
28 | URL *url.URL
29 | Ctx *cli.Context
30 | Aliases map[string]interface{}
31 | }
32 |
33 | // Init ...
34 | func (p *Provider) Init(c *cli.Context) error {
35 | p.Ctx = c
36 | return nil
37 | }
38 |
39 | // GetTargetURL ...
40 | func (p *Provider) GetTargetURL() (string, error) {
41 | const baseURL = "https://github.com"
42 | var err error
43 | if p.baseURL, err = url.Parse(baseURL); err != nil {
44 | return "", err
45 | }
46 |
47 | p.addProductPath(p.Ctx.Command.Name)
48 | return p.URL.String(), nil
49 | }
50 |
51 | func (p *Provider) addProductPath(product string) {
52 | switch product {
53 | case "dashboard":
54 | if org := p.Ctx.String("org"); org != "" {
55 | p.join(fmt.Sprintf("orgs/%s/dashboard", org))
56 | return
57 | }
58 | p.URL = p.baseURL
59 | return
60 | case "trending":
61 | p.join("trending")
62 | if since := p.Ctx.String("since"); since != "" {
63 | param := url.Values{}
64 | param.Add("since", since)
65 | p.URL.RawQuery = param.Encode()
66 | }
67 | if language := p.Ctx.String("language"); language != "" {
68 | p.join(language)
69 | return
70 | }
71 | case "repository":
72 |
73 | users := p.Ctx.String("users")
74 | org := p.Ctx.String("org")
75 | if users != "" && org != "" {
76 | p.URL = p.baseURL
77 | return
78 | }
79 | if users != "" {
80 | p.join(users)
81 | } else {
82 | p.join(org)
83 | }
84 |
85 | if name := p.Ctx.String("name"); name != "" {
86 | if users != "" || org != "" {
87 | p.join(name)
88 | }
89 | return
90 | }
91 | p.URL = p.baseURL
92 | return
93 | default:
94 | p.URL = p.baseURL
95 | }
96 | }
97 |
98 | // GetCtxString ...
99 | func (p *Provider) GetCtxString(str string) string {
100 | key := p.Ctx.String(str)
101 | if key == "" {
102 | return ""
103 | }
104 | value, ok := p.Aliases[key].(string)
105 | if !ok {
106 | return key
107 | }
108 | if value == "" {
109 | return key
110 | }
111 | return value
112 | }
113 |
114 | func (p *Provider) join(additionPath string) {
115 | if p.URL == nil {
116 | p.URL = p.baseURL
117 | }
118 | p.URL.Path = path.Join(p.URL.Path, additionPath)
119 | }
120 |
--------------------------------------------------------------------------------
/providers/azure/azure.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package azure
16 |
17 | import (
18 | "fmt"
19 | "path"
20 |
21 | "github.com/KeisukeYamashita/biko/alias"
22 | "github.com/urfave/cli"
23 | )
24 |
25 | // Provider ...
26 | // TODO(KeisukeYamashita): Use url package for baseURL and URL
27 | type Provider struct {
28 | baseURL string
29 | URL string
30 | Ctx *cli.Context
31 | Aliases map[string]interface{}
32 | }
33 |
34 | // GetProvider ...
35 | func GetProvider() (*Provider, error) {
36 | conf, err := alias.GetConfig()
37 | if err != nil {
38 | return nil, err
39 | }
40 |
41 | return &Provider{
42 | Aliases: conf.Azure["alias"].(map[string]interface{}),
43 | }, nil
44 | }
45 |
46 | // Init ...
47 | func (p *Provider) Init(c *cli.Context) error {
48 | p.Ctx = c
49 | return nil
50 | }
51 |
52 | // GetTargetURL ...
53 | func (p *Provider) GetTargetURL() (string, error) {
54 | p.baseURL = "https://portal.azure.com"
55 | p.addProductPath(p.Ctx.Command.Name)
56 | return p.URL, nil
57 | }
58 |
59 | func (p *Provider) addProductPath(product string) {
60 | p.URL = p.baseURL
61 | if product == "" {
62 | p.join("#home")
63 | return
64 | }
65 |
66 | var productType, path string
67 | suffix := "Blade"
68 | switch product {
69 | case "vm":
70 | productType = "Compute"
71 | path = "VirtualMachines"
72 | case "appservices":
73 | productType = "Web"
74 | path = "sites"
75 | case "funcion":
76 | productType = "Web"
77 | path = "sites/king/functionapp"
78 | case "sql":
79 | productType = "Sql"
80 | path = "services/databases"
81 | case "cosmos":
82 | productType = "DocumentDB"
83 | path = "databaseAccounts"
84 | suffix = ""
85 | case "storage":
86 | productType = "Storage"
87 | path = "StorageAccounts"
88 | default:
89 | return
90 | }
91 | p.join(fmt.Sprintf("#blade/HubsExtension/BrowseResource%s/resourceType/Microsoft.%s%%2F%s", suffix, productType, path))
92 | }
93 |
94 | // GetCtxString ...
95 | func (p *Provider) GetCtxString(str string) string {
96 | key := p.Ctx.String(str)
97 | if key == "" {
98 | return ""
99 | }
100 | value, ok := p.Aliases[key].(string)
101 | if !ok {
102 | return key
103 | }
104 | if value == "" {
105 | return key
106 | }
107 | return value
108 | }
109 |
110 | func (p *Provider) join(additionPath string) {
111 | if p.URL == "" {
112 | p.URL = p.baseURL
113 | }
114 | p.URL = path.Join(p.URL, additionPath)
115 | }
116 |
--------------------------------------------------------------------------------
/providers/datadog/datadog.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package datadog
16 |
17 | import (
18 | "net/url"
19 | "path"
20 |
21 | "github.com/KeisukeYamashita/biko/alias"
22 | "github.com/urfave/cli"
23 | )
24 |
25 | // Provider ...
26 | type Provider struct {
27 | baseURL *url.URL
28 | URL *url.URL
29 | Product string
30 | Ctx *cli.Context
31 | Aliases map[string]interface{}
32 | }
33 |
34 | // GetProvider ...
35 | func GetProvider() (*Provider, error) {
36 | conf, err := alias.GetConfig()
37 | if err != nil {
38 | return nil, err
39 | }
40 |
41 | return &Provider{
42 | Aliases: conf.Datadog["alias"].(map[string]interface{}),
43 | }, nil
44 | }
45 |
46 | // Init ...
47 | func (p *Provider) Init(c *cli.Context) error {
48 | p.Ctx = c
49 | return nil
50 | }
51 |
52 | // GetTargetURL ...
53 | func (p *Provider) GetTargetURL() (string, error) {
54 | const baseURL = "https://app.datadoghq.com"
55 | var err error
56 | if p.baseURL, err = url.Parse(baseURL); err != nil {
57 | return "", err
58 | }
59 |
60 | p.addProductPath(p.Ctx.Command.Name)
61 | return p.URL.String(), nil
62 | }
63 | func (p *Provider) addProductPath(product string) {
64 | switch product {
65 | case "watchdogs":
66 | p.join(product)
67 | case "events":
68 | p.join("events/stream")
69 | case "dashboard":
70 | p.join(product)
71 | case "infrastructure":
72 | p.join(product)
73 | case "monitors":
74 | p.join(product)
75 | case "metrics":
76 | p.join(product)
77 | case "integrations":
78 | p.join("account/settings")
79 | case "apm":
80 | p.join(product)
81 | case "notebook":
82 | p.join(product)
83 | case "logs":
84 | p.join(product)
85 | var view string
86 | if view = p.GetCtxString("view"); view != "" {
87 | param := url.Values{}
88 | param.Add("saved_view", view)
89 | p.URL.RawQuery = param.Encode()
90 | }
91 | case "synthetics":
92 | p.join(product)
93 | default:
94 | p.join("apm/home")
95 | }
96 | return
97 | }
98 |
99 | func (p *Provider) join(additionPath string) {
100 | if p.URL == nil {
101 | p.URL = p.baseURL
102 | }
103 | p.URL.Path = path.Join(p.URL.Path, additionPath)
104 | }
105 |
106 | // GetCtxString ...
107 | func (p *Provider) GetCtxString(str string) string {
108 | key := p.Ctx.String(str)
109 | if key == "" {
110 | return ""
111 | }
112 | value, ok := p.Aliases[key].(string)
113 | if !ok {
114 | return key
115 | }
116 | if value == "" {
117 | return key
118 | }
119 | return value
120 | }
121 |
--------------------------------------------------------------------------------
/cli/github.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package cli
16 |
17 | import (
18 | "github.com/KeisukeYamashita/biko/browser"
19 | gh "github.com/KeisukeYamashita/biko/providers/github"
20 | "github.com/urfave/cli"
21 | )
22 |
23 | func newGithubCmd() cli.Command {
24 | return cli.Command{
25 | Name: "github",
26 | Aliases: []string{"gh"},
27 | Usage: "Open Github resource",
28 | Category: categoryVersioning,
29 | Flags: []cli.Flag{
30 | cli.StringFlag{
31 | Name: "project",
32 | Usage: "Specify the project to open",
33 | },
34 | },
35 | Action: func(c *cli.Context) error {
36 | github := &gh.Provider{}
37 | return browser.Open(c, github)
38 | },
39 | Subcommands: []cli.Command{
40 | newGithubDashboardCmd(),
41 | newGithubTrendingCmd(),
42 | newGithubRepositoryCmd(),
43 | },
44 | }
45 | }
46 |
47 | func newGithubDashboardCmd() cli.Command {
48 | return cli.Command{
49 | Name: "dashboard",
50 | Aliases: []string{"db"},
51 | Usage: "Open a dashboard page",
52 | Flags: []cli.Flag{
53 | cli.StringFlag{
54 | Name: "org",
55 | Usage: "Organization to open",
56 | },
57 | },
58 | Action: func(c *cli.Context) error {
59 |
60 | github := &gh.Provider{}
61 | return browser.Open(c, github)
62 | },
63 | }
64 |
65 | }
66 |
67 | func newGithubTrendingCmd() cli.Command {
68 | return cli.Command{
69 | Name: "trending",
70 | Aliases: []string{"t"},
71 | Usage: "Open the trending page",
72 | Flags: []cli.Flag{
73 | cli.StringFlag{
74 | Name: "language, l",
75 | Usage: "filter trending with language",
76 | },
77 | cli.StringFlag{
78 | Name: "since, s",
79 | Usage: "filter trending with date range(daily, weekly, monthly)",
80 | },
81 | },
82 | Action: func(c *cli.Context) error {
83 |
84 | github := &gh.Provider{}
85 | return browser.Open(c, github)
86 | },
87 | }
88 |
89 | }
90 |
91 | func newGithubRepositoryCmd() cli.Command {
92 | return cli.Command{
93 | Name: "repository",
94 | Aliases: []string{"r"},
95 | Usage: "Open the repository page",
96 | Flags: []cli.Flag{
97 | cli.StringFlag{
98 | Name: "org",
99 | Usage: "Organization to open",
100 | },
101 | cli.StringFlag{
102 | Name: "users, u",
103 | Usage: "User page to open",
104 | },
105 | cli.StringFlag{
106 | Name: "name, n",
107 | Usage: "Name of repository that depend on Organization",
108 | },
109 | },
110 | Action: func(c *cli.Context) error {
111 |
112 | github := &gh.Provider{}
113 | return browser.Open(c, github)
114 | },
115 | }
116 |
117 | }
118 |
--------------------------------------------------------------------------------
/cli/circleci.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package cli
16 |
17 | import (
18 | "fmt"
19 |
20 | "github.com/KeisukeYamashita/biko/browser"
21 | cc "github.com/KeisukeYamashita/biko/providers/circleci"
22 | "github.com/urfave/cli"
23 | )
24 |
25 | func newCircleCICmd() cli.Command {
26 | return cli.Command{
27 | Name: "circleci",
28 | Aliases: []string{"cc"},
29 | Usage: "Open CircleCI resource",
30 | Category: categoryContinousIntegration,
31 | Flags: []cli.Flag{
32 | cli.StringFlag{
33 | Name: "org",
34 | EnvVar: "BIKO_CIRCLECI",
35 | Usage: "Specify CircleCI Organization",
36 | },
37 | },
38 | Action: func(c *cli.Context) error {
39 | var org string
40 | if org = c.String("org"); org == "" {
41 | return fmt.Errorf("Org for circleci not configured pass --org or set BIKO_CIRCLECI")
42 | }
43 | cc := &cc.Provider{
44 | Org: org,
45 | }
46 | return browser.Open(c, cc)
47 | },
48 | Subcommands: []cli.Command{
49 | newCircleCIJobsCmd(),
50 | newCircleCIWorkflowsCmd(),
51 | },
52 | }
53 | }
54 |
55 | func newCircleCIJobsCmd() cli.Command {
56 | return cli.Command{
57 | Name: "jobs",
58 | Aliases: []string{"j"},
59 | Usage: "Open jobs page",
60 | Flags: []cli.Flag{
61 | cli.StringFlag{
62 | Name: "project, p",
63 | Usage: "Specify the project to open",
64 | },
65 | cli.StringFlag{
66 | Name: "org",
67 | EnvVar: "BIKO_CIRCLECI",
68 | Usage: "Specify CircleCI Organization",
69 | },
70 | },
71 | Action: func(c *cli.Context) error {
72 | var org string
73 | if org = c.String("org"); org == "" {
74 | return fmt.Errorf("Org for circleci not configured pass --org or set BIKO_CIRCLECI")
75 | }
76 | cc, err := cc.GetProvider(org)
77 | if err != nil {
78 | return err
79 | }
80 | return browser.Open(c, cc)
81 | },
82 | }
83 | }
84 |
85 | func newCircleCIWorkflowsCmd() cli.Command {
86 | return cli.Command{
87 | Name: "workflows",
88 | Aliases: []string{"wf"},
89 | Usage: "Open workflows page",
90 | Flags: []cli.Flag{
91 | cli.StringFlag{
92 | Name: "project, p",
93 | Usage: "Specify the project to open",
94 | },
95 | cli.StringFlag{
96 | Name: "org",
97 | EnvVar: "BIKO_CIRCLECI",
98 | Usage: "Specify CircleCI Organization",
99 | },
100 | },
101 | Action: func(c *cli.Context) error {
102 | var org string
103 | if org = c.String("org"); org == "" {
104 | return fmt.Errorf("Org for circleci not configured pass --org or set BIKO_CIRCLECI")
105 | }
106 | cc, err := cc.GetProvider(org)
107 | if err != nil {
108 | return err
109 | }
110 | return browser.Open(c, cc)
111 | },
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/cli/pagerduty.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package cli
16 |
17 | import (
18 | "fmt"
19 |
20 | "github.com/KeisukeYamashita/biko/browser"
21 | pd "github.com/KeisukeYamashita/biko/providers/pagerduty"
22 | "github.com/urfave/cli"
23 | )
24 |
25 | func newPagerDutyCmd() cli.Command {
26 | return cli.Command{
27 | Name: "pagerduty",
28 | Aliases: []string{"pd"},
29 | Usage: "Open PagerDuty resource",
30 | Category: categoryIncidentManagement,
31 | Flags: []cli.Flag{
32 | cli.StringFlag{
33 | Name: "project",
34 | Usage: "Specify the project to open",
35 | },
36 | cli.StringFlag{
37 | Name: "org",
38 | EnvVar: "BIKO_PAGERDUTY",
39 | Usage: "Specify Pagerduty Organization",
40 | },
41 | },
42 | Action: func(c *cli.Context) error {
43 | var org string
44 | if org = c.String("org"); org == "" {
45 | return fmt.Errorf("Org for pagerduty not configured pass --org or set BIKO_PAGERDUTY")
46 | }
47 | pd := &pd.Provider{
48 | Org: org,
49 | }
50 | return browser.Open(c, pd)
51 | },
52 | Subcommands: []cli.Command{
53 | newPagerDudyIncidentCmd(),
54 | newPagerDudyAlertCmd(),
55 | newPagerDudySchedulesCmd(),
56 | },
57 | }
58 | }
59 |
60 | func newPagerDudyIncidentCmd() cli.Command {
61 | return cli.Command{
62 | Name: "incident",
63 | Aliases: []string{"i"},
64 | Usage: "Open incident page",
65 | Flags: []cli.Flag{
66 | cli.StringFlag{
67 | Name: "org",
68 | EnvVar: "BIKO_PAGERDUTY",
69 | Usage: "Specify Pagerduty Organization",
70 | },
71 | },
72 | Action: func(c *cli.Context) error {
73 | var org string
74 | if org = c.String("org"); org == "" {
75 | return fmt.Errorf("Org for pagerduty not configured pass --org or set BIKO_PAGERDUTY")
76 | }
77 | pd := &pd.Provider{
78 | Org: org,
79 | }
80 | return browser.Open(c, pd)
81 | },
82 | }
83 |
84 | }
85 |
86 | func newPagerDudyAlertCmd() cli.Command {
87 | return cli.Command{
88 | Name: "alert",
89 | Aliases: []string{"a"},
90 | Usage: "Open alert page",
91 | Flags: []cli.Flag{},
92 | Action: func(c *cli.Context) error {
93 | var org string
94 | if org = c.String("org"); org == "" {
95 | return fmt.Errorf("Org for pagerduty not configured pass --org or set BIKO_PAGERDUTY")
96 | }
97 | pd := &pd.Provider{
98 | Org: org,
99 | }
100 | return browser.Open(c, pd)
101 | },
102 | }
103 | }
104 |
105 | func newPagerDudySchedulesCmd() cli.Command {
106 | return cli.Command{
107 | Name: "schedules",
108 | Aliases: []string{"s"},
109 | Usage: "Open schedules page",
110 | Flags: []cli.Flag{
111 | cli.StringFlag{
112 | Name: "org",
113 | EnvVar: "BIKO_PAGERDUTY",
114 | Usage: "Specify Pagerduty Organization",
115 | },
116 | },
117 | Action: func(c *cli.Context) error {
118 | var org string
119 | if org = c.String("org"); org == "" {
120 | return fmt.Errorf("Org for pagerduty not configured pass --org or set BIKO_PAGERDUTY")
121 | }
122 | pd := &pd.Provider{
123 | Org: org,
124 | }
125 | return browser.Open(c, pd)
126 | },
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/go.sum:
--------------------------------------------------------------------------------
1 | github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
2 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
3 | github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
4 | github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
5 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
6 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
7 | github.com/go-ini/ini v1.62.0 h1:7VJT/ZXjzqSrvtraFp4ONq80hTcRQth1c9ZnQ3uNQvU=
8 | github.com/go-ini/ini v1.62.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
9 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
10 | github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
11 | github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
12 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
13 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
14 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
15 | github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
16 | github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
17 | github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
18 | github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
19 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
20 | github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
21 | github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
22 | github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
23 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
24 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
25 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
26 | github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU=
27 | github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
28 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
29 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
30 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
31 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
32 | golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
33 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
34 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
35 | gopkg.in/ini.v1 v1.48.0 h1:URjZc+8ugRY5mL5uUeQH/a63JcHwdX9xZaWvmNWD7z8=
36 | gopkg.in/ini.v1 v1.48.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
37 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
38 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
39 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
40 |
--------------------------------------------------------------------------------
/cli/azure.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package cli
16 |
17 | import (
18 | "github.com/KeisukeYamashita/biko/browser"
19 | az "github.com/KeisukeYamashita/biko/providers/azure"
20 | "github.com/urfave/cli"
21 | )
22 |
23 | const (
24 | categoryAZuComputing = "Computing"
25 | )
26 |
27 | func newAzureCmd() cli.Command {
28 | return cli.Command{
29 | Name: "azure",
30 | Aliases: []string{"az"},
31 | Usage: "Open Microsoft Azure resource",
32 | Category: categoryCloudProvider,
33 | Flags: []cli.Flag{},
34 | Action: func(c *cli.Context) error {
35 | aws, err := az.GetProvider()
36 | if err != nil {
37 | return err
38 | }
39 | return browser.Open(c, aws)
40 | },
41 | Subcommands: []cli.Command{
42 | newAzureVMCmd(),
43 | newAzureAppServicesCmd(),
44 | newAzureFunctionAppCmd(),
45 | newAzureSQLDatabaseCmd(),
46 | newAzureCosmosDBCmd(),
47 | newAzureStorageAccountsCmd(),
48 | },
49 | }
50 | }
51 |
52 | func newAzureVMCmd() cli.Command {
53 | return cli.Command{
54 | Name: "vm",
55 | Usage: "Open VM",
56 | Flags: []cli.Flag{},
57 | Action: func(c *cli.Context) error {
58 | aws, err := az.GetProvider()
59 | if err != nil {
60 | return err
61 | }
62 | return browser.Open(c, aws)
63 | },
64 | }
65 | }
66 |
67 | func newAzureAppServicesCmd() cli.Command {
68 | return cli.Command{
69 | Name: "appservices",
70 | Aliases: []string{"as", "sites"},
71 | Usage: "Open App Services",
72 | Flags: []cli.Flag{},
73 | Action: func(c *cli.Context) error {
74 | aws, err := az.GetProvider()
75 | if err != nil {
76 | return err
77 | }
78 | return browser.Open(c, aws)
79 | },
80 | }
81 | }
82 |
83 | func newAzureFunctionAppCmd() cli.Command {
84 | return cli.Command{
85 | Name: "function",
86 | Aliases: []string{"f"},
87 | Usage: "Open Function App",
88 | Flags: []cli.Flag{},
89 | Action: func(c *cli.Context) error {
90 | aws, err := az.GetProvider()
91 | if err != nil {
92 | return err
93 | }
94 | return browser.Open(c, aws)
95 | },
96 | }
97 | }
98 |
99 | func newAzureSQLDatabaseCmd() cli.Command {
100 | return cli.Command{
101 | Name: "sql",
102 | Usage: "Open SQL Database",
103 | Flags: []cli.Flag{},
104 | Action: func(c *cli.Context) error {
105 | aws, err := az.GetProvider()
106 | if err != nil {
107 | return err
108 | }
109 | return browser.Open(c, aws)
110 | },
111 | }
112 | }
113 |
114 | func newAzureCosmosDBCmd() cli.Command {
115 | return cli.Command{
116 | Name: "cosmos",
117 | Usage: "Open Cosmos Database",
118 | Flags: []cli.Flag{},
119 | Action: func(c *cli.Context) error {
120 | aws, err := az.GetProvider()
121 | if err != nil {
122 | return err
123 | }
124 | return browser.Open(c, aws)
125 | },
126 | }
127 | }
128 |
129 | func newAzureStorageAccountsCmd() cli.Command {
130 | return cli.Command{
131 | Name: "storage",
132 | Usage: "Open Storage Accounts",
133 | Flags: []cli.Flag{},
134 | Action: func(c *cli.Context) error {
135 | aws, err := az.GetProvider()
136 | if err != nil {
137 | return err
138 | }
139 | return browser.Open(c, aws)
140 | },
141 | }
142 | }
143 |
--------------------------------------------------------------------------------
/providers/googleworkspace/googleworkspace.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package googleworkspace
16 |
17 | import (
18 | "net/url"
19 | "path"
20 |
21 | "github.com/KeisukeYamashita/biko/alias"
22 | "github.com/urfave/cli"
23 | )
24 |
25 | const (
26 | drive = "drive"
27 | document = "document"
28 | spreadsheets = "spreadsheets"
29 | presentation = "presentation"
30 | forms = "forms"
31 | )
32 |
33 | // Provider ...
34 | type Provider struct {
35 | baseURL *url.URL
36 | URL *url.URL
37 | Ctx *cli.Context
38 | Aliases map[string]interface{}
39 | }
40 |
41 | // GetProvider ...
42 | func GetProvider() (*Provider, error) {
43 | conf, err := alias.GetConfig()
44 | if err != nil {
45 | return nil, err
46 | }
47 |
48 | return &Provider{
49 | Aliases: conf.GoogleWorkspace["alias"].(map[string]interface{}),
50 | }, nil
51 | }
52 |
53 | // Init ...
54 | func (p *Provider) Init(c *cli.Context) error {
55 | p.Ctx = c
56 | return nil
57 | }
58 |
59 | // GetTargetURL ...
60 | func (p *Provider) GetTargetURL() (string, error) {
61 | newFlag := p.GetCtxString("new")
62 | if newFlag == "true" { // HACK: need to fix GetCtxString
63 | return p.getNewCmdURL(), nil
64 | }
65 |
66 | var baseURL string
67 | product := p.Ctx.Command.Name
68 | switch product {
69 | case drive:
70 | baseURL = "https://drive.google.com"
71 | case document, spreadsheets, presentation, forms:
72 | baseURL = "https://docs.google.com/"
73 | }
74 |
75 | var err error
76 | if p.baseURL, err = url.Parse(baseURL); err != nil {
77 | return "", err
78 | }
79 | p.addProductPath(product)
80 | return p.URL.String(), nil
81 | }
82 |
83 | func (p *Provider) addProductPath(product string) {
84 | p.URL = p.baseURL
85 | switch product {
86 | case drive:
87 | p.join(drive)
88 | param := url.Values{}
89 | var query string
90 | if query = p.GetCtxString("query"); query != "" {
91 | p.join("search")
92 | param.Add("q", query)
93 | p.URL.RawQuery = param.Encode()
94 | }
95 | case document:
96 | p.join(document)
97 | param := url.Values{}
98 | var query string
99 | if query = p.GetCtxString("query"); query != "" {
100 | param.Add("q", query)
101 | p.URL.RawQuery = param.Encode()
102 | }
103 | case spreadsheets:
104 | p.join(spreadsheets)
105 | param := url.Values{}
106 | var query string
107 | if query = p.GetCtxString("query"); query != "" {
108 | param.Add("q", query)
109 | p.URL.RawQuery = param.Encode()
110 | }
111 | case presentation:
112 | p.join(presentation)
113 | param := url.Values{}
114 | var query string
115 | if query = p.GetCtxString("query"); query != "" {
116 | param.Add("q", query)
117 | p.URL.RawQuery = param.Encode()
118 | }
119 | case forms:
120 | p.join(forms)
121 | param := url.Values{}
122 | var query string
123 | if query = p.GetCtxString("query"); query != "" {
124 | param.Add("q", query)
125 | p.URL.RawQuery = param.Encode()
126 | }
127 | }
128 | }
129 |
130 | func (p *Provider) join(additionPath string) {
131 | if p.URL == nil {
132 | p.URL = p.baseURL
133 | }
134 | p.URL.Path = path.Join(p.URL.Path, additionPath)
135 | }
136 |
137 | func (p *Provider) getNewCmdURL() string {
138 | product := p.Ctx.Command.Name
139 | switch product {
140 | case document:
141 | return "https://document.new"
142 | case spreadsheets:
143 | return "https://spreadsheets.new"
144 | case presentation:
145 | return "https://presentation.new"
146 | case forms:
147 | return "https://forms.new"
148 | }
149 | return ""
150 | }
151 |
152 | // GetCtxString ...
153 | func (p *Provider) GetCtxString(str string) string {
154 | key := p.Ctx.String(str)
155 | if key == "" {
156 | return ""
157 | }
158 | value, ok := p.Aliases[key].(string)
159 | if !ok {
160 | return key
161 | }
162 | if value == "" {
163 | return key
164 | }
165 | return value
166 | }
167 |
--------------------------------------------------------------------------------
/cli/googleworkspace.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package cli
16 |
17 | import (
18 | "github.com/KeisukeYamashita/biko/browser"
19 | "github.com/KeisukeYamashita/biko/providers/googleworkspace"
20 | "github.com/urfave/cli"
21 | )
22 |
23 | func newGoogleWorkspaceCmd() cli.Command {
24 | return cli.Command{
25 | Name: "googleworkspace",
26 | Aliases: []string{"gw"},
27 | Usage: "Open Google Workspace resource",
28 | Category: categoryWebService,
29 | Flags: []cli.Flag{},
30 | Action: func(c *cli.Context) error {
31 | g, err := googleworkspace.GetProvider()
32 | if err != nil {
33 | return err
34 | }
35 | return browser.Open(c, g)
36 | },
37 | Subcommands: []cli.Command{
38 | newDriveCmd(),
39 | newDocumentCmd(),
40 | newSpreadsheetsCmd(),
41 | newPresentationCmd(),
42 | newFormsCmd(),
43 | },
44 | }
45 | }
46 |
47 | func newDriveCmd() cli.Command {
48 | return cli.Command{
49 | Name: "drive",
50 | Aliases: []string{"dr"},
51 | Usage: "Open Google Drive directory",
52 | Flags: []cli.Flag{
53 | cli.StringFlag{
54 | Name: "query, q",
55 | Usage: "Query to search",
56 | },
57 | },
58 | Action: func(c *cli.Context) error {
59 | g, err := googleworkspace.GetProvider()
60 | if err != nil {
61 | return err
62 | }
63 | return browser.Open(c, g)
64 | },
65 | }
66 |
67 | }
68 |
69 | func newDocumentCmd() cli.Command {
70 | return cli.Command{
71 | Name: "document",
72 | Aliases: []string{"doc"},
73 | Usage: "Open Google Document page",
74 | Flags: []cli.Flag{
75 | cli.StringFlag{
76 | Name: "query, q",
77 | Usage: "Query a page",
78 | },
79 | cli.BoolFlag{
80 | Name: "new, n",
81 | Usage: "Create a new document (this flag prioritize over query flag)",
82 | },
83 | },
84 | Action: func(c *cli.Context) error {
85 | g, err := googleworkspace.GetProvider()
86 | if err != nil {
87 | return err
88 | }
89 | return browser.Open(c, g)
90 | },
91 | }
92 |
93 | }
94 |
95 | func newSpreadsheetsCmd() cli.Command {
96 | return cli.Command{
97 | Name: "spreadsheets",
98 | Aliases: []string{"ss"},
99 | Usage: "Open Google Spreadsheets page",
100 | Flags: []cli.Flag{
101 | cli.StringFlag{
102 | Name: "query, q",
103 | Usage: "Query a page",
104 | },
105 | cli.BoolFlag{
106 | Name: "new, n",
107 | Usage: "Create a new spreadsheet (this flag prioritize over query flag)",
108 | },
109 | },
110 | Action: func(c *cli.Context) error {
111 | g, err := googleworkspace.GetProvider()
112 | if err != nil {
113 | return err
114 | }
115 | return browser.Open(c, g)
116 | },
117 | }
118 |
119 | }
120 |
121 | func newPresentationCmd() cli.Command {
122 | return cli.Command{
123 | Name: "presentation",
124 | Aliases: []string{"pr"},
125 | Usage: "Open Google Slides page",
126 | Flags: []cli.Flag{
127 | cli.StringFlag{
128 | Name: "query, q",
129 | Usage: "Query a page",
130 | },
131 | cli.BoolFlag{
132 | Name: "new, n",
133 | Usage: "Create a new presentation (this flag prioritize over query flag)",
134 | },
135 | },
136 | Action: func(c *cli.Context) error {
137 | g, err := googleworkspace.GetProvider()
138 | if err != nil {
139 | return err
140 | }
141 | return browser.Open(c, g)
142 | },
143 | }
144 |
145 | }
146 |
147 | func newFormsCmd() cli.Command {
148 | return cli.Command{
149 | Name: "forms",
150 | Aliases: []string{"fm"},
151 | Usage: "Open Google Forms page",
152 | Flags: []cli.Flag{
153 | cli.StringFlag{
154 | Name: "query, q",
155 | Usage: "Query a page",
156 | },
157 | cli.BoolFlag{
158 | Name: "new, n",
159 | Usage: "Create a new form (this flag prioritize over query flag)",
160 | },
161 | },
162 | Action: func(c *cli.Context) error {
163 | g, err := googleworkspace.GetProvider()
164 | if err != nil {
165 | return err
166 | }
167 | return browser.Open(c, g)
168 | },
169 | }
170 |
171 | }
172 |
--------------------------------------------------------------------------------
/cli/datadog.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package cli
16 |
17 | import (
18 | "github.com/KeisukeYamashita/biko/browser"
19 | dd "github.com/KeisukeYamashita/biko/providers/datadog"
20 | "github.com/urfave/cli"
21 | )
22 |
23 | func newDatadaogCmd() cli.Command {
24 | return cli.Command{
25 | Name: "datadog",
26 | Aliases: []string{"dd"},
27 | Usage: "Open Datadog resource",
28 | Category: categoryMonitor,
29 | Flags: []cli.Flag{},
30 | Subcommands: []cli.Command{
31 | newDDWatchDogCmd(),
32 | newDDEventCmd(),
33 | newDDDashboardCmd(),
34 | newDDInfrastructureCmd(),
35 | newDDMonitorsCmd(),
36 | newDDIntegrationsCmd(),
37 | newDDApmCmd(),
38 | newDDNotebookCmd(),
39 | newDDLogsCmd(),
40 | newDDSyntheticsCmd(),
41 | },
42 | }
43 | }
44 |
45 | func newDDWatchDogCmd() cli.Command {
46 | return cli.Command{
47 | Name: "watchdog",
48 | Aliases: []string{"wd"},
49 | Usage: "Open Watchdog page",
50 | Flags: []cli.Flag{},
51 | Action: func(c *cli.Context) error {
52 | dd, err := dd.GetProvider()
53 | if err != nil {
54 | return err
55 | }
56 | return browser.Open(c, dd)
57 | },
58 | }
59 | }
60 |
61 | func newDDEventCmd() cli.Command {
62 | return cli.Command{
63 | Name: "events",
64 | Usage: "Open Events page",
65 | Flags: []cli.Flag{},
66 | Action: func(c *cli.Context) error {
67 | dd, err := dd.GetProvider()
68 | if err != nil {
69 | return err
70 | }
71 | return browser.Open(c, dd)
72 | },
73 | }
74 | }
75 |
76 | func newDDDashboardCmd() cli.Command {
77 | return cli.Command{
78 | Name: "dashboard",
79 | Usage: "Open Dashboard page",
80 | Flags: []cli.Flag{},
81 | Action: func(c *cli.Context) error {
82 | dd, err := dd.GetProvider()
83 | if err != nil {
84 | return err
85 | }
86 | return browser.Open(c, dd)
87 | },
88 | }
89 | }
90 |
91 | func newDDInfrastructureCmd() cli.Command {
92 | return cli.Command{
93 | Name: "infrastructure",
94 | Usage: "Open Infrastructure page",
95 | Flags: []cli.Flag{},
96 | Action: func(c *cli.Context) error {
97 | dd, err := dd.GetProvider()
98 | if err != nil {
99 | return err
100 | }
101 | return browser.Open(c, dd)
102 | },
103 | }
104 | }
105 |
106 | func newDDMonitorsCmd() cli.Command {
107 | return cli.Command{
108 | Name: "monitors",
109 | Usage: "Open Monitors page",
110 | Flags: []cli.Flag{},
111 | Action: func(c *cli.Context) error {
112 | dd, err := dd.GetProvider()
113 | if err != nil {
114 | return err
115 | }
116 | return browser.Open(c, dd)
117 | },
118 | }
119 | }
120 |
121 | func newDDIntegrationsCmd() cli.Command {
122 | return cli.Command{
123 | Name: "integrations",
124 | Usage: "Open Integrations page",
125 | Flags: []cli.Flag{},
126 | Action: func(c *cli.Context) error {
127 | dd, err := dd.GetProvider()
128 | if err != nil {
129 | return err
130 | }
131 | return browser.Open(c, dd)
132 | },
133 | }
134 | }
135 |
136 | func newDDApmCmd() cli.Command {
137 | return cli.Command{
138 | Name: "apm",
139 | Usage: "Open APM page",
140 | Flags: []cli.Flag{},
141 | Action: func(c *cli.Context) error {
142 | dd, err := dd.GetProvider()
143 | if err != nil {
144 | return err
145 | }
146 | return browser.Open(c, dd)
147 | },
148 | }
149 | }
150 |
151 | func newDDNotebookCmd() cli.Command {
152 | return cli.Command{
153 | Name: "notebook",
154 | Usage: "Open Notebook page",
155 | Flags: []cli.Flag{},
156 | Action: func(c *cli.Context) error {
157 | dd, err := dd.GetProvider()
158 | if err != nil {
159 | return err
160 | }
161 | return browser.Open(c, dd)
162 | },
163 | }
164 | }
165 |
166 | func newDDLogsCmd() cli.Command {
167 | return cli.Command{
168 | Name: "logs",
169 | Usage: "Open Logs page",
170 | Flags: []cli.Flag{
171 | cli.StringFlag{
172 | Name: "view, v",
173 | Usage: "Specify the saved view to open",
174 | },
175 | },
176 | Action: func(c *cli.Context) error {
177 | dd, err := dd.GetProvider()
178 | if err != nil {
179 | return err
180 | }
181 | return browser.Open(c, dd)
182 | },
183 | }
184 | }
185 |
186 | func newDDSyntheticsCmd() cli.Command {
187 | return cli.Command{
188 | Name: "synthetics",
189 | Usage: "Open Synthetics page",
190 | Flags: []cli.Flag{},
191 | Action: func(c *cli.Context) error {
192 | dd, err := dd.GetProvider()
193 | if err != nil {
194 | return err
195 | }
196 | return browser.Open(c, dd)
197 | },
198 | }
199 | }
200 |
--------------------------------------------------------------------------------
/providers/gcp/gcp.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package gcp
16 |
17 | import (
18 | "fmt"
19 | "net/url"
20 | "os"
21 | "path"
22 | "strconv"
23 | "strings"
24 |
25 | "github.com/KeisukeYamashita/biko/alias"
26 | "github.com/go-ini/ini"
27 | "github.com/urfave/cli"
28 | )
29 |
30 | const (
31 | baseURL = "https://console.cloud.google.com"
32 | )
33 |
34 | var (
35 | defaultGoogleSDKConfigPath = os.Getenv("HOME") + "/.config/gcloud/configurations/config_default"
36 | )
37 |
38 | // Provider ...
39 | type Provider struct {
40 | baseURL *url.URL
41 | URL *url.URL
42 | SDKConfig *SDKConfig
43 | Product string
44 | Ctx *cli.Context
45 | Aliases map[string]interface{}
46 | }
47 |
48 | // SDKConfig ...
49 | type SDKConfig struct {
50 | Core *Core
51 | Compute *Compute
52 | Cluster *Container
53 | }
54 |
55 | // Core ...
56 | type Core struct {
57 | Account string
58 | Project string
59 | }
60 |
61 | // Compute ...
62 | type Compute struct {
63 | Zone string
64 | Region string
65 | }
66 |
67 | // Container ...
68 | type Container struct {
69 | Cluster string
70 | }
71 |
72 | // GetProvider ...
73 | func GetProvider() (*Provider, error) {
74 | conf, err := alias.GetConfig()
75 | if err != nil {
76 | return nil, err
77 | }
78 |
79 | return &Provider{
80 | Aliases: conf.GCP["alias"].(map[string]interface{}),
81 | }, nil
82 | }
83 |
84 | // Init ...
85 | func (p *Provider) Init(c *cli.Context) error {
86 | var err error
87 | if p.SDKConfig, err = getSDKConfig(); err != nil {
88 | return err
89 | }
90 |
91 | if c.String("project") != "" {
92 | p.SDKConfig.Core.Project = c.String("project")
93 | }
94 |
95 | p.Ctx = c
96 | return nil
97 | }
98 |
99 | // GetTargetURL ...
100 | func (p *Provider) GetTargetURL() (string, error) {
101 | var err error
102 | if p.baseURL, err = url.Parse(baseURL); err != nil {
103 | return "", err
104 | }
105 |
106 | p.addProductPath(p.Ctx.Command.Name)
107 | p.addProjectParam()
108 | return p.URL.String(), nil
109 | }
110 |
111 | func getSDKConfig() (*SDKConfig, error) {
112 | cfg, err := ini.Load(defaultGoogleSDKConfigPath)
113 | if err != nil {
114 | return nil, err
115 | }
116 |
117 | conf := &SDKConfig{
118 | &Core{
119 | Account: cfg.Section("core").Key("account").MustString("xxx@email.com"),
120 | Project: cfg.Section("core").Key("project").MustString("xxx"),
121 | },
122 | &Compute{
123 | Zone: cfg.Section("compute").Key("zone").MustString("xxx"),
124 | Region: cfg.Section("compute").Key("region").MustString("xxx"),
125 | },
126 | &Container{
127 | Cluster: cfg.Section("container").Key("cluster").MustString("xxx"),
128 | },
129 | }
130 |
131 | return conf, nil
132 | }
133 |
134 | func (p *Provider) addProductPath(product string) {
135 | switch product {
136 | case "appengine":
137 | p.join(product)
138 | case "bigquery":
139 | p.join(product)
140 | var db, table string
141 | if db = p.GetCtxString("database"); db != "" {
142 | q := p.URL.Query()
143 | q.Add("d", db)
144 | if table = p.GetCtxString("table"); table != "" {
145 | q.Add("t", table)
146 | }
147 | p.URL.RawQuery = q.Encode()
148 | }
149 | case "kubernetes":
150 | p.join(product)
151 | var region, name, namespaces string
152 | if region = p.GetCtxString("region"); region != "" {
153 | p.join(fmt.Sprintf("details/%s", region))
154 | if name = p.GetCtxString("name"); name != "" {
155 | p.join(name)
156 | }
157 | } else if namespaces = p.GetCtxString("namespaces"); namespaces != "" {
158 | p.join("workload")
159 | p.addGKEPageStateParam(namespaces)
160 | }
161 | case "secret-manager":
162 | p.join(fmt.Sprintf("security/%s", product))
163 | var secret string
164 | if secret = p.GetCtxString("secret"); secret != "" {
165 | p.join(fmt.Sprintf("secret/%s", secret))
166 | }
167 | case "spanner":
168 | p.join(product)
169 | var instance, db, scheme string
170 | if instance = p.GetCtxString("instance"); instance != "" {
171 | p.join(fmt.Sprintf("instances/%s", instance))
172 | if db = p.GetCtxString("database"); db != "" {
173 | p.join(fmt.Sprintf("databases/%s", db))
174 | if scheme = p.GetCtxString("table"); scheme != "" {
175 | p.join(fmt.Sprintf("schema/%s", scheme))
176 | }
177 | }
178 | }
179 | case "gcr":
180 | p.join(product)
181 | var name string
182 | p.join(fmt.Sprintf("images/%s/", p.SDKConfig.Core.Project))
183 | if name = p.GetCtxString("name"); name != "" {
184 | p.join(fmt.Sprintf("GLOBAL/%s", name))
185 | }
186 | case "run", "functions":
187 | p.join(product)
188 | var region, name string
189 | if region = p.GetCtxString("region"); region != "" {
190 | p.join(fmt.Sprintf("details/%s", region))
191 |
192 | if name = p.GetCtxString("name"); name != "" {
193 | p.join(name)
194 | }
195 | }
196 |
197 | switch product {
198 | case "run":
199 | case "functions":
200 | }
201 | case "logs":
202 | p.join(product)
203 | case "iam":
204 | p.join("iam-admin")
205 | case "sql":
206 | p.join(product)
207 | case "pubsub":
208 | p.join("cloudpubsub")
209 | case "storage":
210 | p.join(fmt.Sprintf("%s/browser", product))
211 | var bucket string
212 | if bucket = p.GetCtxString("bucket"); bucket != "" {
213 | p.join(bucket)
214 | }
215 | case "dataflow":
216 | p.join(product)
217 | case "kms":
218 | p.join("security/kms")
219 | default:
220 | p.join("home/dashboard")
221 | }
222 |
223 | return
224 | }
225 |
226 | func (p *Provider) addProjectParam() {
227 | q := p.URL.Query()
228 | q.Add("project", p.SDKConfig.Core.Project)
229 | p.URL.RawQuery = q.Encode()
230 | return
231 | }
232 |
233 | func (p *Provider) addGKEPageStateParam(namespaces string) {
234 | q := p.URL.Query()
235 | q.Add("pageState", constructPageStateParam(namespaces))
236 | p.URL.RawQuery = q.Encode()
237 | return
238 | }
239 |
240 | func constructPageStateParam(rawNamespaces string) string {
241 | nss := strings.Split(rawNamespaces, ",")
242 | quotedNamespaces := make([]string, 0, len(nss))
243 | for _, s := range nss {
244 | quotedNamespaces = append(quotedNamespaces, strconv.Quote(s))
245 | }
246 | return fmt.Sprintf("(\"savedViews\":(\"n\":[%s]))", strings.Join(quotedNamespaces, ","))
247 | }
248 |
249 | // GetCtxString ...
250 | func (p *Provider) GetCtxString(str string) string {
251 | key := p.Ctx.String(str)
252 | if key == "" {
253 | return ""
254 | }
255 | value, ok := p.Aliases[key].(string)
256 | if !ok {
257 | return key
258 | }
259 | if value == "" {
260 | return key
261 | }
262 | return value
263 | }
264 |
265 | func (p *Provider) join(additionPath string) {
266 | if p.URL == nil {
267 | p.URL = p.baseURL
268 | }
269 | p.URL.Path = path.Join(p.URL.Path, additionPath)
270 | }
271 |
--------------------------------------------------------------------------------
/cli/jira.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package cli
16 |
17 | import (
18 | "fmt"
19 | "net/url"
20 |
21 | "github.com/KeisukeYamashita/biko/browser"
22 | jr "github.com/KeisukeYamashita/biko/providers/jira"
23 | "github.com/urfave/cli"
24 | )
25 |
26 | func newJIRACmd() cli.Command {
27 | return cli.Command{
28 | Name: "jira",
29 | Aliases: []string{"jr"},
30 | Usage: "Open JIRA resource",
31 | Category: categoryCloudProvider,
32 | Flags: []cli.Flag{
33 | cli.StringFlag{
34 | Name: "org",
35 | EnvVar: "BIKO_JIRA",
36 | Usage: "Specify JIRA Organization",
37 | },
38 | cli.StringFlag{
39 | Name: "base",
40 | EnvVar: "BIKO_JIRA_BASE",
41 | Usage: "Specify JIRA Base URL (for self-managed plan)",
42 | },
43 | },
44 | Action: func(c *cli.Context) error {
45 | baseURL, err := getBaseURL(c)
46 | if err != nil {
47 | return err
48 | }
49 | jr := &jr.Provider{}
50 | if jr.BaseURL, err = url.Parse(baseURL); err != nil {
51 | return err
52 | }
53 | return browser.Open(c, jr)
54 | },
55 | Subcommands: []cli.Command{
56 | newJIRADashboardCmd(),
57 | newJIRAProjectsCmd(),
58 | newJIRAPeopleCmd(),
59 | newJIRAIssuesCmd(),
60 | newJIRABacklogCmd(),
61 | newJIRAReportsCmd(),
62 | },
63 | }
64 | }
65 |
66 | func newJIRADashboardCmd() cli.Command {
67 | return cli.Command{
68 | Name: "dashboard",
69 | Aliases: []string{"db"},
70 | Usage: "Open dashboard page",
71 | Flags: []cli.Flag{
72 | cli.StringFlag{
73 | Name: "org",
74 | EnvVar: "BIKO_JIRA",
75 | Usage: "Specify JIRA Organization",
76 | },
77 | cli.StringFlag{
78 | Name: "base",
79 | EnvVar: "BIKO_JIRA_BASE",
80 | Usage: "Specify JIRA Base URL (for self-managed plan)",
81 | },
82 | },
83 | Action: func(c *cli.Context) error {
84 | baseURL, err := getBaseURL(c)
85 | if err != nil {
86 | return err
87 | }
88 | jr := &jr.Provider{}
89 | if jr.BaseURL, err = url.Parse(baseURL); err != nil {
90 | return err
91 | }
92 | return browser.Open(c, jr)
93 | },
94 | }
95 | }
96 |
97 | func newJIRAProjectsCmd() cli.Command {
98 | return cli.Command{
99 | Name: "projects",
100 | Aliases: []string{"ps"},
101 | Usage: "Open projects page",
102 | Flags: []cli.Flag{
103 | cli.StringFlag{
104 | Name: "org",
105 | EnvVar: "BIKO_JIRA",
106 | Usage: "Specify JIRA Organization",
107 | },
108 | cli.StringFlag{
109 | Name: "base",
110 | EnvVar: "BIKO_JIRA_BASE",
111 | Usage: "Specify JIRA Base URL (for self-managed plan)",
112 | },
113 | },
114 | Action: func(c *cli.Context) error {
115 | baseURL, err := getBaseURL(c)
116 | if err != nil {
117 | return err
118 | }
119 | jr := &jr.Provider{}
120 | if jr.BaseURL, err = url.Parse(baseURL); err != nil {
121 | return err
122 | }
123 | return browser.Open(c, jr)
124 | },
125 | }
126 | }
127 |
128 | func newJIRAPeopleCmd() cli.Command {
129 | return cli.Command{
130 | Name: "people",
131 | Aliases: []string{"pp"},
132 | Usage: "Open people page",
133 | Flags: []cli.Flag{
134 | cli.StringFlag{
135 | Name: "org",
136 | EnvVar: "BIKO_JIRA",
137 | Usage: "Specify JIRA Organization",
138 | },
139 | cli.StringFlag{
140 | Name: "base",
141 | EnvVar: "BIKO_JIRA_BASE",
142 | Usage: "Specify JIRA Base URL (for self-managed plan)",
143 | },
144 | },
145 | Action: func(c *cli.Context) error {
146 | baseURL, err := getBaseURL(c)
147 | if err != nil {
148 | return err
149 | }
150 | jr := &jr.Provider{}
151 | if jr.BaseURL, err = url.Parse(baseURL); err != nil {
152 | return err
153 | }
154 | return browser.Open(c, jr)
155 | },
156 | }
157 | }
158 |
159 | func newJIRAIssuesCmd() cli.Command {
160 | return cli.Command{
161 | Name: "issues",
162 | Aliases: []string{"is"},
163 | Usage: "Open issues page",
164 | Flags: []cli.Flag{
165 | cli.StringFlag{
166 | Name: "org",
167 | EnvVar: "BIKO_JIRA",
168 | Usage: "Specify JIRA Organization",
169 | },
170 | cli.StringFlag{
171 | Name: "base",
172 | EnvVar: "BIKO_JIRA_BASE",
173 | Usage: "Specify JIRA Base URL (for self-managed plan)",
174 | },
175 | },
176 | Action: func(c *cli.Context) error {
177 | baseURL, err := getBaseURL(c)
178 | if err != nil {
179 | return err
180 | }
181 | jr := &jr.Provider{}
182 | if jr.BaseURL, err = url.Parse(baseURL); err != nil {
183 | return err
184 | }
185 | return browser.Open(c, jr)
186 | },
187 | }
188 | }
189 |
190 | func newJIRABacklogCmd() cli.Command {
191 | return cli.Command{
192 | Name: "backlog",
193 | Aliases: []string{"bl"},
194 | Usage: "Open backlog page",
195 | Flags: []cli.Flag{
196 | cli.StringFlag{
197 | Name: "project, p",
198 | EnvVar: "BIKO_JIRA_PROJECT",
199 | Usage: "Specify the project to open",
200 | },
201 | cli.StringFlag{
202 | Name: "org",
203 | EnvVar: "BIKO_JIRA",
204 | Usage: "Specify JIRA Organization",
205 | },
206 | cli.StringFlag{
207 | Name: "base",
208 | EnvVar: "BIKO_JIRA_BASE",
209 | Usage: "Specify JIRA Base URL (for self-managed plan)",
210 | },
211 | },
212 | Action: func(c *cli.Context) error {
213 | baseURL, err := getBaseURL(c)
214 | if err != nil {
215 | return err
216 | }
217 | jr := &jr.Provider{}
218 | if jr.BaseURL, err = url.Parse(baseURL); err != nil {
219 | return err
220 | }
221 | return browser.Open(c, jr)
222 | },
223 | }
224 | }
225 |
226 | func newJIRAReportsCmd() cli.Command {
227 | return cli.Command{
228 | Name: "reports",
229 | Aliases: []string{"rp"},
230 | Usage: "Open reports page",
231 | Flags: []cli.Flag{
232 | cli.StringFlag{
233 | Name: "project, p",
234 | EnvVar: "BIKO_JIRA_PROJECT",
235 | Usage: "Specify the project to open",
236 | },
237 | cli.StringFlag{
238 | Name: "org",
239 | EnvVar: "BIKO_JIRA",
240 | Usage: "Specify JIRA Organization",
241 | },
242 | cli.StringFlag{
243 | Name: "base",
244 | EnvVar: "BIKO_JIRA_BASE",
245 | Usage: "Specify JIRA Base URL (for self-managed plan)",
246 | },
247 | },
248 | Action: func(c *cli.Context) error {
249 | var project string
250 | if project = c.String("project"); project == "" {
251 | return fmt.Errorf("Project for jira not configured pass --project or set BIKO_JIRA_PROJECT")
252 | }
253 | baseURL, err := getBaseURL(c)
254 | if err != nil {
255 | return err
256 | }
257 | jr := &jr.Provider{}
258 | if jr.BaseURL, err = url.Parse(baseURL); err != nil {
259 | return err
260 | }
261 | return browser.Open(c, jr)
262 | },
263 | }
264 | }
265 |
266 | func getBaseURL(c *cli.Context) (string, error) {
267 | org := c.String("org")
268 | base := c.String("base")
269 | if org == "" && base == "" {
270 | return "", fmt.Errorf("Org and Base for jira not configured pass --org/BIKO_JIRA or --base/BIKO_JIRA_BASE")
271 | }
272 | var baseURL = fmt.Sprintf("https://%s.atlassian.net", org) // for jira cloud
273 | if base != "" {
274 | baseURL = base // for self-managed
275 | }
276 | return baseURL, nil
277 | }
278 |
--------------------------------------------------------------------------------
/cli/firebase.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package cli
16 |
17 | import (
18 | "github.com/KeisukeYamashita/biko/browser"
19 | "github.com/KeisukeYamashita/biko/providers/firebase"
20 | "github.com/urfave/cli"
21 | )
22 |
23 | const (
24 | categoryDevelop = "Develop"
25 | categoryQuality = "Quality"
26 | categoryAnalytics = "Analitics"
27 | categoryGrow = "Grow"
28 | )
29 |
30 | func newFirebaseCmd() cli.Command {
31 | return cli.Command{
32 | Name: "firebase",
33 | Aliases: []string{"fb"},
34 | Usage: "Open Firebase source",
35 | Category: categoryCloudProvider,
36 | Flags: []cli.Flag{
37 | cli.StringFlag{
38 | Name: "project",
39 | Usage: "Specify the project to open",
40 | },
41 | },
42 | Action: func(c *cli.Context) error {
43 | g, err := firebase.GetProvider()
44 | if err != nil {
45 | return err
46 | }
47 | return browser.Open(c, g)
48 | },
49 | Subcommands: []cli.Command{
50 | newFirebaseAuthenticateCmd(),
51 | newFirebaseDatabaseCmd(),
52 | newFirebaseStorageCmd(),
53 | newFirebaseHostingCmd(),
54 | newFirebaseFunctionsCmd(),
55 | newFirebaseMLKitCmd(),
56 | newFirebaseCrashlyticsCmd(),
57 | newFirebasePerformanceCmd(),
58 | newFirebaseTestLabCmd(),
59 | newFirebaseAppDistributionCmd(),
60 | newFirebasePredictionsCmd(),
61 | },
62 | }
63 | }
64 |
65 | func newFirebaseAuthenticateCmd() cli.Command {
66 | return cli.Command{
67 | Name: "authentication",
68 | Aliases: []string{"auth"},
69 | Category: categoryDevelop,
70 | Usage: "Open authentication page",
71 | Flags: []cli.Flag{
72 | cli.StringFlag{
73 | Name: "project",
74 | Usage: "Specify the project to open",
75 | },
76 | },
77 | Action: func(c *cli.Context) error {
78 | fb, err := firebase.GetProvider()
79 | if err != nil {
80 | return err
81 | }
82 | return browser.Open(c, fb)
83 | },
84 | }
85 | }
86 |
87 | func newFirebaseDatabaseCmd() cli.Command {
88 | return cli.Command{
89 | Name: "database",
90 | Aliases: []string{"db"},
91 | Category: categoryDevelop,
92 | Usage: "Open database page",
93 | Flags: []cli.Flag{
94 | cli.StringFlag{
95 | Name: "project",
96 | Usage: "Specify the project to open",
97 | },
98 | },
99 | Action: func(c *cli.Context) error {
100 | fb, err := firebase.GetProvider()
101 | if err != nil {
102 | return err
103 | }
104 | return browser.Open(c, fb)
105 | },
106 | }
107 | }
108 |
109 | func newFirebaseStorageCmd() cli.Command {
110 | return cli.Command{
111 | Name: "storage",
112 | Category: categoryDevelop,
113 | Usage: "Open storage page",
114 | Flags: []cli.Flag{
115 | cli.StringFlag{
116 | Name: "project",
117 | Usage: "Specify the project to open",
118 | },
119 | },
120 | Action: func(c *cli.Context) error {
121 | fb, err := firebase.GetProvider()
122 | if err != nil {
123 | return err
124 | }
125 | return browser.Open(c, fb)
126 | },
127 | }
128 | }
129 |
130 | func newFirebaseHostingCmd() cli.Command {
131 | return cli.Command{
132 | Name: "hosting",
133 | Aliases: []string{"host", "h"},
134 | Category: categoryDevelop,
135 | Usage: "Open storage page",
136 | Flags: []cli.Flag{
137 | cli.StringFlag{
138 | Name: "project",
139 | Usage: "Specify the project to open",
140 | },
141 | },
142 | Action: func(c *cli.Context) error {
143 | fb, err := firebase.GetProvider()
144 | if err != nil {
145 | return err
146 | }
147 | return browser.Open(c, fb)
148 | },
149 | }
150 | }
151 |
152 | func newFirebaseFunctionsCmd() cli.Command {
153 | return cli.Command{
154 | Name: "functions",
155 | Aliases: []string{"func", "f"},
156 | Category: categoryDevelop,
157 | Usage: "Open functions page",
158 | Flags: []cli.Flag{
159 | cli.StringFlag{
160 | Name: "project",
161 | Usage: "Specify the project to open",
162 | },
163 | },
164 | Action: func(c *cli.Context) error {
165 | fb, err := firebase.GetProvider()
166 | if err != nil {
167 | return err
168 | }
169 | return browser.Open(c, fb)
170 | },
171 | }
172 | }
173 |
174 | func newFirebaseMLKitCmd() cli.Command {
175 | return cli.Command{
176 | Name: "ml",
177 | Category: categoryDevelop,
178 | Usage: "Open ML kit page",
179 | Flags: []cli.Flag{
180 | cli.StringFlag{
181 | Name: "project",
182 | Usage: "Specify the project to open",
183 | },
184 | },
185 | Action: func(c *cli.Context) error {
186 | fb, err := firebase.GetProvider()
187 | if err != nil {
188 | return err
189 | }
190 | return browser.Open(c, fb)
191 | },
192 | }
193 | }
194 |
195 | func newFirebaseCrashlyticsCmd() cli.Command {
196 | return cli.Command{
197 | Name: "crashlytics",
198 | Aliases: []string{"crash"},
199 | Category: categoryQuality,
200 | Usage: "Open crashlytics page",
201 | Flags: []cli.Flag{
202 | cli.StringFlag{
203 | Name: "project",
204 | Usage: "Specify the project to open",
205 | },
206 | },
207 | Action: func(c *cli.Context) error {
208 | fb, err := firebase.GetProvider()
209 | if err != nil {
210 | return err
211 | }
212 | return browser.Open(c, fb)
213 | },
214 | }
215 | }
216 |
217 | func newFirebasePerformanceCmd() cli.Command {
218 | return cli.Command{
219 | Name: "performance",
220 | Aliases: []string{"perf"},
221 | Category: categoryQuality,
222 | Usage: "Open performance page",
223 | Flags: []cli.Flag{
224 | cli.StringFlag{
225 | Name: "project",
226 | Usage: "Specify the project to open",
227 | },
228 | },
229 | Action: func(c *cli.Context) error {
230 | fb, err := firebase.GetProvider()
231 | if err != nil {
232 | return err
233 | }
234 | return browser.Open(c, fb)
235 | },
236 | }
237 | }
238 |
239 | func newFirebaseTestLabCmd() cli.Command {
240 | return cli.Command{
241 | Name: "testlab",
242 | Aliases: []string{"tl"},
243 | Category: categoryQuality,
244 | Usage: "Open testlab page",
245 | Flags: []cli.Flag{
246 | cli.StringFlag{
247 | Name: "project",
248 | Usage: "Specify the project to open",
249 | },
250 | },
251 | Action: func(c *cli.Context) error {
252 | fb, err := firebase.GetProvider()
253 | if err != nil {
254 | return err
255 | }
256 | return browser.Open(c, fb)
257 | },
258 | }
259 | }
260 |
261 | func newFirebaseAppDistributionCmd() cli.Command {
262 | return cli.Command{
263 | Name: "appdistribution",
264 | Aliases: []string{"ad"},
265 | Category: categoryQuality,
266 | Usage: "Open app distribution page",
267 | Flags: []cli.Flag{
268 | cli.StringFlag{
269 | Name: "project",
270 | Usage: "Specify the project to open",
271 | },
272 | },
273 | Action: func(c *cli.Context) error {
274 | fb, err := firebase.GetProvider()
275 | if err != nil {
276 | return err
277 | }
278 | return browser.Open(c, fb)
279 | },
280 | }
281 | }
282 |
283 | func newFirebaseDashboardCmd() cli.Command {
284 | return cli.Command{
285 | Name: "dashboard",
286 | Aliases: []string{"a"},
287 | Category: categoryAnalytics,
288 | Usage: "Open dashboard page",
289 | Flags: []cli.Flag{
290 | cli.StringFlag{
291 | Name: "project",
292 | Usage: "Specify the project to open",
293 | },
294 | },
295 | Action: func(c *cli.Context) error {
296 | fb, err := firebase.GetProvider()
297 | if err != nil {
298 | return err
299 | }
300 | return browser.Open(c, fb)
301 | },
302 | }
303 | }
304 |
305 | func newFirebasePredictionsCmd() cli.Command {
306 | return cli.Command{
307 | Name: "predictions",
308 | Aliases: []string{"pred"},
309 | Category: categoryGrow,
310 | Usage: "Open predictions page",
311 | Flags: []cli.Flag{
312 | cli.StringFlag{
313 | Name: "project",
314 | Usage: "Specify the project to open",
315 | },
316 | },
317 | Action: func(c *cli.Context) error {
318 | fb, err := firebase.GetProvider()
319 | if err != nil {
320 | return err
321 | }
322 | return browser.Open(c, fb)
323 | },
324 | }
325 | }
326 |
--------------------------------------------------------------------------------
/cli/aws.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package cli
16 |
17 | import (
18 | "github.com/KeisukeYamashita/biko/browser"
19 | "github.com/KeisukeYamashita/biko/providers/aws"
20 | "github.com/urfave/cli"
21 | )
22 |
23 | const (
24 | categoryAWSComputing = "Computing"
25 | categoryAWSStorage = "Storage"
26 | categoryAWSDatabase = "Database"
27 | categoryAWSNetworking = "Networking and Contens Delivery"
28 | )
29 |
30 | func newAWSCmd() cli.Command {
31 | return cli.Command{
32 | Name: "aws",
33 | Usage: "Open AWS resource",
34 | Category: categoryCloudProvider,
35 | Flags: []cli.Flag{},
36 | Action: func(c *cli.Context) error {
37 | aws, err := aws.GetProvider()
38 | if err != nil {
39 | return err
40 | }
41 | return browser.Open(c, aws)
42 | },
43 | Subcommands: []cli.Command{
44 | newAWSEC2Cmd(),
45 | newAWSECRCmd(),
46 | newAWSECSCmd(),
47 | newAWSLambdaCmd(),
48 | newAWSBatchCmd(),
49 | newAWSS3Cmd(),
50 | newAWSEFSCmd(),
51 | newAWSRDSCmd(),
52 | newAWSDynamoDBCmd(),
53 | newAWSNeptuneCmd(),
54 | newAWSVPCCmd(),
55 | newAWSRoute53Cmd(),
56 | },
57 | }
58 | }
59 |
60 | func newAWSEC2Cmd() cli.Command {
61 | return cli.Command{
62 | Name: "ec2",
63 | Usage: "Open EC2 page",
64 | Category: categoryAWSComputing,
65 | Flags: []cli.Flag{
66 | cli.StringFlag{
67 | Name: "region, r",
68 | Usage: "Specify the region to open",
69 | },
70 | },
71 | Action: func(c *cli.Context) error {
72 | aws, err := aws.GetProvider()
73 | if err != nil {
74 | return err
75 | }
76 | return browser.Open(c, aws)
77 | },
78 | }
79 | }
80 |
81 | func newAWSECRCmd() cli.Command {
82 | return cli.Command{
83 | Name: "ecr",
84 | Usage: "Open ECR page",
85 | Category: categoryAWSComputing,
86 | Flags: []cli.Flag{},
87 | Action: func(c *cli.Context) error {
88 | aws, err := aws.GetProvider()
89 | if err != nil {
90 | return err
91 | }
92 | return browser.Open(c, aws)
93 | },
94 | }
95 | }
96 |
97 | func newAWSECSCmd() cli.Command {
98 | return cli.Command{
99 | Name: "ecs",
100 | Usage: "Open ECS page",
101 | Category: categoryAWSComputing,
102 | Flags: []cli.Flag{
103 | cli.StringFlag{
104 | Name: "region, r",
105 | Usage: "Specify the region to open",
106 | },
107 | },
108 | Action: func(c *cli.Context) error {
109 | aws, err := aws.GetProvider()
110 | if err != nil {
111 | return err
112 | }
113 | return browser.Open(c, aws)
114 | },
115 | }
116 | }
117 |
118 | func newAWSEKSCmd() cli.Command {
119 | return cli.Command{
120 | Name: "eks",
121 | Usage: "Open EKS page",
122 | Category: categoryAWSComputing,
123 | Flags: []cli.Flag{
124 | cli.StringFlag{
125 | Name: "region, r",
126 | Usage: "Specify the region to open",
127 | },
128 | },
129 | Action: func(c *cli.Context) error {
130 | aws, err := aws.GetProvider()
131 | if err != nil {
132 | return err
133 | }
134 | return browser.Open(c, aws)
135 | },
136 | }
137 | }
138 |
139 | func newAWSLambdaCmd() cli.Command {
140 | return cli.Command{
141 | Name: "lambda",
142 | Aliases: []string{"lam", "l"},
143 | Usage: "Open EKS page",
144 | Category: categoryAWSComputing,
145 | Flags: []cli.Flag{
146 | cli.StringFlag{
147 | Name: "region, r",
148 | Usage: "Specify the region to open",
149 | },
150 | },
151 | Action: func(c *cli.Context) error {
152 | aws, err := aws.GetProvider()
153 | if err != nil {
154 | return err
155 | }
156 | return browser.Open(c, aws)
157 | },
158 | }
159 | }
160 |
161 | func newAWSBatchCmd() cli.Command {
162 | return cli.Command{
163 | Name: "batch",
164 | Aliases: []string{"b"},
165 | Usage: "Open Batch page",
166 | Category: categoryAWSComputing,
167 | Flags: []cli.Flag{
168 | cli.StringFlag{
169 | Name: "region, r",
170 | Usage: "Specify the region to open",
171 | },
172 | },
173 | Action: func(c *cli.Context) error {
174 | aws, err := aws.GetProvider()
175 | if err != nil {
176 | return err
177 | }
178 | return browser.Open(c, aws)
179 | },
180 | }
181 | }
182 |
183 | func newAWSS3Cmd() cli.Command {
184 | return cli.Command{
185 | Name: "s3",
186 | Usage: "Open S3 page",
187 | Category: categoryAWSStorage,
188 | Flags: []cli.Flag{
189 | cli.StringFlag{
190 | Name: "region, r",
191 | Usage: "Specify the region to open",
192 | },
193 | },
194 | Action: func(c *cli.Context) error {
195 | aws, err := aws.GetProvider()
196 | if err != nil {
197 | return err
198 | }
199 | return browser.Open(c, aws)
200 | },
201 | }
202 | }
203 |
204 | func newAWSEFSCmd() cli.Command {
205 | return cli.Command{
206 | Name: "efs",
207 | Usage: "Open EFS page",
208 | Category: categoryAWSStorage,
209 | Flags: []cli.Flag{
210 | cli.StringFlag{
211 | Name: "region, r",
212 | Usage: "Specify the region to open",
213 | },
214 | },
215 | Action: func(c *cli.Context) error {
216 | aws, err := aws.GetProvider()
217 | if err != nil {
218 | return err
219 | }
220 | return browser.Open(c, aws)
221 | },
222 | }
223 | }
224 |
225 | func newAWSRDSCmd() cli.Command {
226 | return cli.Command{
227 | Name: "rds",
228 | Usage: "Open RDS page",
229 | Category: categoryAWSDatabase,
230 | Flags: []cli.Flag{
231 | cli.StringFlag{
232 | Name: "region, r",
233 | Usage: "Specify the region to open",
234 | },
235 | },
236 | Action: func(c *cli.Context) error {
237 | aws, err := aws.GetProvider()
238 | if err != nil {
239 | return err
240 | }
241 | return browser.Open(c, aws)
242 | },
243 | }
244 | }
245 |
246 | func newAWSDynamoDBCmd() cli.Command {
247 | return cli.Command{
248 | Name: "dynamodb",
249 | Aliases: []string{"dynamo", "dyn"},
250 | Usage: "Open Dynamo page",
251 | Category: categoryAWSDatabase,
252 | Flags: []cli.Flag{
253 | cli.StringFlag{
254 | Name: "region, r",
255 | Usage: "Specify the region to open",
256 | },
257 | },
258 | Action: func(c *cli.Context) error {
259 | aws, err := aws.GetProvider()
260 | if err != nil {
261 | return err
262 | }
263 | return browser.Open(c, aws)
264 | },
265 | }
266 | }
267 |
268 | func newAWSNeptuneCmd() cli.Command {
269 | return cli.Command{
270 | Name: "neptune",
271 | Usage: "Open Neptune page",
272 | Category: categoryAWSDatabase,
273 | Flags: []cli.Flag{
274 | cli.StringFlag{
275 | Name: "region, r",
276 | Usage: "Specify the region to open",
277 | },
278 | },
279 | Action: func(c *cli.Context) error {
280 | aws, err := aws.GetProvider()
281 | if err != nil {
282 | return err
283 | }
284 | return browser.Open(c, aws)
285 | },
286 | }
287 | }
288 |
289 | func newAWSRedshiftCmd() cli.Command {
290 | return cli.Command{
291 | Name: "redshift",
292 | Aliases: []string{"red", "rs"},
293 | Usage: "Open Neptune page",
294 | Category: categoryAWSDatabase,
295 | Flags: []cli.Flag{
296 | cli.StringFlag{
297 | Name: "region, r",
298 | Usage: "Specify the region to open",
299 | },
300 | },
301 | Action: func(c *cli.Context) error {
302 | aws, err := aws.GetProvider()
303 | if err != nil {
304 | return err
305 | }
306 | return browser.Open(c, aws)
307 | },
308 | }
309 | }
310 |
311 | func newAWSVPCCmd() cli.Command {
312 | return cli.Command{
313 | Name: "vpc",
314 | Usage: "Open VPC page",
315 | Category: categoryAWSNetworking,
316 | Flags: []cli.Flag{
317 | cli.StringFlag{
318 | Name: "region, r",
319 | Usage: "Specify the region to open",
320 | },
321 | },
322 | Action: func(c *cli.Context) error {
323 | aws, err := aws.GetProvider()
324 | if err != nil {
325 | return err
326 | }
327 | return browser.Open(c, aws)
328 | },
329 | }
330 | }
331 |
332 | func newAWSRoute53Cmd() cli.Command {
333 | return cli.Command{
334 | Name: "route53",
335 | Usage: "Open Route53 page",
336 | Aliases: []string{"route", "53"},
337 | Category: categoryAWSNetworking,
338 | Flags: []cli.Flag{
339 | cli.StringFlag{
340 | Name: "region, r",
341 | Usage: "Specify the region to open",
342 | },
343 | },
344 | Action: func(c *cli.Context) error {
345 | aws, err := aws.GetProvider()
346 | if err != nil {
347 | return err
348 | }
349 | return browser.Open(c, aws)
350 | },
351 | }
352 | }
353 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/cli/gcp.go:
--------------------------------------------------------------------------------
1 | // Copyright 2019 The Biko Authors.
2 | //
3 | // Licensed under the Apache License, Version 2.0 (the "License");
4 | // you may not use this file except in compliance with the License.
5 | // You may obtain a copy of the License at
6 | //
7 | // http://www.apache.org/licenses/LICENSE-2.0
8 | //
9 | // Unless required by applicable law or agreed to in writing, software
10 | // distributed under the License is distributed on an "AS IS" BASIS,
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | // See the License for the specific language governing permissions and
13 | // limitations under the License.
14 |
15 | package cli
16 |
17 | import (
18 | "github.com/KeisukeYamashita/biko/browser"
19 | "github.com/KeisukeYamashita/biko/providers/gcp"
20 | "github.com/urfave/cli"
21 | )
22 |
23 | const (
24 | categoryCommon = "Common"
25 | categoryCompute = "Compute"
26 | categoryStorage = "Storage"
27 | categoryNetworking = "Networking"
28 | categoryStackdriver = "Stackdriver"
29 | categoryTools = "Tools"
30 | categoryBigData = "Big Data"
31 | )
32 |
33 | func newGCPCmd() cli.Command {
34 | return cli.Command{
35 | Name: "gcp",
36 | Usage: "Open GCP resource",
37 | Category: categoryCloudProvider,
38 | Flags: []cli.Flag{
39 | cli.StringFlag{
40 | Name: "project",
41 | Usage: "Specify the project to open",
42 | },
43 | },
44 | Action: func(c *cli.Context) error {
45 | gcp := &gcp.Provider{}
46 | return browser.Open(c, gcp)
47 | },
48 | Subcommands: []cli.Command{
49 | newGCPGAECmd(),
50 | newGCPBQCmd(),
51 | newGCPCloudRunCmd(),
52 | newGCPDataflowCmd(),
53 | newGCPFunctionsCmd(),
54 | newGCPGCECmd(),
55 | newGCPGCRCmd(),
56 | newGCPGKECmd(),
57 | newGCPIAMCmd(),
58 | newGCPLogsCmd(),
59 | newGCPKMSCmd(),
60 | newGCPPubSubCmd(),
61 | newGCPSecretManagerCmd(),
62 | newGCPSpannerCmd(),
63 | newGCPStorageCmd(),
64 | newGCPSQLCmd(),
65 | },
66 | }
67 | }
68 |
69 | func newGCPGAECmd() cli.Command {
70 | return cli.Command{
71 | Name: "appengine",
72 | Aliases: []string{"gae"},
73 | Category: categoryCompute,
74 | Usage: "Open GAE page",
75 | Flags: []cli.Flag{
76 | cli.StringFlag{
77 | Name: "project",
78 | Usage: "Specify the project to open",
79 | },
80 | },
81 | Action: func(c *cli.Context) error {
82 | gcp, err := gcp.GetProvider()
83 | if err != nil {
84 | return err
85 | }
86 | return browser.Open(c, gcp)
87 | },
88 | }
89 | }
90 |
91 | func newGCPBQCmd() cli.Command {
92 | return cli.Command{
93 | Name: "bigquery",
94 | Aliases: []string{"bq"},
95 | Category: categoryBigData,
96 | Usage: "Open Bigquery page",
97 | Flags: []cli.Flag{
98 | cli.StringFlag{
99 | Name: "project",
100 | Usage: "Specify the project to open",
101 | },
102 | cli.StringFlag{
103 | Name: "database, db",
104 | Usage: "Database to show",
105 | },
106 | cli.StringFlag{
107 | Name: "table, t",
108 | Usage: "Table to show",
109 | },
110 | },
111 | Action: func(c *cli.Context) error {
112 | gcp, err := gcp.GetProvider()
113 | if err != nil {
114 | return err
115 | }
116 | return browser.Open(c, gcp)
117 | },
118 | }
119 | }
120 |
121 | func newGCPGKECmd() cli.Command {
122 | return cli.Command{
123 | Name: "kubernetes",
124 | Aliases: []string{"gke"},
125 | Category: categoryCompute,
126 | Usage: "Open GKE page",
127 | Flags: []cli.Flag{
128 | cli.StringFlag{
129 | Name: "project",
130 | Usage: "Specify the project to open",
131 | },
132 | cli.StringFlag{
133 | Name: "region, r",
134 | Usage: "Region of the cluster",
135 | },
136 | cli.StringFlag{
137 | Name: "name, n",
138 | Usage: "Name of the cluter",
139 | },
140 | cli.StringFlag{
141 | Name: "namespaces, ns",
142 | Usage: "Namespaces of workload page to open (you can input multiple namespaces by comma-speparated string)",
143 | },
144 | },
145 | Action: func(c *cli.Context) error {
146 | gcp, err := gcp.GetProvider()
147 | if err != nil {
148 | return err
149 | }
150 | return browser.Open(c, gcp)
151 | },
152 | }
153 | }
154 |
155 | func newGCPSpannerCmd() cli.Command {
156 | return cli.Command{
157 | Name: "spanner",
158 | Usage: "Open Cloud Spanner page",
159 | Category: categoryStorage,
160 | Flags: []cli.Flag{
161 | cli.StringFlag{
162 | Name: "project",
163 | Usage: "Specify the project to open",
164 | },
165 | cli.StringFlag{
166 | Name: "instance, i",
167 | Usage: "Instance name",
168 | },
169 | cli.StringFlag{
170 | Name: "database, db",
171 | Usage: "Database name",
172 | },
173 | cli.StringFlag{
174 | Name: "table, tb",
175 | Usage: "Table name",
176 | },
177 | },
178 | Action: func(c *cli.Context) error {
179 | gcp, err := gcp.GetProvider()
180 | if err != nil {
181 | return err
182 | }
183 | return browser.Open(c, gcp)
184 | },
185 | }
186 | }
187 |
188 | func newGCPSecretManagerCmd() cli.Command {
189 | return cli.Command{
190 | Name: "secret-manager",
191 | Aliases: []string{"sm", "secretmanager", "secretManager"},
192 | Usage: "Open Secret Manager page",
193 | Category: categoryStorage,
194 | Flags: []cli.Flag{
195 | cli.StringFlag{
196 | Name: "project",
197 | Usage: "Specify the project to open",
198 | },
199 | cli.StringFlag{
200 | Name: "secret, s",
201 | Usage: "Secret name",
202 | },
203 | },
204 | Action: func(c *cli.Context) error {
205 | gcp, err := gcp.GetProvider()
206 | if err != nil {
207 | return err
208 | }
209 | return browser.Open(c, gcp)
210 | },
211 | }
212 | }
213 |
214 | func newGCPGCRCmd() cli.Command {
215 | return cli.Command{
216 | Name: "gcr",
217 | Usage: "Open Cloud Registry page",
218 | Category: categoryTools,
219 | Flags: []cli.Flag{
220 | cli.StringFlag{
221 | Name: "project",
222 | Usage: "Specify the project to open",
223 | },
224 | cli.StringFlag{
225 | Name: "name, n",
226 | Usage: "Name of the image",
227 | },
228 | },
229 | Action: func(c *cli.Context) error {
230 | gcp, err := gcp.GetProvider()
231 | if err != nil {
232 | return err
233 | }
234 | return browser.Open(c, gcp)
235 | },
236 | }
237 | }
238 |
239 | func newGCPFunctionsCmd() cli.Command {
240 | return cli.Command{
241 | Name: "functions",
242 | Aliases: []string{"f"},
243 | Category: categoryCompute,
244 | Usage: "Open Cloud Functions page",
245 | Flags: []cli.Flag{
246 | cli.StringFlag{
247 | Name: "project",
248 | Usage: "Specify the project to open",
249 | },
250 | cli.StringFlag{
251 | Name: "name, n",
252 | Usage: "Name of the function",
253 | },
254 | cli.StringFlag{
255 | Name: "region, r",
256 | Usage: "Region of the function",
257 | },
258 | },
259 | Action: func(c *cli.Context) error {
260 | gcp, err := gcp.GetProvider()
261 | if err != nil {
262 | return err
263 | }
264 | return browser.Open(c, gcp)
265 | },
266 | }
267 | }
268 |
269 | func newGCPCloudRunCmd() cli.Command {
270 | return cli.Command{
271 | Name: "run",
272 | Category: categoryCompute,
273 | Usage: "Open Cloud Run page",
274 | Flags: []cli.Flag{
275 | cli.StringFlag{
276 | Name: "project",
277 | Usage: "Specify the project to open",
278 | },
279 | cli.StringFlag{
280 | Name: "name, n",
281 | Usage: "Name of the function",
282 | },
283 | cli.StringFlag{
284 | Name: "region, r",
285 | Usage: "Region of the function",
286 | },
287 | },
288 | Action: func(c *cli.Context) error {
289 | gcp, err := gcp.GetProvider()
290 | if err != nil {
291 | return err
292 | }
293 | return browser.Open(c, gcp)
294 | },
295 | }
296 | }
297 |
298 | func newGCPGCECmd() cli.Command {
299 | return cli.Command{
300 | Name: "compute",
301 | Aliases: []string{"gce"},
302 | Category: categoryCompute,
303 | Usage: "Open Compute Engine page",
304 | Flags: []cli.Flag{
305 | cli.StringFlag{
306 | Name: "project",
307 | Usage: "Specify the project to open",
308 | },
309 | },
310 | Action: func(c *cli.Context) error {
311 | gcp, err := gcp.GetProvider()
312 | if err != nil {
313 | return err
314 | }
315 | return browser.Open(c, gcp)
316 | },
317 | }
318 | }
319 |
320 | func newGCPLogsCmd() cli.Command {
321 | return cli.Command{
322 | Name: "logs",
323 | Aliases: []string{"l"},
324 | Category: categoryStackdriver,
325 | Usage: "Open Stackdriver log page",
326 | Flags: []cli.Flag{
327 | cli.StringFlag{
328 | Name: "project",
329 | Usage: "Specify the project to open",
330 | },
331 | },
332 | Action: func(c *cli.Context) error {
333 | gcp, err := gcp.GetProvider()
334 | if err != nil {
335 | return err
336 | }
337 | return browser.Open(c, gcp)
338 | },
339 | }
340 | }
341 |
342 | func newGCPIAMCmd() cli.Command {
343 | return cli.Command{
344 | Name: "iam",
345 | Category: categoryCommon,
346 | Usage: "Open IAM & admin page",
347 | Flags: []cli.Flag{
348 | cli.StringFlag{
349 | Name: "project",
350 | Usage: "Specify the project to open",
351 | },
352 | },
353 | Action: func(c *cli.Context) error {
354 | gcp, err := gcp.GetProvider()
355 | if err != nil {
356 | return err
357 | }
358 | return browser.Open(c, gcp)
359 | },
360 | }
361 | }
362 |
363 | func newGCPSQLCmd() cli.Command {
364 | return cli.Command{
365 | Name: "sql",
366 | Category: categoryStorage,
367 | Usage: "Open Cloud SQL page",
368 | Flags: []cli.Flag{
369 | cli.StringFlag{
370 | Name: "project",
371 | Usage: "Specify the project to open",
372 | },
373 | },
374 | Action: func(c *cli.Context) error {
375 | gcp, err := gcp.GetProvider()
376 | if err != nil {
377 | return err
378 | }
379 | return browser.Open(c, gcp)
380 | },
381 | }
382 | }
383 |
384 | func newGCPPubSubCmd() cli.Command {
385 | return cli.Command{
386 | Name: "pubsub",
387 | Category: categoryBigData,
388 | Usage: "Open Cloud PubSub page",
389 | Flags: []cli.Flag{
390 | cli.StringFlag{
391 | Name: "project",
392 | Usage: "Specify the project to open",
393 | },
394 | },
395 | Action: func(c *cli.Context) error {
396 | gcp, err := gcp.GetProvider()
397 | if err != nil {
398 | return err
399 | }
400 | return browser.Open(c, gcp)
401 | },
402 | }
403 | }
404 |
405 | func newGCPStorageCmd() cli.Command {
406 | return cli.Command{
407 | Name: "storage",
408 | Aliases: []string{"gcs"},
409 | Category: categoryStorage,
410 | Usage: "Open Cloud Storage page",
411 | Flags: []cli.Flag{
412 | cli.StringFlag{
413 | Name: "project",
414 | Usage: "Specify the project to open",
415 | },
416 | cli.StringFlag{
417 | Name: "bucket, b",
418 | Usage: "Specify the bucket to open",
419 | },
420 | },
421 | Action: func(c *cli.Context) error {
422 | gcp, err := gcp.GetProvider()
423 | if err != nil {
424 | return err
425 | }
426 | return browser.Open(c, gcp)
427 | },
428 | }
429 | }
430 |
431 | func newGCPDataflowCmd() cli.Command {
432 | return cli.Command{
433 | Name: "dataflow",
434 | Category: categoryBigData,
435 | Usage: "Open Cloud Dataflow page",
436 | Flags: []cli.Flag{
437 | cli.StringFlag{
438 | Name: "project",
439 | Usage: "Specify the project to open",
440 | },
441 | },
442 | Action: func(c *cli.Context) error {
443 | gcp, err := gcp.GetProvider()
444 | if err != nil {
445 | return err
446 | }
447 | return browser.Open(c, gcp)
448 | },
449 | }
450 | }
451 |
452 | func newGCPKMSCmd() cli.Command {
453 | return cli.Command{
454 | Name: "kms",
455 | Category: categoryBigData,
456 | Usage: "Open Cloud KMS",
457 | Flags: []cli.Flag{
458 | cli.StringFlag{
459 | Name: "project",
460 | Usage: "Specify the project to open",
461 | },
462 | },
463 | Action: func(c *cli.Context) error {
464 | gcp, err := gcp.GetProvider()
465 | if err != nil {
466 | return err
467 | }
468 | return browser.Open(c, gcp)
469 | },
470 | }
471 | }
472 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Biko
2 |
3 | > CLI tool to jump to your browser directly to improve productivity
4 |
5 |
6 |