Merge pull request #5955 from concourse/fix-fly-tokens
Fly commands don't assume tokens are JWTs
This commit is contained in:
commit
203e2b3f9b
|
@ -21,12 +21,12 @@ func (command *LogoutCommand) Execute(args []string) error {
|
|||
fmt.Println("logged out of target: " + Fly.Target)
|
||||
} else if Fly.Target == "" && command.All {
|
||||
|
||||
flyYAML, err := rc.LoadTargets()
|
||||
targets, err := rc.LoadTargets()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for targetName := range flyYAML.Targets {
|
||||
for targetName := range targets {
|
||||
if err := rc.LogoutTarget(targetName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@ import (
|
|||
|
||||
"github.com/concourse/concourse/fly/commands/internal/displayhelpers"
|
||||
"github.com/concourse/concourse/fly/rc"
|
||||
jwt "github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
type StatusCommand struct{}
|
||||
|
@ -23,21 +22,10 @@ func (c *StatusCommand) Execute([]string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
if tToken != nil {
|
||||
_, err := jwt.Parse(tToken.Value, func(token *jwt.Token) (interface{}, error) {
|
||||
return nil, token.Claims.Valid()
|
||||
})
|
||||
|
||||
if err != nil && err.Error() != jwt.ErrInvalidKeyType.Error() {
|
||||
displayhelpers.FailWithErrorf("please login again.\n\ntoken validation failed with error ", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
_, err = target.Client().UserInfo()
|
||||
if err != nil {
|
||||
displayhelpers.FailWithErrorf("please login again.\n\ntoken validation failed with error ", err)
|
||||
return nil
|
||||
}
|
||||
_, err = target.Client().UserInfo()
|
||||
if err != nil {
|
||||
displayhelpers.FailWithErrorf("please login again.\n\ntoken validation failed with error", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Println("logged in successfully")
|
||||
|
|
|
@ -1,22 +1,20 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/concourse/concourse/fly/rc"
|
||||
"github.com/concourse/concourse/fly/ui"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/concourse/concourse/skymarshal/token"
|
||||
"github.com/fatih/color"
|
||||
)
|
||||
|
||||
type TargetsCommand struct{}
|
||||
|
||||
func (command *TargetsCommand) Execute([]string) error {
|
||||
flyYAML, err := rc.LoadTargets()
|
||||
targets, err := rc.LoadTargets()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -30,7 +28,7 @@ func (command *TargetsCommand) Execute([]string) error {
|
|||
},
|
||||
}
|
||||
|
||||
for targetName, targetValues := range flyYAML.Targets {
|
||||
for targetName, targetValues := range targets {
|
||||
expirationTime := getExpirationFromString(targetValues.Token)
|
||||
|
||||
row := ui.TableRow{
|
||||
|
@ -48,43 +46,15 @@ func (command *TargetsCommand) Execute([]string) error {
|
|||
return table.Render(os.Stdout, Fly.PrintTableHeaders)
|
||||
}
|
||||
|
||||
func getExpirationFromString(token *rc.TargetToken) string {
|
||||
if token == nil || token.Type == "" || token.Value == "" {
|
||||
func getExpirationFromString(ttoken *rc.TargetToken) string {
|
||||
if ttoken == nil || ttoken.Type == "" || ttoken.Value == "" {
|
||||
return "n/a"
|
||||
}
|
||||
|
||||
parsedToken, err := jwt.Parse(token.Value, func(token *jwt.Token) (interface{}, error) {
|
||||
return "", token.Claims.Valid()
|
||||
})
|
||||
|
||||
if err != nil && err.Error() != jwt.ErrInvalidKeyType.Error() {
|
||||
return fmt.Sprintf("n/a: %s", err)
|
||||
expiry, err := token.Factory{}.ParseExpiry(ttoken.Value)
|
||||
if err != nil {
|
||||
return "n/a: invalid token"
|
||||
}
|
||||
|
||||
claims := parsedToken.Claims.(jwt.MapClaims)
|
||||
expClaim, ok := claims["exp"]
|
||||
if !ok {
|
||||
return "n/a"
|
||||
}
|
||||
|
||||
var intSeconds int64
|
||||
|
||||
floatSeconds, ok := expClaim.(float64)
|
||||
if ok {
|
||||
intSeconds = int64(floatSeconds)
|
||||
} else {
|
||||
stringSeconds, ok := expClaim.(string)
|
||||
if !ok {
|
||||
return "n/a"
|
||||
}
|
||||
var err error
|
||||
intSeconds, err = strconv.ParseInt(stringSeconds, 10, 64)
|
||||
if err != nil {
|
||||
return "n/a"
|
||||
}
|
||||
}
|
||||
|
||||
unixSeconds := time.Unix(intSeconds, 0).UTC()
|
||||
|
||||
return unixSeconds.Format(time.RFC1123)
|
||||
return expiry.UTC().Format(time.RFC1123)
|
||||
}
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
package integration_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/concourse/concourse/fly/rc"
|
||||
"github.com/concourse/concourse/fly/ui"
|
||||
"github.com/fatih/color"
|
||||
|
||||
|
@ -21,32 +17,19 @@ import (
|
|||
var _ = Describe("Fly CLI", func() {
|
||||
Describe("delete target", func() {
|
||||
Describe("valid configuration", func() {
|
||||
var (
|
||||
flyrc string
|
||||
tmpDir string
|
||||
)
|
||||
BeforeEach(func() {
|
||||
var err error
|
||||
tmpDir, err = ioutil.TempDir("", "fly-test")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
os.Setenv("USERPROFILE", tmpDir)
|
||||
os.Setenv("HOMEPATH", strings.TrimPrefix(tmpDir, os.Getenv("HOMEDRIVE")))
|
||||
} else {
|
||||
os.Setenv("HOME", tmpDir)
|
||||
}
|
||||
|
||||
flyrc = filepath.Join(userHomeDir(), ".flyrc")
|
||||
|
||||
flyFixtureFile, err := os.OpenFile("./fixtures/flyrc.yml", os.O_RDONLY, 0600)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
flyFixtureData, err := ioutil.ReadAll(flyFixtureFile)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = ioutil.WriteFile(flyrc, flyFixtureData, 0600)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
createFlyRc(rc.Targets{
|
||||
"test1": {
|
||||
API: "https://example.com/test1",
|
||||
TeamName: "main",
|
||||
Token: &rc.TargetToken{Type: "Bearer", Value: validAccessToken(date(2020, 1, 1))},
|
||||
},
|
||||
"test2": {
|
||||
API: "https://example.com/test2",
|
||||
TeamName: "main",
|
||||
Token: &rc.TargetToken{Type: "Bearer", Value: validAccessToken(date(2020, 1, 2))},
|
||||
},
|
||||
})
|
||||
|
||||
flyCmd := exec.Command(flyPath, "targets")
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
|
@ -62,21 +45,15 @@ var _ = Describe("Fly CLI", func() {
|
|||
{Contents: "expiry", Color: color.New(color.Bold)},
|
||||
},
|
||||
Data: []ui.TableRow{
|
||||
{{Contents: "another-test"}, {Contents: "https://example.com/another-test"}, {Contents: "test"}, {Contents: "Sat, 19 Mar 2016 01:54:30 UTC"}},
|
||||
{{Contents: "no-token"}, {Contents: "https://example.com/no-token"}, {Contents: "main"}, {Contents: "n/a"}},
|
||||
{{Contents: "omt"}, {Contents: "https://example.com/omt"}, {Contents: "main"}, {Contents: "Mon, 21 Mar 2016 01:54:30 UTC"}},
|
||||
{{Contents: "test"}, {Contents: "https://example.com/test"}, {Contents: "test"}, {Contents: "Fri, 25 Mar 2016 23:29:57 UTC"}},
|
||||
{{Contents: "test1"}, {Contents: "https://example.com/test1"}, {Contents: "main"}, {Contents: "Wed, 01 Jan 2020 00:00:00 UTC"}},
|
||||
{{Contents: "test2"}, {Contents: "https://example.com/test2"}, {Contents: "main"}, {Contents: "Thu, 02 Jan 2020 00:00:00 UTC"}},
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
os.RemoveAll(tmpDir)
|
||||
})
|
||||
|
||||
Context("when fly target is specified", func() {
|
||||
It("should delete target", func() {
|
||||
flyCmd := exec.Command(flyPath, "-t", "test", "delete-target")
|
||||
flyCmd := exec.Command(flyPath, "-t", "test1", "delete-target")
|
||||
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
@ -84,7 +61,7 @@ var _ = Describe("Fly CLI", func() {
|
|||
<-sess.Exited
|
||||
Expect(sess.ExitCode()).To(Equal(0))
|
||||
|
||||
Expect(sess.Out).To(gbytes.Say(`deleted target: test`))
|
||||
Expect(sess.Out).To(gbytes.Say(`deleted target: test1`))
|
||||
|
||||
flyCmd = exec.Command(flyPath, "targets")
|
||||
sess, err = gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
|
@ -99,9 +76,7 @@ var _ = Describe("Fly CLI", func() {
|
|||
{Contents: "expiry", Color: color.New(color.Bold)},
|
||||
},
|
||||
Data: []ui.TableRow{
|
||||
{{Contents: "another-test"}, {Contents: "https://example.com/another-test"}, {Contents: "test"}, {Contents: "Sat, 19 Mar 2016 01:54:30 UTC"}},
|
||||
{{Contents: "no-token"}, {Contents: "https://example.com/no-token"}, {Contents: "main"}, {Contents: "n/a"}},
|
||||
{{Contents: "omt"}, {Contents: "https://example.com/omt"}, {Contents: "main"}, {Contents: "Mon, 21 Mar 2016 01:54:30 UTC"}},
|
||||
{{Contents: "test2"}, {Contents: "https://example.com/test2"}, {Contents: "main"}, {Contents: "Thu, 02 Jan 2020 00:00:00 UTC"}},
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
@ -109,7 +84,7 @@ var _ = Describe("Fly CLI", func() {
|
|||
|
||||
Context("when configuration all", func() {
|
||||
It("should delete all targets", func() {
|
||||
flyCmd := exec.Command(flyPath, "-t", "test", "delete-target", "--all")
|
||||
flyCmd := exec.Command(flyPath, "-t", "test1", "delete-target", "--all")
|
||||
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
package integration_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/concourse/concourse/fly/rc"
|
||||
"github.com/concourse/concourse/fly/ui"
|
||||
"github.com/fatih/color"
|
||||
|
||||
|
@ -39,33 +35,19 @@ var _ = Describe("Fly CLI", func() {
|
|||
})
|
||||
|
||||
Describe("valid configuration", func() {
|
||||
var (
|
||||
flyrc string
|
||||
tmpDir string
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
var err error
|
||||
tmpDir, err = ioutil.TempDir("", "fly-test")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
os.Setenv("USERPROFILE", tmpDir)
|
||||
os.Setenv("HOMEPATH", strings.TrimPrefix(tmpDir, os.Getenv("HOMEDRIVE")))
|
||||
} else {
|
||||
os.Setenv("HOME", tmpDir)
|
||||
}
|
||||
|
||||
flyrc = filepath.Join(userHomeDir(), ".flyrc")
|
||||
|
||||
flyFixtureFile, err := os.OpenFile("./fixtures/flyrc.yml", os.O_RDONLY, 0600)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
flyFixtureData, err := ioutil.ReadAll(flyFixtureFile)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = ioutil.WriteFile(flyrc, flyFixtureData, 0600)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
createFlyRc(rc.Targets{
|
||||
"test1": {
|
||||
API: "https://example.com/test1",
|
||||
TeamName: "main",
|
||||
Token: &rc.TargetToken{Type: "Bearer", Value: validAccessToken(date(2020, 1, 1))},
|
||||
},
|
||||
"test2": {
|
||||
API: "https://example.com/test2",
|
||||
TeamName: "main",
|
||||
Token: &rc.TargetToken{Type: "Bearer", Value: validAccessToken(date(2020, 1, 2))},
|
||||
},
|
||||
})
|
||||
|
||||
flyCmd := exec.Command(flyPath, "targets")
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
|
@ -81,21 +63,15 @@ var _ = Describe("Fly CLI", func() {
|
|||
{Contents: "expiry", Color: color.New(color.Bold)},
|
||||
},
|
||||
Data: []ui.TableRow{
|
||||
{{Contents: "another-test"}, {Contents: "https://example.com/another-test"}, {Contents: "test"}, {Contents: "Sat, 19 Mar 2016 01:54:30 UTC"}},
|
||||
{{Contents: "no-token"}, {Contents: "https://example.com/no-token"}, {Contents: "main"}, {Contents: "n/a"}},
|
||||
{{Contents: "omt"}, {Contents: "https://example.com/omt"}, {Contents: "main"}, {Contents: "Mon, 21 Mar 2016 01:54:30 UTC"}},
|
||||
{{Contents: "test"}, {Contents: "https://example.com/test"}, {Contents: "test"}, {Contents: "Fri, 25 Mar 2016 23:29:57 UTC"}},
|
||||
{{Contents: "test1"}, {Contents: "https://example.com/test1"}, {Contents: "main"}, {Contents: "Wed, 01 Jan 2020 00:00:00 UTC"}},
|
||||
{{Contents: "test2"}, {Contents: "https://example.com/test2"}, {Contents: "main"}, {Contents: "Thu, 02 Jan 2020 00:00:00 UTC"}},
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
os.RemoveAll(tmpDir)
|
||||
})
|
||||
|
||||
Context("when url configuration is specified", func() {
|
||||
It("should update url field of target", func() {
|
||||
flyCmd = exec.Command(flyPath, "-t", "test", "edit-target", "--concourse-url", "new-url")
|
||||
flyCmd = exec.Command(flyPath, "-t", "test1", "edit-target", "--concourse-url", "new-url")
|
||||
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
@ -103,7 +79,7 @@ var _ = Describe("Fly CLI", func() {
|
|||
<-sess.Exited
|
||||
Expect(sess.ExitCode()).To(Equal(0))
|
||||
|
||||
Expect(sess.Out).To(gbytes.Say(`Updated target: test`))
|
||||
Expect(sess.Out).To(gbytes.Say(`Updated target: test1`))
|
||||
|
||||
flyCmd = exec.Command(flyPath, "targets")
|
||||
sess, err = gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
|
@ -118,10 +94,8 @@ var _ = Describe("Fly CLI", func() {
|
|||
{Contents: "expiry", Color: color.New(color.Bold)},
|
||||
},
|
||||
Data: []ui.TableRow{
|
||||
{{Contents: "another-test"}, {Contents: "https://example.com/another-test"}, {Contents: "test"}, {Contents: "Sat, 19 Mar 2016 01:54:30 UTC"}},
|
||||
{{Contents: "no-token"}, {Contents: "https://example.com/no-token"}, {Contents: "main"}, {Contents: "n/a"}},
|
||||
{{Contents: "omt"}, {Contents: "https://example.com/omt"}, {Contents: "main"}, {Contents: "Mon, 21 Mar 2016 01:54:30 UTC"}},
|
||||
{{Contents: "test"}, {Contents: "new-url"}, {Contents: "test"}, {Contents: "Fri, 25 Mar 2016 23:29:57 UTC"}},
|
||||
{{Contents: "test1"}, {Contents: "new-url"}, {Contents: "main"}, {Contents: "Wed, 01 Jan 2020 00:00:00 UTC"}},
|
||||
{{Contents: "test2"}, {Contents: "https://example.com/test2"}, {Contents: "main"}, {Contents: "Thu, 02 Jan 2020 00:00:00 UTC"}},
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
@ -129,7 +103,7 @@ var _ = Describe("Fly CLI", func() {
|
|||
|
||||
Context("when team name configuration is specified", func() {
|
||||
It("should update team name of target", func() {
|
||||
flyCmd = exec.Command(flyPath, "-t", "omt", "edit-target", "--team-name", "new-team")
|
||||
flyCmd = exec.Command(flyPath, "-t", "test2", "edit-target", "--team-name", "new-team")
|
||||
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
@ -137,7 +111,7 @@ var _ = Describe("Fly CLI", func() {
|
|||
<-sess.Exited
|
||||
Expect(sess.ExitCode()).To(Equal(0))
|
||||
|
||||
Expect(sess.Out).To(gbytes.Say(`Updated target: omt`))
|
||||
Expect(sess.Out).To(gbytes.Say(`Updated target: test2`))
|
||||
|
||||
flyCmd = exec.Command(flyPath, "targets")
|
||||
sess, err = gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
|
@ -152,10 +126,8 @@ var _ = Describe("Fly CLI", func() {
|
|||
{Contents: "expiry", Color: color.New(color.Bold)},
|
||||
},
|
||||
Data: []ui.TableRow{
|
||||
{{Contents: "another-test"}, {Contents: "https://example.com/another-test"}, {Contents: "test"}, {Contents: "Sat, 19 Mar 2016 01:54:30 UTC"}},
|
||||
{{Contents: "no-token"}, {Contents: "https://example.com/no-token"}, {Contents: "main"}, {Contents: "n/a"}},
|
||||
{{Contents: "omt"}, {Contents: "https://example.com/omt"}, {Contents: "new-team"}, {Contents: "Mon, 21 Mar 2016 01:54:30 UTC"}},
|
||||
{{Contents: "test"}, {Contents: "https://example.com/test"}, {Contents: "test"}, {Contents: "Fri, 25 Mar 2016 23:29:57 UTC"}},
|
||||
{{Contents: "test1"}, {Contents: "https://example.com/test1"}, {Contents: "main"}, {Contents: "Wed, 01 Jan 2020 00:00:00 UTC"}},
|
||||
{{Contents: "test2"}, {Contents: "https://example.com/test2"}, {Contents: "new-team"}, {Contents: "Thu, 02 Jan 2020 00:00:00 UTC"}},
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
@ -163,7 +135,7 @@ var _ = Describe("Fly CLI", func() {
|
|||
|
||||
Context("when target name configuration is specified", func() {
|
||||
It("should update the target name", func() {
|
||||
flyCmd = exec.Command(flyPath, "-t", "another-test", "edit-target", "--target-name", "and-another-test")
|
||||
flyCmd = exec.Command(flyPath, "-t", "test2", "edit-target", "--target-name", "new-target")
|
||||
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
@ -171,7 +143,7 @@ var _ = Describe("Fly CLI", func() {
|
|||
<-sess.Exited
|
||||
Expect(sess.ExitCode()).To(Equal(0))
|
||||
|
||||
Expect(sess.Out).To(gbytes.Say(`Updated target: another-test`))
|
||||
Expect(sess.Out).To(gbytes.Say(`Updated target: test2`))
|
||||
|
||||
flyCmd = exec.Command(flyPath, "targets")
|
||||
sess, err = gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
|
@ -186,10 +158,8 @@ var _ = Describe("Fly CLI", func() {
|
|||
{Contents: "expiry", Color: color.New(color.Bold)},
|
||||
},
|
||||
Data: []ui.TableRow{
|
||||
{{Contents: "and-another-test"}, {Contents: "https://example.com/another-test"}, {Contents: "test"}, {Contents: "Sat, 19 Mar 2016 01:54:30 UTC"}},
|
||||
{{Contents: "no-token"}, {Contents: "https://example.com/no-token"}, {Contents: "main"}, {Contents: "n/a"}},
|
||||
{{Contents: "omt"}, {Contents: "https://example.com/omt"}, {Contents: "main"}, {Contents: "Mon, 21 Mar 2016 01:54:30 UTC"}},
|
||||
{{Contents: "test"}, {Contents: "https://example.com/test"}, {Contents: "test"}, {Contents: "Fri, 25 Mar 2016 23:29:57 UTC"}},
|
||||
{{Contents: "new-target"}, {Contents: "https://example.com/test2"}, {Contents: "main"}, {Contents: "Thu, 02 Jan 2020 00:00:00 UTC"}},
|
||||
{{Contents: "test1"}, {Contents: "https://example.com/test1"}, {Contents: "main"}, {Contents: "Wed, 01 Jan 2020 00:00:00 UTC"}},
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
targets:
|
||||
test:
|
||||
api: https://example.com/test
|
||||
team: test
|
||||
token:
|
||||
type: Bearer
|
||||
value: banana
|
|
@ -1,20 +0,0 @@
|
|||
targets:
|
||||
test:
|
||||
api: https://example.com/test
|
||||
team: test
|
||||
token:
|
||||
type: Bearer
|
||||
value: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxNDU4OTQ4NTk3IiwiaXNBZG1pbiI6Im5vcGUiLCJ0ZWFtSUQiOjEsInRlYW1OYW1lIjoibWFpbiJ9.278HuhPsg5mU51ipDI2aVrhzIHfM-a8OcyQ5Us_0faw
|
||||
another-test:
|
||||
api: https://example.com/another-test
|
||||
team: test
|
||||
token:
|
||||
type: Bearer
|
||||
value: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxNDU4MzUyNDcwIiwiaXNBZG1pbiI6Im5vcGUiLCJ0ZWFtSUQiOjEsInRlYW1OYW1lIjoibWFpbiJ9.v04hbwIFdMNjp6BCpz2jvOYNpAeBY8pio6hlXQizLAM
|
||||
omt:
|
||||
api: https://example.com/omt
|
||||
token:
|
||||
type: Bearer
|
||||
value: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxNDU4NTI1MjcwIiwiaXNBZG1pbiI6Im5vcGUiLCJ0ZWFtSUQiOjEsInRlYW1OYW1lIjoibWFpbiJ9.W14O2X3HpAt0s_aYeQ-WXqdzFhSzbdW7G-twpPSkBOA
|
||||
no-token:
|
||||
api: https://example.com/no-token
|
|
@ -5,7 +5,6 @@ import (
|
|||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
. "github.com/onsi/ginkgo"
|
||||
|
@ -142,7 +141,6 @@ var _ = Describe("login -k Command", func() {
|
|||
|
||||
Context("with --ca-cert", func() {
|
||||
var (
|
||||
tmpDir string
|
||||
sslCert string
|
||||
)
|
||||
|
||||
|
@ -165,11 +163,6 @@ var _ = Describe("login -k Command", func() {
|
|||
tokenHandler(),
|
||||
userInfoHandler(),
|
||||
)
|
||||
|
||||
tmpDir, err = ioutil.TempDir("", "fly-test")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
os.Setenv("HOME", tmpDir)
|
||||
})
|
||||
|
||||
It("succeeds", func() {
|
||||
|
@ -195,15 +188,14 @@ var _ = Describe("login -k Command", func() {
|
|||
Context("to existing target with invalid SSL certificate", func() {
|
||||
Context("when 'insecure' is not set", func() {
|
||||
BeforeEach(func() {
|
||||
flyrcContents := `targets:
|
||||
some-target:
|
||||
api: ` + loginATCServer.URL() + `
|
||||
team: main
|
||||
ca_cert: some-ca-cert
|
||||
token:
|
||||
type: Bearer
|
||||
value: some-token`
|
||||
ioutil.WriteFile(homeDir+"/.flyrc", []byte(flyrcContents), 0777)
|
||||
createFlyRc(rc.Targets{
|
||||
"some-target": {
|
||||
API: loginATCServer.URL(),
|
||||
TeamName: "main",
|
||||
CACert: "some-ca-cert",
|
||||
Token: &rc.TargetToken{Type: "Bearer", Value: validAccessToken(date(2020, 1, 1))},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
Context("with -k", func() {
|
||||
|
|
|
@ -25,21 +25,8 @@ import (
|
|||
var _ = Describe("login Command", func() {
|
||||
var (
|
||||
loginATCServer *ghttp.Server
|
||||
tmpDir string
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
var err error
|
||||
tmpDir, err = ioutil.TempDir("", "fly-test")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
os.Setenv("HOME", tmpDir)
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
os.RemoveAll(tmpDir)
|
||||
})
|
||||
|
||||
Describe("login with no target name", func() {
|
||||
var (
|
||||
flyCmd *exec.Cmd
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
package integration_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/concourse/concourse/fly/rc"
|
||||
"github.com/concourse/concourse/fly/ui"
|
||||
"github.com/fatih/color"
|
||||
|
||||
|
@ -20,6 +16,40 @@ import (
|
|||
|
||||
var _ = Describe("logout Command", func() {
|
||||
|
||||
BeforeEach(func() {
|
||||
createFlyRc(rc.Targets{
|
||||
"test1": {
|
||||
API: "https://example.com/test1",
|
||||
TeamName: "main",
|
||||
Token: &rc.TargetToken{Type: "Bearer", Value: validAccessToken(date(2020, 1, 1))},
|
||||
},
|
||||
"test2": {
|
||||
API: "https://example.com/test2",
|
||||
TeamName: "main",
|
||||
Token: &rc.TargetToken{Type: "Bearer", Value: validAccessToken(date(2020, 1, 2))},
|
||||
},
|
||||
})
|
||||
|
||||
flyCmd := exec.Command(flyPath, "targets")
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Eventually(sess).Should(gexec.Exit(0))
|
||||
|
||||
Expect(sess.Out).To(PrintTable(ui.Table{
|
||||
Headers: ui.TableRow{
|
||||
{Contents: "name", Color: color.New(color.Bold)},
|
||||
{Contents: "url", Color: color.New(color.Bold)},
|
||||
{Contents: "team", Color: color.New(color.Bold)},
|
||||
{Contents: "expiry", Color: color.New(color.Bold)},
|
||||
},
|
||||
Data: []ui.TableRow{
|
||||
{{Contents: "test1"}, {Contents: "https://example.com/test1"}, {Contents: "main"}, {Contents: "Wed, 01 Jan 2020 00:00:00 UTC"}},
|
||||
{{Contents: "test2"}, {Contents: "https://example.com/test2"}, {Contents: "main"}, {Contents: "Thu, 02 Jan 2020 00:00:00 UTC"}},
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
||||
Describe("missing parameters", func() {
|
||||
Context("when validating parameters", func() {
|
||||
It("instructs the user to specify --target or --all if both are missing", func() {
|
||||
|
@ -49,147 +79,50 @@ var _ = Describe("logout Command", func() {
|
|||
})
|
||||
|
||||
Describe("delete all", func() {
|
||||
var (
|
||||
flyrc string
|
||||
tmpDir string
|
||||
)
|
||||
It("removes all tokens and all targets remain in flyrc", func() {
|
||||
flyCmd := exec.Command(flyPath, "logout", "--all")
|
||||
|
||||
BeforeEach(func() {
|
||||
var err error
|
||||
tmpDir, err = ioutil.TempDir("", "fly-test")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
os.Setenv("USERPROFILE", tmpDir)
|
||||
os.Setenv("HOMEPATH", strings.TrimPrefix(tmpDir, os.Getenv("HOMEDRIVE")))
|
||||
} else {
|
||||
os.Setenv("HOME", tmpDir)
|
||||
}
|
||||
|
||||
flyrc = filepath.Join(userHomeDir(), ".flyrc")
|
||||
|
||||
flyFixtureFile, err := os.OpenFile("./fixtures/flyrc.yml", os.O_RDONLY, 0600)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
flyFixtureData, err := ioutil.ReadAll(flyFixtureFile)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = ioutil.WriteFile(flyrc, flyFixtureData, 0600)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
flyCmd := exec.Command(flyPath, "targets")
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Eventually(sess).Should(gexec.Exit(0))
|
||||
<-sess.Exited
|
||||
Expect(sess.ExitCode()).To(Equal(0))
|
||||
|
||||
Expect(sess.Out).To(gbytes.Say(`logged out of all targets`))
|
||||
|
||||
flyCmd = exec.Command(flyPath, "targets")
|
||||
sess, err = gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Eventually(sess).Should(gexec.Exit(0))
|
||||
Expect(sess.Out).To(PrintTable(ui.Table{
|
||||
Headers: ui.TableRow{
|
||||
{Contents: "name", Color: color.New(color.Bold)},
|
||||
{Contents: "url", Color: color.New(color.Bold)},
|
||||
{Contents: "team", Color: color.New(color.Bold)},
|
||||
{Contents: "expiry", Color: color.New(color.Bold)},
|
||||
},
|
||||
Data: []ui.TableRow{
|
||||
{{Contents: "another-test"}, {Contents: "https://example.com/another-test"}, {Contents: "test"}, {Contents: "Sat, 19 Mar 2016 01:54:30 UTC"}},
|
||||
{{Contents: "no-token"}, {Contents: "https://example.com/no-token"}, {Contents: "main"}, {Contents: "n/a"}},
|
||||
{{Contents: "omt"}, {Contents: "https://example.com/omt"}, {Contents: "main"}, {Contents: "Mon, 21 Mar 2016 01:54:30 UTC"}},
|
||||
{{Contents: "test"}, {Contents: "https://example.com/test"}, {Contents: "test"}, {Contents: "Fri, 25 Mar 2016 23:29:57 UTC"}},
|
||||
{{Contents: "test1"}, {Contents: "https://example.com/test1"}, {Contents: "main"}, {Contents: "n/a"}},
|
||||
{{Contents: "test2"}, {Contents: "https://example.com/test2"}, {Contents: "main"}, {Contents: "n/a"}},
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
os.RemoveAll(tmpDir)
|
||||
})
|
||||
|
||||
Context("when it is called", func() {
|
||||
It("removes all tokens and all targets remain in flyrc", func() {
|
||||
flyCmd := exec.Command(flyPath, "logout", "--all")
|
||||
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
<-sess.Exited
|
||||
Expect(sess.ExitCode()).To(Equal(0))
|
||||
|
||||
Expect(sess.Out).To(gbytes.Say(`logged out of all targets`))
|
||||
|
||||
flyCmd = exec.Command(flyPath, "targets")
|
||||
sess, err = gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Eventually(sess).Should(gexec.Exit(0))
|
||||
Expect(sess.Out).To(PrintTable(ui.Table{
|
||||
Headers: ui.TableRow{
|
||||
{Contents: "name", Color: color.New(color.Bold)},
|
||||
{Contents: "url", Color: color.New(color.Bold)},
|
||||
{Contents: "expiry", Color: color.New(color.Bold)},
|
||||
},
|
||||
Data: []ui.TableRow{
|
||||
{{Contents: "another-test"}, {Contents: "https://example.com/another-test"}, {Contents: "test"}, {Contents: "n/a"}},
|
||||
{{Contents: "no-token"}, {Contents: "https://example.com/no-token"}, {Contents: "main"}, {Contents: "n/a"}},
|
||||
{{Contents: "omt"}, {Contents: "https://example.com/omt"}, {Contents: "main"}, {Contents: "n/a"}},
|
||||
{{Contents: "test"}, {Contents: "https://example.com/test"}, {Contents: "test"}, {Contents: "n/a"}},
|
||||
},
|
||||
}))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Describe("delete one", func() {
|
||||
var (
|
||||
flyrc string
|
||||
tmpDir string
|
||||
)
|
||||
It("removes token of the target and the target should remain in .flyrc", func() {
|
||||
flyCmd := exec.Command(flyPath, "logout", "-t", "test2")
|
||||
|
||||
BeforeEach(func() {
|
||||
var err error
|
||||
tmpDir, err = ioutil.TempDir("", "fly-test")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
if runtime.GOOS == "windows" {
|
||||
os.Setenv("USERPROFILE", tmpDir)
|
||||
os.Setenv("HOMEPATH", strings.TrimPrefix(tmpDir, os.Getenv("HOMEDRIVE")))
|
||||
} else {
|
||||
os.Setenv("HOME", tmpDir)
|
||||
}
|
||||
|
||||
flyrc = filepath.Join(userHomeDir(), ".flyrc")
|
||||
|
||||
flyFixtureFile, err := os.OpenFile("./fixtures/flyrc.yml", os.O_RDONLY, 0600)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
flyFixtureData, err := ioutil.ReadAll(flyFixtureFile)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = ioutil.WriteFile(flyrc, flyFixtureData, 0600)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
flyCmd := exec.Command(flyPath, "targets")
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Eventually(sess).Should(gexec.Exit(0))
|
||||
<-sess.Exited
|
||||
Expect(sess.ExitCode()).To(Equal(0))
|
||||
|
||||
Expect(sess.Out).To(PrintTable(ui.Table{
|
||||
Headers: ui.TableRow{
|
||||
{Contents: "name", Color: color.New(color.Bold)},
|
||||
{Contents: "url", Color: color.New(color.Bold)},
|
||||
{Contents: "expiry", Color: color.New(color.Bold)},
|
||||
},
|
||||
Data: []ui.TableRow{
|
||||
{{Contents: "another-test"}, {Contents: "https://example.com/another-test"}, {Contents: "test"}, {Contents: "Sat, 19 Mar 2016 01:54:30 UTC"}},
|
||||
{{Contents: "no-token"}, {Contents: "https://example.com/no-token"}, {Contents: "main"}, {Contents: "n/a"}},
|
||||
{{Contents: "omt"}, {Contents: "https://example.com/omt"}, {Contents: "main"}, {Contents: "Mon, 21 Mar 2016 01:54:30 UTC"}},
|
||||
{{Contents: "test"}, {Contents: "https://example.com/test"}, {Contents: "test"}, {Contents: "Fri, 25 Mar 2016 23:29:57 UTC"}},
|
||||
},
|
||||
}))
|
||||
})
|
||||
Expect(sess.Out).To(gbytes.Say(`logged out of target: test2`))
|
||||
|
||||
AfterEach(func() {
|
||||
flyCmd := exec.Command(flyPath, "targets")
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
flyCmd = exec.Command(flyPath, "targets")
|
||||
sess, err = gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Eventually(sess).Should(gexec.Exit(0))
|
||||
|
@ -197,32 +130,13 @@ var _ = Describe("logout Command", func() {
|
|||
Headers: ui.TableRow{
|
||||
{Contents: "name", Color: color.New(color.Bold)},
|
||||
{Contents: "url", Color: color.New(color.Bold)},
|
||||
{Contents: "team", Color: color.New(color.Bold)},
|
||||
{Contents: "expiry", Color: color.New(color.Bold)},
|
||||
},
|
||||
Data: []ui.TableRow{
|
||||
{{Contents: "another-test"}, {Contents: "https://example.com/another-test"}, {Contents: "test"}, {Contents: "Sat, 19 Mar 2016 01:54:30 UTC"}},
|
||||
{{Contents: "no-token"}, {Contents: "https://example.com/no-token"}, {Contents: "main"}, {Contents: "n/a"}},
|
||||
{{Contents: "omt"}, {Contents: "https://example.com/omt"}, {Contents: "main"}, {Contents: "n/a"}},
|
||||
{{Contents: "test"}, {Contents: "https://example.com/test"}, {Contents: "test"}, {Contents: "Fri, 25 Mar 2016 23:29:57 UTC"}},
|
||||
{{Contents: "test1"}, {Contents: "https://example.com/test1"}, {Contents: "main"}, {Contents: "Wed, 01 Jan 2020 00:00:00 UTC"}},
|
||||
{{Contents: "test2"}, {Contents: "https://example.com/test2"}, {Contents: "main"}, {Contents: "n/a"}},
|
||||
},
|
||||
}))
|
||||
|
||||
os.RemoveAll(tmpDir)
|
||||
})
|
||||
|
||||
Context("when it is called", func() {
|
||||
It("removes token of the target and the target should remain in .flyrc", func() {
|
||||
flyCmd := exec.Command(flyPath, "logout", "-t", "omt")
|
||||
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
<-sess.Exited
|
||||
Expect(sess.ExitCode()).To(Equal(0))
|
||||
|
||||
Expect(sess.Out).To(gbytes.Say(`logged out of target: omt`))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
package integration_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"net/http"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/concourse/concourse/fly/rc"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/onsi/gomega/gbytes"
|
||||
|
@ -15,56 +14,22 @@ import (
|
|||
|
||||
var _ = Describe("status Command", func() {
|
||||
var (
|
||||
tmpDir string
|
||||
flyrc string
|
||||
flyCmd *exec.Cmd
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
var err error
|
||||
tmpDir, err = ioutil.TempDir("", "fly-test")
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
|
||||
os.Setenv("HOME", tmpDir)
|
||||
flyrc = filepath.Join(userHomeDir(), ".flyrc")
|
||||
|
||||
flyFixtureData := []byte(`
|
||||
targets:
|
||||
another-test:
|
||||
api: ` + atcServer.URL() + `
|
||||
team: test
|
||||
token:
|
||||
type: Bearer
|
||||
value: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOiIxNDU4MzUyNDcwIiwiaXNBZG1pbiI6Im5vcGUiLCJ0ZWFtSUQiOjEsInRlYW1OYW1lIjoibWFpbiJ9.v04hbwIFdMNjp6BCpz2jvOYNpAeBY8pio6hlXQizLAM
|
||||
bad-test:
|
||||
api: https://example.com/another-test
|
||||
team: test
|
||||
token:
|
||||
type: Bearer
|
||||
value: bad-token
|
||||
loggedout-test:
|
||||
api: https://example.com/loggedout-test
|
||||
team: test
|
||||
token:
|
||||
type: ""
|
||||
value: ""
|
||||
invalid-test:
|
||||
api: https://example.com/invalid-test
|
||||
team: test
|
||||
token:
|
||||
expired-test:
|
||||
api: https://example.com/expired-test
|
||||
team: test
|
||||
token:
|
||||
type: Bearer
|
||||
value: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJjc3JmIjoiNGZlOGM1Y2VhYjFjNWFiMzE5MzMzNmQ2YThkOTE3OTJmZTA0YmEzZjg5Y2IwZDg0MTkzN2I2MzkzYTdhYTg2MyIsImV4cCI6MTUyMTMwODk2MCwiaXNBZG1pbiI6dHJ1ZSwidGVhbU5hbWUiOiJtYWluIn0.oyb-2CPLnXy-7S-9FWWlx106KI5Xpd6B5XIrFOvcG1yyh5nrGpM4NfgaW7ugN4zzi2mSFGawRlkulzgAZ4RxAEdTOnlSXvVZO3vD70sMlrp_LX-lYaqJ7XXVXNKvKE_74YGZY414TYVy2IxL-4Qf7pbb0uGDky03jQFxkWVSUiD5iLwaqpvxpHTEuVNoZc9a8YNiOdETvqnt50drsmxpkblM60DrWuDVPifOfTrooSMxULnl3pYXDsTPZbrc6QVLA_Hpi7wWCNEZbAojTQ3taIwzp7BBAuxUNcVMpJKy3Um5oMHcibe1R0PsZ0J49PbLSclZfhJ7wjHBc7FQEKTZzQ
|
||||
`)
|
||||
|
||||
err = ioutil.WriteFile(flyrc, flyFixtureData, 0600)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
os.RemoveAll(tmpDir)
|
||||
createFlyRc(rc.Targets{
|
||||
"with-token": {
|
||||
API: atcServer.URL(),
|
||||
TeamName: "test",
|
||||
Token: &rc.TargetToken{Type: "Bearer", Value: validAccessToken(date(2020, 1, 1))},
|
||||
},
|
||||
"without-token": {
|
||||
API: "https://example.com/another-test",
|
||||
TeamName: "test",
|
||||
Token: &rc.TargetToken{},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
Context("status with no target name", func() {
|
||||
|
@ -98,8 +63,8 @@ targets:
|
|||
)
|
||||
})
|
||||
|
||||
It("command exist with 0", func() {
|
||||
flyCmd = exec.Command(flyPath, "-t", "another-test", "status")
|
||||
It("the command succeeds", func() {
|
||||
flyCmd = exec.Command(flyPath, "-t", "with-token", "status")
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
|
@ -110,19 +75,19 @@ targets:
|
|||
})
|
||||
})
|
||||
|
||||
Context("when target is saved with valid token but is unauthorized on server", func() {
|
||||
Context("when target is saved with a token that is rejected by the server", func() {
|
||||
BeforeEach(func() {
|
||||
atcServer.Reset()
|
||||
atcServer.AppendHandlers(
|
||||
ghttp.CombineHandlers(
|
||||
ghttp.VerifyRequest("GET", "/api/v1/user"),
|
||||
ghttp.RespondWith(401, nil),
|
||||
ghttp.RespondWith(http.StatusUnauthorized, nil),
|
||||
),
|
||||
)
|
||||
})
|
||||
|
||||
It("command exist with 1", func() {
|
||||
flyCmd = exec.Command(flyPath, "-t", "another-test", "status")
|
||||
It("the command fails", func() {
|
||||
flyCmd = exec.Command(flyPath, "-t", "with-token", "status")
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
|
@ -130,73 +95,21 @@ targets:
|
|||
Expect(sess.ExitCode()).To(Equal(1))
|
||||
|
||||
Expect(sess.Err).To(gbytes.Say(`please login again`))
|
||||
Expect(sess.Err).To(gbytes.Say(`token validation failed with error : not authorized`))
|
||||
Expect(sess.Err).To(gbytes.Say(`token validation failed with error: not authorized`))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when target is saved with invalid token", func() {
|
||||
It("command exist with 1", func() {
|
||||
flyCmd = exec.Command(flyPath, "-t", "bad-test", "status")
|
||||
It("the command fails", func() {
|
||||
flyCmd = exec.Command(flyPath, "-t", "without-token", "status")
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
<-sess.Exited
|
||||
Expect(sess.ExitCode()).To(Equal(1))
|
||||
|
||||
Expect(sess.Err).To(gbytes.Say(`please login again`))
|
||||
Expect(sess.Err).To(gbytes.Say(`token validation failed with error : token contains an invalid number of segments`))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when target is saved with expired token", func() {
|
||||
It("command exist with 1", func() {
|
||||
flyCmd = exec.Command(flyPath, "-t", "expired-test", "status")
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
<-sess.Exited
|
||||
Expect(sess.ExitCode()).To(Equal(1))
|
||||
|
||||
Expect(sess.Err).To(gbytes.Say(`please login again`))
|
||||
Expect(sess.Err).To(gbytes.Say(`token validation failed with error : Token is expired`))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when target is logged out", func() {
|
||||
It("command exist with 1 and log out msg", func() {
|
||||
flyCmd = exec.Command(flyPath, "-t", "loggedout-test", "status")
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
<-sess.Exited
|
||||
Expect(sess.ExitCode()).To(Equal(1))
|
||||
Expect(sess.Err).To(gbytes.Say(`logged out`))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when invalid token is in target", func() {
|
||||
It("command exist with 1", func() {
|
||||
flyCmd = exec.Command(flyPath, "-t", "invalid-test", "status")
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
<-sess.Exited
|
||||
Expect(sess.ExitCode()).To(Equal(1))
|
||||
Expect(sess.Err).To(gbytes.Say(`logged out`))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when unknown target is used", func() {
|
||||
It("command exist with 1", func() {
|
||||
flyCmd = exec.Command(flyPath, "-t", "unknown-test", "status")
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
<-sess.Exited
|
||||
Expect(sess.ExitCode()).To(Equal(1))
|
||||
|
||||
Expect(sess.Err).To(gbytes.Say(`unknown target: unknown-test`))
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,21 +1,27 @@
|
|||
package integration_test
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/concourse/concourse/atc"
|
||||
"github.com/concourse/concourse/atc/db"
|
||||
"github.com/concourse/concourse/fly/rc"
|
||||
"github.com/concourse/concourse/skymarshal/token"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/onsi/gomega/gexec"
|
||||
"github.com/onsi/gomega/ghttp"
|
||||
"gopkg.in/square/go-jose.v2/jwt"
|
||||
)
|
||||
|
||||
var flyPath string
|
||||
|
@ -67,7 +73,7 @@ func tokenHandler() http.HandlerFunc {
|
|||
ghttp.VerifyRequest("POST", "/sky/issuer/token"),
|
||||
ghttp.RespondWithJSONEncoded(
|
||||
200,
|
||||
token(),
|
||||
oauthToken(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
@ -86,14 +92,42 @@ func userInfoHandler() http.HandlerFunc {
|
|||
)
|
||||
}
|
||||
|
||||
func token() map[string]string {
|
||||
func validAccessToken(expiry time.Time) string {
|
||||
accessToken, err := token.Factory{}.GenerateAccessToken(db.Claims{
|
||||
Claims: jwt.Claims{Expiry: jwt.NewNumericDate(expiry)}},
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return accessToken
|
||||
}
|
||||
|
||||
func oauthToken() map[string]string {
|
||||
return map[string]string{
|
||||
"token_type": "Bearer",
|
||||
"access_token": "some-access-token",
|
||||
"access_token": validAccessToken(time.Now()),
|
||||
"id_token": "some-token",
|
||||
}
|
||||
}
|
||||
|
||||
func date(year int, month time.Month, day int) time.Time {
|
||||
return time.Date(year, month, day, 0, 0, 0, 0, time.UTC)
|
||||
}
|
||||
|
||||
func createFlyRc(targets rc.Targets) {
|
||||
flyrc := filepath.Join(homeDir, ".flyrc")
|
||||
|
||||
flyrcBytes, err := json.Marshal(rc.RC{Targets: targets})
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(flyrc, flyrcBytes, 0600)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
var _ = BeforeEach(func() {
|
||||
atcServer = ghttp.NewServer()
|
||||
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
package integration_test
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/concourse/concourse/fly/rc"
|
||||
"github.com/concourse/concourse/fly/ui"
|
||||
"github.com/fatih/color"
|
||||
"github.com/onsi/gomega/gbytes"
|
||||
|
@ -17,38 +15,39 @@ import (
|
|||
|
||||
var _ = Describe("Fly CLI", func() {
|
||||
var (
|
||||
flyCmd *exec.Cmd
|
||||
flyrc string
|
||||
tmpDir string
|
||||
flyrcFixture string
|
||||
flyCmd *exec.Cmd
|
||||
targets rc.Targets
|
||||
)
|
||||
|
||||
JustBeforeEach(func() {
|
||||
var err error
|
||||
tmpDir, err = ioutil.TempDir("", "fly-test")
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
os.Setenv("HOME", tmpDir)
|
||||
flyrc = filepath.Join(userHomeDir(), ".flyrc")
|
||||
|
||||
flyFixtureFile, err := os.OpenFile(flyrcFixture, os.O_RDONLY, 0600)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
flyFixtureData, err := ioutil.ReadAll(flyFixtureFile)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
err = ioutil.WriteFile(flyrc, flyFixtureData, 0600)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
createFlyRc(targets)
|
||||
|
||||
flyCmd = exec.Command(flyPath, "targets")
|
||||
})
|
||||
|
||||
BeforeEach(func() {
|
||||
flyrcFixture = "./fixtures/flyrc.yml"
|
||||
})
|
||||
|
||||
AfterEach(func() {
|
||||
os.RemoveAll(tmpDir)
|
||||
targets = rc.Targets{
|
||||
"another-test": {
|
||||
API: "https://example.com/another-test",
|
||||
TeamName: "test",
|
||||
Token: &rc.TargetToken{Type: "Bearer", Value: validAccessToken(date(2020, 1, 1))},
|
||||
},
|
||||
"no-token": {
|
||||
API: "https://example.com/no-token",
|
||||
TeamName: "main",
|
||||
Token: nil,
|
||||
},
|
||||
"omt": {
|
||||
API: "https://example.com/omt",
|
||||
TeamName: "main",
|
||||
Token: &rc.TargetToken{Type: "Bearer", Value: validAccessToken(date(2020, 1, 2))},
|
||||
},
|
||||
"test": {
|
||||
API: "https://example.com/test",
|
||||
TeamName: "test",
|
||||
Token: &rc.TargetToken{Type: "Bearer", Value: validAccessToken(date(2020, 1, 3))},
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
Describe("targets", func() {
|
||||
|
@ -67,10 +66,10 @@ var _ = Describe("Fly CLI", func() {
|
|||
{Contents: "expiry", Color: color.New(color.Bold)},
|
||||
},
|
||||
Data: []ui.TableRow{
|
||||
{{Contents: "another-test"}, {Contents: "https://example.com/another-test"}, {Contents: "test"}, {Contents: "Sat, 19 Mar 2016 01:54:30 UTC"}},
|
||||
{{Contents: "another-test"}, {Contents: "https://example.com/another-test"}, {Contents: "test"}, {Contents: "Wed, 01 Jan 2020 00:00:00 UTC"}},
|
||||
{{Contents: "no-token"}, {Contents: "https://example.com/no-token"}, {Contents: "main"}, {Contents: "n/a"}},
|
||||
{{Contents: "omt"}, {Contents: "https://example.com/omt"}, {Contents: "main"}, {Contents: "Mon, 21 Mar 2016 01:54:30 UTC"}},
|
||||
{{Contents: "test"}, {Contents: "https://example.com/test"}, {Contents: "test"}, {Contents: "Fri, 25 Mar 2016 23:29:57 UTC"}},
|
||||
{{Contents: "omt"}, {Contents: "https://example.com/omt"}, {Contents: "main"}, {Contents: "Thu, 02 Jan 2020 00:00:00 UTC"}},
|
||||
{{Contents: "test"}, {Contents: "https://example.com/test"}, {Contents: "test"}, {Contents: "Fri, 03 Jan 2020 00:00:00 UTC"}},
|
||||
},
|
||||
}))
|
||||
})
|
||||
|
@ -78,22 +77,27 @@ var _ = Describe("Fly CLI", func() {
|
|||
|
||||
Context("when the .flyrc contains a target with an invalid token", func() {
|
||||
BeforeEach(func() {
|
||||
flyrcFixture = "./fixtures/flyrc-badtoken.yml"
|
||||
targets = rc.Targets{
|
||||
"test": {
|
||||
API: "https://example.com/test",
|
||||
Token: &rc.TargetToken{Type: "Bearer", Value: "banana"},
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
It("shows error message from jwt parsing library but does not fail", func() {
|
||||
It("indicates the token is invalid", func() {
|
||||
sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
|
||||
Expect(err).NotTo(HaveOccurred())
|
||||
|
||||
Eventually(sess).Should(gexec.Exit(0))
|
||||
|
||||
Expect(sess).Should(gbytes.Say("n/a: token contains an invalid number of segments"))
|
||||
Expect(sess).Should(gbytes.Say("n/a: invalid token"))
|
||||
})
|
||||
})
|
||||
|
||||
Context("when no targets are available", func() {
|
||||
BeforeEach(func() {
|
||||
os.RemoveAll(flyrc)
|
||||
createFlyRc(nil)
|
||||
})
|
||||
|
||||
It("prints an empty table", func() {
|
||||
|
|
|
@ -101,7 +101,7 @@ func LoadTargetFromURL(url, team string, tracing bool) (Target, TargetName, erro
|
|||
return nil, "", err
|
||||
}
|
||||
|
||||
for name, props := range flyTargets.Targets {
|
||||
for name, props := range flyTargets {
|
||||
if props.API == url && props.TeamName == team {
|
||||
target, err := LoadTarget(name, tracing)
|
||||
return target, name, err
|
||||
|
|
|
@ -21,7 +21,7 @@ func (name *TargetName) Complete(match string) []flags.Completion {
|
|||
}
|
||||
|
||||
names := []string{}
|
||||
for name := range flyTargets.Targets {
|
||||
for name := range flyTargets {
|
||||
if strings.HasPrefix(string(name), match) {
|
||||
names = append(names, string(name))
|
||||
}
|
||||
|
|
|
@ -26,6 +26,12 @@ func (err UnknownTargetError) Error() string {
|
|||
return fmt.Sprintf("unknown target: %s", err.TargetName)
|
||||
}
|
||||
|
||||
type Targets map[TargetName]TargetProps
|
||||
|
||||
type RC struct {
|
||||
Targets Targets `json:"targets"`
|
||||
}
|
||||
|
||||
type TargetProps struct {
|
||||
API string `json:"api"`
|
||||
TeamName string `json:"team"`
|
||||
|
@ -39,10 +45,6 @@ type TargetToken struct {
|
|||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
type targetDetailsYAML struct {
|
||||
Targets map[TargetName]TargetProps `json:"targets"`
|
||||
}
|
||||
|
||||
func flyrcPath() string {
|
||||
return filepath.Join(userHomeDir(), ".flyrc")
|
||||
}
|
||||
|
@ -53,7 +55,7 @@ func LogoutTarget(targetName TargetName) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if target, ok := flyTargets.Targets[targetName]; ok {
|
||||
if target, ok := flyTargets[targetName]; ok {
|
||||
if target.Token != nil {
|
||||
*target.Token = TargetToken{}
|
||||
}
|
||||
|
@ -68,13 +70,13 @@ func DeleteTarget(targetName TargetName) error {
|
|||
return err
|
||||
}
|
||||
|
||||
delete(flyTargets.Targets, targetName)
|
||||
delete(flyTargets, targetName)
|
||||
|
||||
return writeTargets(flyrcPath(), flyTargets)
|
||||
}
|
||||
|
||||
func DeleteAllTargets() error {
|
||||
return writeTargets(flyrcPath(), &targetDetailsYAML{})
|
||||
return writeTargets(flyrcPath(), Targets{})
|
||||
}
|
||||
|
||||
func UpdateTargetProps(targetName TargetName, targetProps TargetProps) error {
|
||||
|
@ -83,7 +85,7 @@ func UpdateTargetProps(targetName TargetName, targetProps TargetProps) error {
|
|||
return err
|
||||
}
|
||||
|
||||
target := flyTargets.Targets[targetName]
|
||||
target := flyTargets[targetName]
|
||||
|
||||
if targetProps.API != "" {
|
||||
target.API = targetProps.API
|
||||
|
@ -93,7 +95,7 @@ func UpdateTargetProps(targetName TargetName, targetProps TargetProps) error {
|
|||
target.TeamName = targetProps.TeamName
|
||||
}
|
||||
|
||||
flyTargets.Targets[targetName] = target
|
||||
flyTargets[targetName] = target
|
||||
|
||||
return writeTargets(flyrcPath(), flyTargets)
|
||||
}
|
||||
|
@ -105,8 +107,8 @@ func UpdateTargetName(targetName TargetName, newTargetName TargetName) error {
|
|||
}
|
||||
|
||||
if newTargetName != "" {
|
||||
flyTargets.Targets[newTargetName] = flyTargets.Targets[targetName]
|
||||
delete(flyTargets.Targets, targetName)
|
||||
flyTargets[newTargetName] = flyTargets[targetName]
|
||||
delete(flyTargets, targetName)
|
||||
}
|
||||
|
||||
return writeTargets(flyrcPath(), flyTargets)
|
||||
|
@ -126,14 +128,14 @@ func SaveTarget(
|
|||
}
|
||||
|
||||
flyrc := flyrcPath()
|
||||
newInfo := flyTargets.Targets[targetName]
|
||||
newInfo := flyTargets[targetName]
|
||||
newInfo.API = api
|
||||
newInfo.Insecure = insecure
|
||||
newInfo.Token = token
|
||||
newInfo.TeamName = teamName
|
||||
newInfo.CACert = caCert
|
||||
|
||||
flyTargets.Targets[targetName] = newInfo
|
||||
flyTargets[targetName] = newInfo
|
||||
return writeTargets(flyrc, flyTargets)
|
||||
}
|
||||
|
||||
|
@ -146,7 +148,7 @@ func selectTarget(selectedTarget TargetName) (TargetProps, error) {
|
|||
return TargetProps{}, err
|
||||
}
|
||||
|
||||
target, ok := flyTargets.Targets[selectedTarget]
|
||||
target, ok := flyTargets[selectedTarget]
|
||||
if !ok {
|
||||
return TargetProps{}, UnknownTargetError{selectedTarget}
|
||||
}
|
||||
|
@ -174,8 +176,8 @@ func userHomeDir() string {
|
|||
panic("could not detect home directory for .flyrc")
|
||||
}
|
||||
|
||||
func LoadTargets() (*targetDetailsYAML, error) {
|
||||
var flyTargets targetDetailsYAML
|
||||
func LoadTargets() (Targets, error) {
|
||||
var rc RC
|
||||
|
||||
flyrc := flyrcPath()
|
||||
if _, err := os.Stat(flyrc); err == nil {
|
||||
|
@ -183,28 +185,29 @@ func LoadTargets() (*targetDetailsYAML, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = yaml.Unmarshal(flyTargetsBytes, &flyTargets)
|
||||
err = yaml.Unmarshal(flyTargetsBytes, &rc)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("in the file '%s': %s", flyrc, err)
|
||||
}
|
||||
}
|
||||
|
||||
if flyTargets.Targets == nil {
|
||||
flyTargets.Targets = map[TargetName]TargetProps{}
|
||||
targets := rc.Targets
|
||||
if targets == nil {
|
||||
targets = map[TargetName]TargetProps{}
|
||||
}
|
||||
|
||||
for name, targetProps := range flyTargets.Targets {
|
||||
for name, targetProps := range targets {
|
||||
if targetProps.TeamName == "" {
|
||||
targetProps.TeamName = atc.DefaultTeamName
|
||||
flyTargets.Targets[name] = targetProps
|
||||
targets[name] = targetProps
|
||||
}
|
||||
}
|
||||
|
||||
return &flyTargets, nil
|
||||
return targets, nil
|
||||
}
|
||||
|
||||
func writeTargets(configFileLocation string, targetsToWrite *targetDetailsYAML) error {
|
||||
yamlBytes, err := yaml.Marshal(targetsToWrite)
|
||||
func writeTargets(configFileLocation string, targetsToWrite Targets) error {
|
||||
yamlBytes, err := yaml.Marshal(RC{Targets: targetsToWrite})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ var _ = Describe("Targets", func() {
|
|||
It("loads target with default team", func() {
|
||||
targets, err := rc.LoadTargets()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(targets.Targets).To(Equal(map[rc.TargetName]rc.TargetProps{
|
||||
Expect(targets).To(Equal(rc.Targets{
|
||||
"some-target": {
|
||||
API: "http://concourse.com",
|
||||
TeamName: atc.DefaultTeamName,
|
||||
|
@ -85,7 +85,7 @@ var _ = Describe("Targets", func() {
|
|||
It("should delete target from flyrc", func() {
|
||||
returnedTargets, err := rc.LoadTargets()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(returnedTargets.Targets).To(Equal(map[rc.TargetName]rc.TargetProps{
|
||||
Expect(returnedTargets).To(Equal(rc.Targets{
|
||||
"new-target": {
|
||||
API: "some-api",
|
||||
TeamName: "another-team",
|
||||
|
@ -106,7 +106,7 @@ var _ = Describe("Targets", func() {
|
|||
It("should delete all targets from flyrc", func() {
|
||||
returnedTargets, err := rc.LoadTargets()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(returnedTargets.Targets).To(Equal(map[rc.TargetName]rc.TargetProps{}))
|
||||
Expect(returnedTargets).To(Equal(rc.Targets{}))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -134,7 +134,7 @@ var _ = Describe("Targets", func() {
|
|||
|
||||
targets, err := rc.LoadTargets()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(targets.Targets).To(Equal(map[rc.TargetName]rc.TargetProps{
|
||||
Expect(targets).To(Equal(rc.Targets{
|
||||
"some-target": {
|
||||
API: "new-api",
|
||||
TeamName: "other-team",
|
||||
|
@ -154,7 +154,7 @@ var _ = Describe("Targets", func() {
|
|||
|
||||
targets, err := rc.LoadTargets()
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(targets.Targets).To(Equal(map[rc.TargetName]rc.TargetProps{
|
||||
Expect(targets).To(Equal(rc.Targets{
|
||||
"some-other-target": {
|
||||
API: "http://concourse.com",
|
||||
TeamName: "main",
|
||||
|
|
|
@ -128,6 +128,7 @@ func (client *client) FindTeam(teamName string) (Team, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
switch resp.StatusCode {
|
||||
case http.StatusOK:
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package concourse
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
"github.com/concourse/concourse/atc"
|
||||
|
@ -8,17 +10,31 @@ import (
|
|||
)
|
||||
|
||||
func (client *client) UserInfo() (atc.UserInfo, error) {
|
||||
var connection = client.connection
|
||||
resp, err := client.httpAgent.Send(internal.Request{
|
||||
RequestName: atc.GetUser,
|
||||
})
|
||||
|
||||
req, err := http.NewRequest("GET", connection.URL()+"/api/v1/user", nil)
|
||||
if err != nil {
|
||||
return atc.UserInfo{}, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var userInfo atc.UserInfo
|
||||
err = connection.SendHTTPRequest(req, false, &internal.Response{
|
||||
Result: &userInfo,
|
||||
})
|
||||
|
||||
return userInfo, err
|
||||
switch resp.StatusCode {
|
||||
case http.StatusOK:
|
||||
var userInfo atc.UserInfo
|
||||
err = json.NewDecoder(resp.Body).Decode(&userInfo)
|
||||
if err != nil {
|
||||
return atc.UserInfo{}, err
|
||||
}
|
||||
return userInfo, nil
|
||||
case http.StatusUnauthorized:
|
||||
return atc.UserInfo{}, ErrUnauthorized
|
||||
default:
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
return atc.UserInfo{}, internal.UnexpectedResponseError{
|
||||
StatusCode: resp.StatusCode,
|
||||
Status: resp.Status,
|
||||
Body: string(body),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
1
go.mod
1
go.mod
|
@ -36,7 +36,6 @@ require (
|
|||
github.com/cppforlife/go-semi-semantic v0.0.0-20160921010311-576b6af77ae4
|
||||
github.com/creack/pty v1.1.9 // indirect
|
||||
github.com/cyberark/conjur-api-go v0.6.0
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/docker/distribution v2.7.1+incompatible // indirect
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
|
||||
github.com/evanphx/json-patch v4.5.0+incompatible // indirect
|
||||
|
|
Loading…
Reference in New Issue