diff --git a/docs/index.md b/docs/index.md index 13b4b3f..6c18468 100644 --- a/docs/index.md +++ b/docs/index.md @@ -17,10 +17,12 @@ description: |- ### Required -- `access_token` (String) IAM颁发的用户凭证 - `cmp_endpoint` (String) CMP地址 -- `sso_endpoint` (String) SSO地址 +- `iam_client_id` (String) IAM颁发的客户端ID +- `iam_client_secret` (String) IAM颁发的客户端Secret +- `iam_endpoint` (String) IAM地址 ### Optional -- `cmp_client_secret` (String) IAM颁发给CMP的客户端凭证 +- `password` (String) 密码 +- `user_name` (String) 用户名 diff --git a/examples/bingo_cmp_command/main.tf b/examples/bingo_cmp_command/main.tf index 8405096..1dea18a 100644 --- a/examples/bingo_cmp_command/main.tf +++ b/examples/bingo_cmp_command/main.tf @@ -7,9 +7,7 @@ terraform { } provider "bingo" { - ssoEndpoint = "##" - accessToken = "##" - cmpEndpoint = "##" + } resource "bingo_cmp_command" "cmd" { diff --git a/internal/pkg/sso/client.go b/internal/pkg/sso/client.go index 4f3a2af..daa0b4c 100644 --- a/internal/pkg/sso/client.go +++ b/internal/pkg/sso/client.go @@ -11,6 +11,8 @@ type config struct { Endpoint string ClientId string ClientSecret string + UserName string + Password string Options grequests.RequestOptions } @@ -18,12 +20,14 @@ type Client struct { config *config } -func New(endpoint, clientId, clientSecret string) *Client { +func New(endpoint, clientId, clientSecret, userName, password string) *Client { ssoClient := &Client{} ssoClient.config = &config{} ssoClient.config.Endpoint = endpoint ssoClient.config.ClientId = clientId ssoClient.config.ClientSecret = clientSecret + ssoClient.config.UserName = userName + ssoClient.config.Password = password var headers map[string]string if clientSecret != "" { diff --git a/internal/pkg/sso/sso_test.go b/internal/pkg/sso/sso_test.go index af9cddc..bb226b8 100644 --- a/internal/pkg/sso/sso_test.go +++ b/internal/pkg/sso/sso_test.go @@ -6,6 +6,7 @@ import ( ) func TestClient_GenerateAccessToken(t *testing.T) { - ssoClient := New("https://sso.bingosoft.net", "ajcNcUVYSmEW99qCyA9PnT", "b25da097-657d-4ed0-a579-47da34ad87e1") - log.Println(ssoClient.GenerateAccessToken()) + ssoClient := New("https://sso.bingosoft.net", "ajcNcUVYSmEW99qCyA9PnT", "b25da097-657d-4ed0-a579-47da34ad87e1", "bingo", "pass@cmp#2019") + log.Println(ssoClient.GenerateAccessTokenByUser()) + log.Println(ssoClient.GenerateAccessTokenByClient()) } diff --git a/internal/pkg/sso/v3.go b/internal/pkg/sso/v3.go index 182400f..03511a7 100644 --- a/internal/pkg/sso/v3.go +++ b/internal/pkg/sso/v3.go @@ -3,6 +3,7 @@ package sso import ( "encoding/json" "fmt" + "net/url" "github.com/levigross/grequests" @@ -20,7 +21,7 @@ func (its Authorization) String() string { return utils.Prettify(its) } -func (its *Client) GenerateAccessToken() (*Authorization, error) { +func (its *Client) GenerateAccessTokenByClient() (*Authorization, error) { options := its.config.Options resp, err := grequests.Post(fmt.Sprintf("%v/oauth2/token?grant_type=client_credentials", its.config.Endpoint), &options) if err != nil { @@ -39,3 +40,23 @@ func (its *Client) GenerateAccessToken() (*Authorization, error) { return auth, err } + +func (its *Client) GenerateAccessTokenByUser() (*Authorization, error) { + options := its.config.Options + resp, err := grequests.Post(fmt.Sprintf("%v/oauth2/token?grant_type=password&username=%v&password=%v", its.config.Endpoint, its.config.UserName, url.QueryEscape(its.config.Password)), &options) + if err != nil { + return nil, err + } + defer resp.Close() + + content := resp.String() + if !resp.Ok { + err = fmt.Errorf("[SSO] Response code: [%v],result: [%s]", resp.StatusCode, content) + return nil, err + } + + auth := &Authorization{} + err = json.Unmarshal([]byte(content), &auth) + + return auth, err +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index f69b3eb..bd06b4d 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -33,6 +33,8 @@ const ( CMP_ENDPOINT = "CMP_ENDPOINT" IAM_CLIENT_ID = "IAM_CLIENT_ID" IAM_CLIENT_SECRET = "IAM_CLIENT_SECRET" + USER_NAME = "USER_NAME" + PASSWORD = "PASSWORD" ) type bingoCloudClient struct { @@ -63,10 +65,22 @@ func New(version string) func() *schema.Provider { }, "iam_client_secret": { Type: schema.TypeString, - Optional: true, + Required: true, DefaultFunc: schema.EnvDefaultFunc(IAM_CLIENT_SECRET, nil), Description: "IAM颁发的客户端Secret", }, + "user_name": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc(USER_NAME, nil), + Description: "用户名", + }, + "password": { + Type: schema.TypeString, + Optional: true, + DefaultFunc: schema.EnvDefaultFunc(PASSWORD, nil), + Description: "密码", + }, }, DataSourcesMap: map[string]*schema.Resource{}, @@ -88,9 +102,19 @@ func configure(version string, p *schema.Provider) func(context.Context, *schema cmpEndpoint := r.Get("cmp_endpoint").(string) iamClientId := r.Get("iam_client_id").(string) iamClientSecret := r.Get("iam_client_secret").(string) + userName := r.Get("user_name").(string) + password := r.Get("password").(string) + + var err error + auth := &sso.Authorization{} + ssoClient := sso.New(iamEndpoint, iamClientId, iamClientSecret, userName, password) + + if userName != "" && password != "" { + auth, err = ssoClient.GenerateAccessTokenByUser() + } else { + auth, err = ssoClient.GenerateAccessTokenByClient() + } - ssoClient := sso.New(iamEndpoint, iamClientId, iamClientSecret) - auth, err := ssoClient.GenerateAccessToken() if err != nil { return nil, diag.Errorf(fmt.Sprintf("[SSO] Generate AccessToken failed: %s", err)) } diff --git a/internal/provider/provider_test.go b/internal/provider/provider_test.go index 2647ad9..fb4d1d8 100644 --- a/internal/provider/provider_test.go +++ b/internal/provider/provider_test.go @@ -15,6 +15,8 @@ func init() { _ = os.Setenv("CMP_ENDPOINT", "https://cmp-dev.bingosoft.net") _ = os.Setenv("IAM_CLIENT_ID", "ajcNcUVYSmEW99qCyA9PnT") _ = os.Setenv("IAM_CLIENT_SECRET", "b25da097-657d-4ed0-a579-47da34ad87e1") + _ = os.Setenv("USER_NAME", "bingo") + _ = os.Setenv("PASSWORD", "pass@cmp#2019") } // providerFactories are used to instantiate a provider during acceptance testing.