Skip to content

Commit

Permalink
*: add a new API and command for checking auth status
Browse files Browse the repository at this point in the history
This changes have started at etcdctl under auth.go, and make changes to stub out everything down into the internal raft.  Made changes to the .proto files and regenerated them so that the local version would build successfully.
  • Loading branch information
tarcinil committed Feb 5, 2020
1 parent 574ee42 commit 3d74793
Show file tree
Hide file tree
Showing 21 changed files with 1,013 additions and 465 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG-3.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.

- Fix [`etcdctl member add`](https://github.com/etcd-io/etcd/pull/11194) command to prevent potential timeout.
- Add [`etcdctl watch --progress-notify`](https://github.com/etcd-io/etcd/pull/11462) flag.
- Add [`etcdctl auth status`](https://github.com/etcd-io/etcd/pull/11536) command to check if authentication is enabled

### gRPC gateway

Expand All @@ -107,6 +108,10 @@ Note that any `etcd_debugging_*` metrics are experimental and subject to change.

- Fix [NoPassword check when adding user through GRPC gateway](https://github.com/etcd-io/etcd/pull/11418) ([issue#11414](https://github.com/etcd-io/etcd/issues/11414))

### API
- Add [`/v3/auth/status`](https://github.com/etcd-io/etcd/pull/11536) endpoint to check if authentication is enabled


### Dependency

- Upgrade [`google.golang.org/grpc`](https://github.com/grpc/grpc-go/releases) from [**`v1.23.0`**](https://github.com/grpc/grpc-go/releases/tag/v1.23.0) to [**`v1.23.1`**](https://github.com/grpc/grpc-go/releases/tag/v1.23.1).
Expand Down
16 changes: 16 additions & 0 deletions Documentation/dev-guide/api_reference_v3.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ This is a generated documentation. Please read the proto files for more.
| ------ | ------------ | ------------- | ----------- |
| AuthEnable | AuthEnableRequest | AuthEnableResponse | AuthEnable enables authentication. |
| AuthDisable | AuthDisableRequest | AuthDisableResponse | AuthDisable disables authentication. |
| AuthStatus | AuthStatusRequest | AuthStatusResponse | AuthStatus displays authentication status. |
| Authenticate | AuthenticateRequest | AuthenticateResponse | Authenticate processes an authenticate request. |
| UserAdd | AuthUserAddRequest | AuthUserAddResponse | UserAdd adds a new user. User name cannot be empty. |
| UserGet | AuthUserGetRequest | AuthUserGetResponse | UserGet gets detailed user information. |
Expand Down Expand Up @@ -240,6 +241,21 @@ Empty field.



##### message `AuthStatusRequest` (etcdserver/etcdserverpb/rpc.proto)

Empty field.



##### message `AuthStatusResponse` (etcdserver/etcdserverpb/rpc.proto)

| Field | Description | Type |
| ----- | ----------- | ---- |
| header | | ResponseHeader |
| enabled | | bool |



##### message `AuthUserAddRequest` (etcdserver/etcdserverpb/rpc.proto)

| Field | Description | Type |
Expand Down
119 changes: 73 additions & 46 deletions Documentation/dev-guide/apispec/swagger/rpc.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@
"produces": [
"application/json"
],
"schemes": [
"http",
"https"
],
"swagger": "2.0",
"info": {
"title": "etcdserver/etcdserverpb/rpc.proto",
Expand Down Expand Up @@ -258,6 +254,33 @@
}
}
},
"/v3/auth/status": {
"post": {
"tags": [
"Auth"
],
"summary": "AuthStatus displays authentication status.",
"operationId": "AuthStatus",
"parameters": [
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/etcdserverpbAuthStatusRequest"
}
}
],
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/etcdserverpbAuthStatusResponse"
}
}
}
}
},
"/v3/auth/user/add": {
"post": {
"tags": [
Expand Down Expand Up @@ -847,7 +870,16 @@
"200": {
"description": "A successful response.(streaming responses)",
"schema": {
"$ref": "#/x-stream-definitions/etcdserverpbLeaseKeepAliveResponse"
"type": "object",
"title": "Stream result of etcdserverpbLeaseKeepAliveResponse",
"properties": {
"error": {
"$ref": "#/definitions/runtimeStreamError"
},
"result": {
"$ref": "#/definitions/etcdserverpbLeaseKeepAliveResponse"
}
}
}
}
}
Expand Down Expand Up @@ -1036,7 +1068,16 @@
"200": {
"description": "A successful response.(streaming responses)",
"schema": {
"$ref": "#/x-stream-definitions/etcdserverpbSnapshotResponse"
"type": "object",
"title": "Stream result of etcdserverpbSnapshotResponse",
"properties": {
"error": {
"$ref": "#/definitions/runtimeStreamError"
},
"result": {
"$ref": "#/definitions/etcdserverpbSnapshotResponse"
}
}
}
}
}
Expand Down Expand Up @@ -1118,7 +1159,16 @@
"200": {
"description": "A successful response.(streaming responses)",
"schema": {
"$ref": "#/x-stream-definitions/etcdserverpbWatchResponse"
"type": "object",
"title": "Stream result of etcdserverpbWatchResponse",
"properties": {
"error": {
"$ref": "#/definitions/runtimeStreamError"
},
"result": {
"$ref": "#/definitions/etcdserverpbWatchResponse"
}
}
}
}
}
Expand Down Expand Up @@ -1423,6 +1473,21 @@
}
}
},
"etcdserverpbAuthStatusRequest": {
"type": "object"
},
"etcdserverpbAuthStatusResponse": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean",
"format": "boolean"
},
"header": {
"$ref": "#/definitions/etcdserverpbResponseHeader"
}
}
},
"etcdserverpbAuthUserAddRequest": {
"type": "object",
"properties": {
Expand Down Expand Up @@ -2637,43 +2702,5 @@
{
"ApiKey": []
}
],
"x-stream-definitions": {
"etcdserverpbLeaseKeepAliveResponse": {
"properties": {
"error": {
"$ref": "#/definitions/runtimeStreamError"
},
"result": {
"$ref": "#/definitions/etcdserverpbLeaseKeepAliveResponse"
}
},
"title": "Stream result of etcdserverpbLeaseKeepAliveResponse",
"type": "object"
},
"etcdserverpbSnapshotResponse": {
"properties": {
"error": {
"$ref": "#/definitions/runtimeStreamError"
},
"result": {
"$ref": "#/definitions/etcdserverpbSnapshotResponse"
}
},
"title": "Stream result of etcdserverpbSnapshotResponse",
"type": "object"
},
"etcdserverpbWatchResponse": {
"properties": {
"error": {
"$ref": "#/definitions/runtimeStreamError"
},
"result": {
"$ref": "#/definitions/etcdserverpbWatchResponse"
}
},
"title": "Stream result of etcdserverpbWatchResponse",
"type": "object"
}
}
]
}
29 changes: 10 additions & 19 deletions Documentation/dev-guide/apispec/swagger/v3election.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
"title": "etcdserver/api/v3election/v3electionpb/v3election.proto",
"version": "version not set"
},
"schemes": [
"http",
"https"
],
"consumes": [
"application/json"
],
Expand Down Expand Up @@ -77,7 +73,16 @@
"200": {
"description": "A successful response.(streaming responses)",
"schema": {
"$ref": "#/x-stream-definitions/v3electionpbLeaderResponse"
"type": "object",
"properties": {
"result": {
"$ref": "#/definitions/v3electionpbLeaderResponse"
},
"error": {
"$ref": "#/definitions/runtimeStreamError"
}
},
"title": "Stream result of v3electionpbLeaderResponse"
}
}
},
Expand Down Expand Up @@ -367,19 +372,5 @@
}
}
}
},
"x-stream-definitions": {
"v3electionpbLeaderResponse": {
"type": "object",
"properties": {
"result": {
"$ref": "#/definitions/v3electionpbLeaderResponse"
},
"error": {
"$ref": "#/definitions/runtimeStreamError"
}
},
"title": "Stream result of v3electionpbLeaderResponse"
}
}
}
4 changes: 0 additions & 4 deletions Documentation/dev-guide/apispec/swagger/v3lock.swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,6 @@
"title": "etcdserver/api/v3lock/v3lockpb/v3lock.proto",
"version": "version not set"
},
"schemes": [
"http",
"https"
],
"consumes": [
"application/json"
],
Expand Down
24 changes: 24 additions & 0 deletions auth/store_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,30 @@ func TestAuthDisable(t *testing.T) {
}
}

