fix: client auth needs project domain info

This commit is contained in:
Qiu Jian
2019-05-30 19:07:45 +08:00
parent 42861cd43f
commit 8c799e3a5e
13 changed files with 100 additions and 67 deletions
+4 -1
View File
@@ -52,7 +52,9 @@ type BaseOptions struct {
OsUsername string `default:"$OS_USERNAME" help:"Username, defaults to env[OS_USERNAME]"`
OsPassword string `default:"$OS_PASSWORD" help:"Password, defaults to env[OS_PASSWORD]"`
// OsProjectId string `default:"$OS_PROJECT_ID" help:"Proejct ID, defaults to env[OS_PROJECT_ID]"`
OsProjectName string `default:"$OS_PROJECT_NAME" help:"Project name, defaults to env[OS_PROJECT_NAME]"`
OsProjectName string `default:"$OS_PROJECT_NAME" help:"Project name, defaults to env[OS_PROJECT_NAME]"`
OsProjectDomain string `default:"$OS_PROJECT_DOMAIN" help:"Domain name of project, defaults to env[OS_PROJECT_DOMAIN]"`
OsDomainName string `default:"$OS_DOMAIN_NAME" help:"Domain name, defaults to env[OS_DOMAIN_NAME]"`
OsAuthURL string `default:"$OS_AUTH_URL" help:"Defaults to env[OS_AUTH_URL]"`
OsRegionName string `default:"$OS_REGION_NAME" help:"Defaults to env[OS_REGION_NAME]"`
@@ -178,6 +180,7 @@ func newClientSession(options *BaseOptions) (*mcclient.ClientSession, error) {
options.OsPassword,
options.OsDomainName,
options.OsProjectName,
options.OsProjectDomain,
mcclient.AuthSourceCli)
if err != nil {
return nil, err
+12 -11
View File
@@ -27,16 +27,17 @@ import (
)
type BaseOptions struct {
Debug bool `help:"debug mode"`
Help bool `help:"Show help"`
AuthURL string `help:"Auth URL" default:"$OPENSTACK_AUTH_URL"`
Username string `help:"Username" default:"$OPENSTACK_USERNAME"`
Password string `help:"Password" default:"$OPENSTACK_PASSWORD"`
Project string `help:"Project" default:"$OPENSTACK_PROJECT"`
EndpointType string `help:"Project" default:"$OPENSTACK_ENDPOINT_TYPE|internal"`
DomainName string `help:"DomainName" default:"$OPENSTACK_DOMAIN_NAME"`
RegionID string `help:"RegionId" default:"$OPENSTACK_REGION_ID"`
SUBCOMMAND string `help:"openstackcli subcommand" subcommand:"true"`
Debug bool `help:"debug mode"`
Help bool `help:"Show help"`
AuthURL string `help:"Auth URL" default:"$OPENSTACK_AUTH_URL"`
Username string `help:"Username" default:"$OPENSTACK_USERNAME"`
Password string `help:"Password" default:"$OPENSTACK_PASSWORD"`
Project string `help:"Project" default:"$OPENSTACK_PROJECT"`
EndpointType string `help:"Project" default:"$OPENSTACK_ENDPOINT_TYPE|internal"`
DomainName string `help:"Domain of user" default:"$OPENSTACK_DOMAIN_NAME"`
ProjectDomain string `help:"Domain of project" default:"$OPENSTACK_PROJECT_DOMAIN"`
RegionID string `help:"RegionId" default:"$OPENSTACK_REGION_ID"`
SUBCOMMAND string `help:"openstackcli subcommand" subcommand:"true"`
}
func getSubcommandParser() (*structarg.ArgumentParser, error) {
@@ -92,7 +93,7 @@ func newClient(options *BaseOptions) (*openstack.SRegion, error) {
return nil, fmt.Errorf("Missing Password")
}
cli, err := openstack.NewOpenStackClient("", "", options.AuthURL, options.Username, options.Password, options.Project, options.EndpointType, options.DomainName, options.Debug)
cli, err := openstack.NewOpenStackClient("", "", options.AuthURL, options.Username, options.Password, options.Project, options.EndpointType, options.DomainName, options.ProjectDomain, options.Debug)
if err != nil {
return nil, err
}
+5 -2
View File
@@ -48,11 +48,14 @@ func InitAuth(options *common_options.CommonOptions, authComplete auth.AuthCompl
os.Exit(1)
}
a := auth.NewAuthInfo(options.AuthURL,
a := auth.NewAuthInfo(
options.AuthURL,
options.AdminDomain,
options.AdminUser,
options.AdminPassword,
options.AdminProject)
options.AdminProject,
options.AdminProjectDomain,
)
// debug := options.LogLevel == "debug"
+1
View File
@@ -74,6 +74,7 @@ type CommonOptions struct {
AdminDomain string `help:"Admin user domain"`
AdminPassword string `help:"Admin password" alias:"admin-passwd"`
AdminProject string `help:"Admin project" default:"system" alias:"admin-tenant-name"`
AdminProjectDomain string `help:"Domain of Admin project"`
AuthTokenCacheSize uint32 `help:"Auth token Cache Size" default:"2048"`
BaseOptions
+1 -1
View File
@@ -125,7 +125,7 @@ func (r *SRegionDNS) getAdminSession(ctx context.Context) *mcclient.ClientSessio
}
func (r *SRegionDNS) initAuth() {
authInfo := auth.NewAuthInfo(r.AuthUrl, "", r.AdminUser, r.AdminPassword, r.AdminProject)
authInfo := auth.NewAuthInfo(r.AuthUrl, "", r.AdminUser, r.AdminPassword, r.AdminProject, "")
auth.Init(authInfo, false, true, "", "")
}
+1 -1
View File
@@ -125,7 +125,7 @@ func (manager *SDomainManager) FetchDomainById(domainId string) (*SDomain, error
if err != nil {
return nil, err
}
q := manager.Query().Equals("id", domainId).NotEquals("id", api.KeystoneDomainRoot)
q := manager.Query().Equals("id", domainId)
err = q.First(obj)
if err != nil {
return nil, err
+1
View File
@@ -269,6 +269,7 @@ func (manager *SIdentityProviderManager) ValidateCreateData(ctx context.Context,
return nil, httperrors.NewInputParameterError("invalid template")
}
drvName = api.IdpTemplateDriver[template]
data.Set("driver", jsonutils.NewString(drvName))
} else {
drvName, _ = data.GetString("driver")
if len(drvName) == 0 {
+28 -10
View File
@@ -126,18 +126,36 @@ func (manager *SProjectManager) Query(fields ...string) *sqlchemy.SQuery {
func (manager *SProjectManager) FetchProjectByName(projectName string, domainId, domainName string) (*SProject, error) {
obj, err := db.NewModelObject(manager)
if err != nil {
return nil, err
return nil, errors.Wrap(err, "db.NewModelObject")
}
domain, err := DomainManager.FetchDomain(domainId, domainName)
if err != nil {
return nil, err
if len(domainId) == 0 && len(domainName) == 0 {
q := manager.Query().Equals("name", projectName)
cnt, err := q.CountWithError()
if err != nil {
return nil, errors.Wrap(err, "CountWithError")
}
if cnt == 0 {
return nil, sql.ErrNoRows
}
if cnt > 1 {
return nil, sqlchemy.ErrDuplicateEntry
}
err = q.First(obj)
if err != nil {
return nil, errors.Wrap(err, "q.First")
}
} else {
domain, err := DomainManager.FetchDomain(domainId, domainName)
if err != nil {
return nil, errors.Wrap(err, "DomainManager.FetchDomain")
}
q := manager.Query().Equals("name", projectName).Equals("domain_id", domain.Id)
err = q.First(obj)
if err != nil {
return nil, errors.Wrap(err, "q.First")
}
}
q := manager.Query().Equals("name", projectName).Equals("domain_id", domain.Id)
err = q.First(obj)
if err != nil {
return nil, err
}
return obj.(*SProject), err
return obj.(*SProject), nil
}
func (manager *SProjectManager) FetchProjectById(projectId string) (*SProject, error) {
+1
View File
@@ -90,6 +90,7 @@ func authUserByIdentity(ctx context.Context, ident mcclient.SAuthenticationIdent
if err != nil {
return nil, errors.Wrap(err, "Query user")
}
ident.Password.User.Domain.Id = usr.DomainId
idmap, err := models.IdmappingManager.FetchEntity(usr.Id, api.IdMappingEntityUser)
if err != nil && err != sql.ErrNoRows {
return nil, errors.Wrap(err, "IdmappingManager.FetchEntity")
+12 -10
View File
@@ -40,7 +40,8 @@ type AuthInfo struct {
Username string
Passwd string
// Project is tenant when v2 auth
Project string
Project string
ProjectDomain string
}
func SetTimeout(t time.Duration) {
@@ -48,16 +49,17 @@ func SetTimeout(t time.Duration) {
}
func NewV2AuthInfo(authUrl, user, passwd, tenant string) *AuthInfo {
return NewAuthInfo(authUrl, "", user, passwd, tenant)
return NewAuthInfo(authUrl, "", user, passwd, tenant, "")
}
func NewAuthInfo(authUrl, domain, user, passwd, project string) *AuthInfo {
func NewAuthInfo(authUrl, domain, user, passwd, project, projectDomain string) *AuthInfo {
return &AuthInfo{
AuthUrl: authUrl,
Domain: domain,
Username: user,
Passwd: passwd,
Project: project,
AuthUrl: authUrl,
Domain: domain,
Username: user,
Passwd: passwd,
Project: project,
ProjectDomain: projectDomain,
}
}
@@ -154,8 +156,8 @@ func (a *authManager) authAdmin() error {
var token mcclient.TokenCredential
var err error
token, err = a.client.AuthenticateWithSource(
a.info.Username, a.info.Passwd,
a.info.Domain, a.info.Project, mcclient.AuthSourceSrv)
a.info.Username, a.info.Passwd, a.info.Domain,
a.info.Project, a.info.ProjectDomain, mcclient.AuthSourceSrv)
if err != nil {
log.Errorf("Admin auth failed: %s", err)
return err
+19 -18
View File
@@ -127,7 +127,7 @@ func (this *Client) jsonRequest(ctx context.Context, endpoint string, token stri
return httputils.JSONRequest(this.httpconn, ctx, method, joinUrl(endpoint, url), getDefaultHeader(header, token), body, this.debug)
}
func (this *Client) _authV3(domainName, uname, passwd, projectId, projectName, token string, aCtx SAuthContext) (TokenCredential, error) {
func (this *Client) _authV3(domainName, uname, passwd, projectId, projectName, projectDomain, token string, aCtx SAuthContext) (TokenCredential, error) {
input := SAuthenticationInputV3{}
if len(uname) > 0 && len(passwd) > 0 { // Password authentication
input.Auth.Identity.Methods = []string{api.AUTH_METHOD_PASSWORD}
@@ -148,11 +148,12 @@ func (this *Client) _authV3(domainName, uname, passwd, projectId, projectName, t
}
if len(projectName) > 0 {
input.Auth.Scope.Project.Name = projectName
if len(domainName) > 0 {
if len(projectDomain) > 0 {
input.Auth.Scope.Project.Domain.Name = domainName
} else {
input.Auth.Scope.Project.Domain.Id = api.DEFAULT_DOMAIN_ID
}
// else {
// input.Auth.Scope.Project.Domain.Id = api.DEFAULT_DOMAIN_ID
// }
}
input.Auth.Context = aCtx
hdr, rbody, err := this.jsonRequest(context.Background(), this.authUrl, "", "POST", "/auth/tokens", nil, jsonutils.Marshal(&input))
@@ -189,32 +190,32 @@ func (this *Client) _authV2(uname, passwd, tenantId, tenantName, token string, a
return this.unmarshalV2Token(rbody)
}
func (this *Client) Authenticate(uname, passwd, domainName, tenantName string) (TokenCredential, error) {
return this.AuthenticateApi(uname, passwd, domainName, tenantName)
func (this *Client) Authenticate(uname, passwd, domainName, tenantName, tenantDomain string) (TokenCredential, error) {
return this.AuthenticateApi(uname, passwd, domainName, tenantName, tenantDomain)
}
func (this *Client) AuthenticateApi(uname, passwd, domainName, tenantName string) (TokenCredential, error) {
return this.AuthenticateWithSource(uname, passwd, domainName, tenantName, AuthSourceAPI)
func (this *Client) AuthenticateApi(uname, passwd, domainName, tenantName, tenantDomain string) (TokenCredential, error) {
return this.AuthenticateWithSource(uname, passwd, domainName, tenantName, tenantDomain, AuthSourceAPI)
}
func (this *Client) AuthenticateWeb(uname, passwd, domainName, tenantName string, cliIp string) (TokenCredential, error) {
func (this *Client) AuthenticateWeb(uname, passwd, domainName, tenantName, tenantDomain string, cliIp string) (TokenCredential, error) {
aCtx := SAuthContext{
Source: AuthSourceWeb,
Ip: cliIp,
}
return this.authenticateWithContext(uname, passwd, domainName, tenantName, aCtx)
return this.authenticateWithContext(uname, passwd, domainName, tenantName, tenantDomain, aCtx)
}
func (this *Client) AuthenticateWithSource(uname, passwd, domainName, tenantName string, source string) (TokenCredential, error) {
func (this *Client) AuthenticateWithSource(uname, passwd, domainName, tenantName, tenantDomain string, source string) (TokenCredential, error) {
aCtx := SAuthContext{
Source: source,
}
return this.authenticateWithContext(uname, passwd, domainName, tenantName, aCtx)
return this.authenticateWithContext(uname, passwd, domainName, tenantName, tenantDomain, aCtx)
}
func (this *Client) authenticateWithContext(uname, passwd, domainName, tenantName string, aCtx SAuthContext) (TokenCredential, error) {
func (this *Client) authenticateWithContext(uname, passwd, domainName, tenantName, tenantDomain string, aCtx SAuthContext) (TokenCredential, error) {
if this.AuthVersion() == "v3" {
return this._authV3(domainName, uname, passwd, "", tenantName, "", aCtx)
return this._authV3(domainName, uname, passwd, "", tenantName, tenantDomain, "", aCtx)
}
return this._authV2(uname, passwd, "", tenantName, "", aCtx)
}
@@ -281,17 +282,17 @@ func (this *Client) Verify(adminToken, token string) (cred TokenCredential, err
return this.verifyV2(adminToken, token)
}
func (this *Client) SetTenant(tenantId, tenantName string, token TokenCredential) (TokenCredential, error) {
return this.SetProject(tenantId, tenantName, token)
func (this *Client) SetTenant(tenantId, tenantName, tenantDomain string, token TokenCredential) (TokenCredential, error) {
return this.SetProject(tenantId, tenantName, tenantDomain, token)
}
func (this *Client) SetProject(tenantId, tenantName string, token TokenCredential) (TokenCredential, error) {
func (this *Client) SetProject(tenantId, tenantName, tenantDomain string, token TokenCredential) (TokenCredential, error) {
aCtx := SAuthContext{
Source: token.GetLoginSource(),
Ip: token.GetLoginIp(),
}
if this.AuthVersion() == "v3" {
return this._authV3("", "", "", tenantId, tenantName, token.GetTokenString(), aCtx)
return this._authV3("", "", "", tenantId, tenantName, tenantDomain, token.GetTokenString(), aCtx)
} else {
return this._authV2("", "", "", tenantName, token.GetTokenString(), aCtx)
}
+13 -11
View File
@@ -44,6 +44,7 @@ type SOpenStackClient struct {
username string
password string
project string
projectDomain string
endpointType string
domainName string
client *mcclient.Client
@@ -53,17 +54,18 @@ type SOpenStackClient struct {
Debug bool
}
func NewOpenStackClient(providerID string, providerName string, authURL string, username string, password string, project string, endpointType string, domainName string, isDebug bool) (*SOpenStackClient, error) {
func NewOpenStackClient(providerID string, providerName string, authURL string, username string, password string, project string, endpointType string, domainName string, projectDomainName string, isDebug bool) (*SOpenStackClient, error) {
cli := &SOpenStackClient{
providerID: providerID,
providerName: providerName,
authURL: strings.TrimRight(authURL, "/"),
username: username,
password: password,
project: project,
endpointType: endpointType,
domainName: domainName,
Debug: isDebug,
providerID: providerID,
providerName: providerName,
authURL: strings.TrimRight(authURL, "/"),
username: username,
password: password,
project: project,
projectDomain: projectDomainName,
endpointType: endpointType,
domainName: domainName,
Debug: isDebug,
}
return cli, cli.fetchRegions()
}
@@ -192,7 +194,7 @@ func (cli *SOpenStackClient) getVersion(region string, service string) (string,
func (cli *SOpenStackClient) connect() error {
cli.client = mcclient.NewClient(cli.authURL, 5, cli.Debug, false, "", "")
tokenCredential, err := cli.client.Authenticate(cli.username, cli.password, cli.domainName, cli.project)
tokenCredential, err := cli.client.Authenticate(cli.username, cli.password, cli.domainName, cli.project, cli.projectDomain)
if err != nil {
return err
}
+2 -2
View File
@@ -112,11 +112,11 @@ func (self *SOpenStackProviderFactory) GetProvider(providerId, providerName, url
if len(accountInfo) < 2 {
return nil, fmt.Errorf("Missing username or project name %s", account)
}
project, username, endpointType, domainName := accountInfo[0], accountInfo[1], "internal", ""
project, username, endpointType, domainName, projectDomainName := accountInfo[0], accountInfo[1], "internal", "", ""
if len(accountInfo) == 3 {
domainName = accountInfo[2]
}
client, err := openstack.NewOpenStackClient(providerId, providerName, url, username, password, project, endpointType, domainName, false)
client, err := openstack.NewOpenStackClient(providerId, providerName, url, username, password, project, endpointType, domainName, projectDomainName, false)
if err != nil {
return nil, err
}