mirror of https://github.com/docker/compose.git
Implement azure logout
This commit is contained in:
parent
78cb0a87c7
commit
492ce96dd4
|
@ -342,6 +342,10 @@ func (cs *aciCloudService) Login(ctx context.Context, params map[string]string)
|
|||
return cs.loginService.Login(ctx, params[login.TenantIDLoginParam])
|
||||
}
|
||||
|
||||
func (cs *aciCloudService) Logout(ctx context.Context) error {
|
||||
return cs.loginService.Logout(ctx)
|
||||
}
|
||||
|
||||
func (cs *aciCloudService) CreateContextData(ctx context.Context, params map[string]string) (interface{}, string, error) {
|
||||
contextHelper := newContextCreateHelper()
|
||||
return contextHelper.createContextData(ctx, params)
|
||||
|
|
|
@ -22,14 +22,13 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"os"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
"github.com/Azure/go-autorest/autorest/adal"
|
||||
auth2 "github.com/Azure/go-autorest/autorest/azure/auth"
|
||||
"github.com/Azure/go-autorest/autorest/azure/cli"
|
||||
"github.com/Azure/go-autorest/autorest/date"
|
||||
"github.com/pkg/errors"
|
||||
"golang.org/x/oauth2"
|
||||
|
@ -80,7 +79,7 @@ const tokenStoreFilename = "dockerAccessToken.json"
|
|||
|
||||
// NewAzureLoginService creates a NewAzureLoginService
|
||||
func NewAzureLoginService() (AzureLoginService, error) {
|
||||
return newAzureLoginServiceFromPath(getTokenStorePath(), azureAPIHelper{})
|
||||
return newAzureLoginServiceFromPath(GetTokenStorePath(), azureAPIHelper{})
|
||||
}
|
||||
|
||||
func newAzureLoginServiceFromPath(tokenStorePath string, helper apiHelper) (AzureLoginService, error) {
|
||||
|
@ -120,6 +119,15 @@ func (login AzureLoginService) TestLoginFromServicePrincipal(clientID string, cl
|
|||
return nil
|
||||
}
|
||||
|
||||
// Logout remove azure token data
|
||||
func (login AzureLoginService) Logout(ctx context.Context) error {
|
||||
err := login.tokenStore.removeData()
|
||||
if os.IsNotExist(err) {
|
||||
return errors.New("No Azure login data to be removed")
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Login performs an Azure login through a web browser
|
||||
func (login AzureLoginService) Login(ctx context.Context, requestedTenantID string) error {
|
||||
queryCh := make(chan localResponse, 1)
|
||||
|
@ -208,11 +216,6 @@ func getTenantID(tenantValues []tenantValue, requestedTenantID string) (string,
|
|||
return "", errors.Errorf("could not find requested azure tenant %s", requestedTenantID)
|
||||
}
|
||||
|
||||
func getTokenStorePath() string {
|
||||
cliPath, _ := cli.AccessTokensPath()
|
||||
return filepath.Join(filepath.Dir(cliPath), tokenStoreFilename)
|
||||
}
|
||||
|
||||
func toOAuthToken(token azureToken) oauth2.Token {
|
||||
expireTime := time.Now().Add(time.Duration(token.ExpiresIn) * time.Second)
|
||||
oauthToken := oauth2.Token{
|
||||
|
@ -241,7 +244,7 @@ func spToOAuthToken(token adal.Token) (oauth2.Token, error) {
|
|||
|
||||
// NewAuthorizerFromLogin creates an authorizer based on login access token
|
||||
func NewAuthorizerFromLogin() (autorest.Authorizer, error) {
|
||||
return newAuthorizerFromLoginStorePath(getTokenStorePath())
|
||||
return newAuthorizerFromLoginStorePath(GetTokenStorePath())
|
||||
}
|
||||
|
||||
func newAuthorizerFromLoginStorePath(storeTokenPath string) (autorest.Authorizer, error) {
|
||||
|
|
|
@ -23,6 +23,8 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/Azure/go-autorest/autorest/azure/cli"
|
||||
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
|
@ -57,6 +59,12 @@ func newTokenStore(path string) (tokenStore, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// GetTokenStorePath the path for token store
|
||||
func GetTokenStorePath() string {
|
||||
cliPath, _ := cli.AccessTokensPath()
|
||||
return filepath.Join(filepath.Dir(cliPath), tokenStoreFilename)
|
||||
}
|
||||
|
||||
func (store tokenStore) writeLoginInfo(info TokenInfo) error {
|
||||
bytes, err := json.MarshalIndent(info, "", " ")
|
||||
if err != nil {
|
||||
|
@ -76,3 +84,7 @@ func (store tokenStore) readToken() (TokenInfo, error) {
|
|||
}
|
||||
return loginInfo, nil
|
||||
}
|
||||
|
||||
func (store tokenStore) removeData() error {
|
||||
return os.Remove(store.filePath)
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ import (
|
|||
func Command() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "login [OPTIONS] [SERVER]",
|
||||
Short: "Log in to a Docker registry",
|
||||
Short: "Log in to a Docker registry or cloud backend",
|
||||
Long: "Log in to a Docker registry or cloud backend.\nIf no registry server is specified, the default is defined by the daemon.",
|
||||
Args: cobra.MaximumNArgs(1),
|
||||
RunE: runLogin,
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
package logout
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/docker/api/client"
|
||||
"github.com/docker/api/errdefs"
|
||||
)
|
||||
|
||||
// AzureLogoutCommand returns the azure logout command
|
||||
func AzureLogoutCommand() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "azure",
|
||||
Short: "Logout from Azure",
|
||||
Args: cobra.MaximumNArgs(0),
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return cloudLogout(cmd, "aci")
|
||||
},
|
||||
}
|
||||
return cmd
|
||||
}
|
||||
|
||||
func cloudLogout(cmd *cobra.Command, backendType string) error {
|
||||
ctx := cmd.Context()
|
||||
cs, err := client.GetCloudService(ctx, backendType)
|
||||
if err != nil {
|
||||
return errors.Wrap(errdefs.ErrLoginFailed, "cannot connect to backend")
|
||||
}
|
||||
err = cs.Logout(ctx)
|
||||
if errors.Is(err, context.Canceled) {
|
||||
return errors.New("logout canceled")
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Removing login credentials for Azure")
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package logout
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/docker/api/cli/mobycli"
|
||||
)
|
||||
|
||||
// Command returns the login command
|
||||
func Command() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "logout [SERVER]",
|
||||
Short: "Log out from a Docker registry or cloud backend",
|
||||
Long: "Log out from a Docker registry or cloud backend.\nIf no server is specified, the default is defined by the daemon.",
|
||||
Args: cobra.MaximumNArgs(0),
|
||||
RunE: runLogout,
|
||||
}
|
||||
|
||||
cmd.AddCommand(AzureLogoutCommand())
|
||||
return cmd
|
||||
}
|
||||
|
||||
func runLogout(cmd *cobra.Command, args []string) error {
|
||||
return mobycli.ExecCmd(cmd)
|
||||
}
|
|
@ -27,6 +27,8 @@ import (
|
|||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/docker/api/cli/cmd/logout"
|
||||
|
||||
"github.com/docker/api/errdefs"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
@ -59,6 +61,7 @@ var (
|
|||
ownCommands = map[string]struct{}{
|
||||
"context": {},
|
||||
"login": {},
|
||||
"logout": {},
|
||||
"serve": {},
|
||||
"version": {},
|
||||
}
|
||||
|
@ -117,6 +120,7 @@ func main() {
|
|||
cmd.InspectCommand(),
|
||||
compose.Command(),
|
||||
login.Command(),
|
||||
logout.Command(),
|
||||
cmd.VersionCommand(version),
|
||||
)
|
||||
|
||||
|
|
|
@ -26,7 +26,9 @@ import (
|
|||
type Service interface {
|
||||
// Login login to cloud provider
|
||||
Login(ctx context.Context, params map[string]string) error
|
||||
// Login login to cloud provider
|
||||
// Logout logout from cloud provider
|
||||
Logout(ctx context.Context) error
|
||||
// CreateContextData create data for cloud context
|
||||
CreateContextData(ctx context.Context, params map[string]string) (contextData interface{}, description string, err error)
|
||||
}
|
||||
|
||||
|
@ -38,6 +40,11 @@ func NotImplementedCloudService() (Service, error) {
|
|||
type notImplementedCloudService struct {
|
||||
}
|
||||
|
||||
// Logout login to cloud provider
|
||||
func (cs notImplementedCloudService) Logout(ctx context.Context) error {
|
||||
return errdefs.ErrNotImplemented
|
||||
}
|
||||
|
||||
func (cs notImplementedCloudService) Login(ctx context.Context, params map[string]string) error {
|
||||
return errdefs.ErrNotImplemented
|
||||
}
|
||||
|
|
|
@ -22,10 +22,13 @@ import (
|
|||
"math/rand"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/api/errdefs"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/profiles/2019-03-01/resources/mgmt/resources"
|
||||
azure_storage "github.com/Azure/azure-sdk-for-go/profiles/2019-03-01/storage/mgmt/storage"
|
||||
"github.com/Azure/azure-storage-file-go/azfile"
|
||||
|
@ -58,6 +61,25 @@ type E2eACISuite struct {
|
|||
Suite
|
||||
}
|
||||
|
||||
func (s *E2eACISuite) TestLoginLogoutCreateContextError() {
|
||||
s.Step("Logs in azure using service principal credentials", azureLogin)
|
||||
|
||||
s.Step("logout from azure", func() {
|
||||
output := s.NewDockerCommand("logout", "azure").ExecOrDie()
|
||||
Expect(output).To(ContainSubstring(""))
|
||||
_, err := os.Stat(login.GetTokenStorePath())
|
||||
Expect(os.IsNotExist(err)).To(BeTrue())
|
||||
})
|
||||
|
||||
s.Step("check context create fails with an explicit error and returns a specific error code", func() {
|
||||
cmd := exec.Command("docker", "context", "create", "aci", "someContext")
|
||||
bytes, err := cmd.CombinedOutput()
|
||||
Expect(err).NotTo(BeNil())
|
||||
Expect(string(bytes)).To(ContainSubstring("not logged in to azure, you need to run \"docker login azure\" first"))
|
||||
Expect(cmd.ProcessState.ExitCode()).To(Equal(errdefs.ExitCodeLoginRequired))
|
||||
})
|
||||
}
|
||||
|
||||
func (s *E2eACISuite) TestACIRunSingleContainer() {
|
||||
resourceGroupName := s.setupTestResourceGroup()
|
||||
defer deleteResourceGroup(resourceGroupName)
|
||||
|
|
|
@ -18,17 +18,13 @@ package main
|
|||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/docker/api/errdefs"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"gotest.tools/golden"
|
||||
|
||||
. "github.com/docker/api/tests/framework"
|
||||
|
@ -46,14 +42,6 @@ func (s *E2eSuite) TestContextHelp() {
|
|||
Expect(output).To(ContainSubstring("--resource-group"))
|
||||
}
|
||||
|
||||
func (s *E2eSuite) TestContextCreateAciExitWithErrorCodeIfLoginRequired() {
|
||||
cmd := exec.Command("docker", "context", "create", "aci", "someContext")
|
||||
output, err := cmd.CombinedOutput()
|
||||
Expect(err).NotTo(BeNil())
|
||||
Expect(string(output)).To(ContainSubstring("not logged in to azure, you need to run \"docker login azure\" first"))
|
||||
Expect(cmd.ProcessState.ExitCode()).To(Equal(errdefs.ExitCodeLoginRequired))
|
||||
}
|
||||
|
||||
func (s *E2eSuite) TestListAndShowDefaultContext() {
|
||||
output := s.NewDockerCommand("context", "show").ExecOrDie()
|
||||
Expect(output).To(ContainSubstring("default"))
|
||||
|
|
Loading…
Reference in New Issue