func TestIsAuthEnabled(t *testing.T) {
as, tearDown := setupAuthStore(t)
defer tearDown(t)

// enable authentication to test the first possible condition
as.AuthEnable()

status := as.IsAuthEnabled()
ctx := context.WithValue(context.WithValue(context.TODO(), AuthenticateParamIndex{}, uint64(2)), AuthenticateParamSimpleTokenPrefix{}, "dummy")
_, _ = as.Authenticate(ctx, "foo", "bar")
if status != true {
t.Errorf("expected %v, got %v", true, false)
}

// Disabling disabled auth to test the other condition that can be return
as.AuthDisable()

status = as.IsAuthEnabled()
_, _ = as.Authenticate(ctx, "foo", "bar")
if status != false {
t.Errorf("expected %v, got %v", false, true)
}
}

// TestAuthRevisionRace ensures that access to authStore.revision is thread-safe.
func TestAuthInfoFromCtxRace(t *testing.T) {
b, tPath := backend.NewDefaultTmpBackend()
Expand Down
9 changes: 9 additions & 0 deletions clientv3/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
type (
AuthEnableResponse pb.AuthEnableResponse
AuthDisableResponse pb.AuthDisableResponse
AuthStatusResponse pb.AuthStatusResponse
AuthenticateResponse pb.AuthenticateResponse
AuthUserAddResponse pb.AuthUserAddResponse
AuthUserDeleteResponse pb.AuthUserDeleteResponse
Expand Down Expand Up @@ -61,6 +62,9 @@ type Auth interface {
// AuthDisable disables auth of an etcd cluster.
AuthDisable(ctx context.Context) (*AuthDisableResponse, error)

// AuthStatus returns the status of auth of an etcd cluster.
AuthStatus(ctx context.Context) (*AuthStatusResponse, error)

// UserAdd adds a new user to an etcd cluster.
UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error)

Expand Down Expand Up @@ -127,6 +131,11 @@ func (auth *authClient) AuthDisable(ctx context.Context) (*AuthDisableResponse,
return (*AuthDisableResponse)(resp), toErr(ctx, err)
}

func (auth *authClient) AuthStatus(ctx context.Context) (*AuthStatusResponse, error) {
resp, err := auth.remote.AuthStatus(ctx, &pb.AuthStatusRequest{}, auth.callOpts...)
return (*AuthStatusResponse)(resp), toErr(ctx, err)
}

func (auth *authClient) UserAdd(ctx context.Context, name string, password string) (*AuthUserAddResponse, error) {
resp, err := auth.remote.UserAdd(ctx, &pb.AuthUserAddRequest{Name: name, Password: password, Options: &authpb.UserAddOptions{NoPassword: false}}, auth.callOpts...)
return (*AuthUserAddResponse)(resp), toErr(ctx, err)
Expand Down
4 changes: 4 additions & 0 deletions clientv3/retry.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,10 @@ func (rac *retryAuthClient) AuthDisable(ctx context.Context, in *pb.AuthDisableR
return rac.ac.AuthDisable(ctx, in, opts...)
}

func (rac *retryAuthClient) AuthStatus(ctx context.Context, in *pb.AuthStatusRequest, opts ...grpc.CallOption) (resp *pb.AuthStatusResponse, err error) {
return rac.ac.AuthStatus(ctx, in, opts...)
}

func (rac *retryAuthClient) UserAdd(ctx context.Context, in *pb.AuthUserAddRequest, opts ...grpc.CallOption) (resp *pb.AuthUserAddResponse, err error) {
return rac.ac.UserAdd(ctx, in, opts...)
}
Expand Down
25 changes: 25 additions & 0 deletions etcdctl/ctlv3/command/auth_command.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,35 @@ func NewAuthCommand() *cobra.Command {

ac.AddCommand(newAuthEnableCommand())
ac.AddCommand(newAuthDisableCommand())
ac.AddCommand(newAuthStatusCommand())

return ac
}

func newAuthStatusCommand() *cobra.Command {
return &cobra.Command{
Use: "status",
Short: "Returns authentication status",
Run: authStatusCommandFunc,
}
}

// authStatusCommandFunc executes the "auth status" command.
func authStatusCommandFunc(cmd *cobra.Command, args []string) {
if len(args) != 0 {
ExitWithError(ExitBadArgs, fmt.Errorf("auth status command does not accept any arguments"))
}

ctx, cancel := commandCtx(cmd)
result, err := mustClientFromCmd(cmd).Auth.AuthStatus(ctx)
cancel()
if err != nil {
ExitWithError(ExitError, err)
}

fmt.Println("Authentication Status:", result.Enabled)
}

func newAuthEnableCommand() *cobra.Command {
return &cobra.Command{
Use: "enable",
Expand Down
8 changes: 8 additions & 0 deletions etcdserver/api/v3rpc/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ func (as *AuthServer) AuthDisable(ctx context.Context, r *pb.AuthDisableRequest)
return resp, nil
}

func (as *AuthServer) AuthStatus(ctx context.Context, r *pb.AuthStatusRequest) (*pb.AuthStatusResponse, error) {
resp, err := as.authenticator.AuthStatus(ctx, r)
if err != nil {
return nil, togRPCError(err)
}
return resp, nil
}

func (as *AuthServer) Authenticate(ctx context.Context, r *pb.AuthenticateRequest) (*pb.AuthenticateResponse, error) {
resp, err := as.authenticator.Authenticate(ctx, r)
if err != nil {
Expand Down
Loading

0 comments on commit 3d74793

Please sign in to comment.