Skip to content

Commit

Permalink
Move admin-only RPCs into a separate Admin service. (#354)
Browse files Browse the repository at this point in the history
  • Loading branch information
timburks authored Oct 21, 2021
1 parent 76bbe75 commit e1616a8
Show file tree
Hide file tree
Showing 66 changed files with 3,692 additions and 2,899 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ server with the following:
Now you can check your server and configuration with the
automatically-generated `apg` client:

`apg registry get-status`
`apg admin get-status`

Next run a suite of tests with `make test` and see a corresponding walkthrough
of API features in [tests/demo/walkthrough.sh](tests/demo/walkthrough.sh). For
Expand Down Expand Up @@ -275,7 +275,7 @@ and adding the "Cloud Run Invoker" role to the special username "allUsers".

Now you can call the API with your generated CLI.

`apg registry get-status`
`apg admin get-status`

You can also verify your installation by running `make test`. This will run
tests against the same service that your CLI is configured to use via the
Expand Down
9 changes: 8 additions & 1 deletion auth/CLOUDRUN.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,11 @@ export APG_REGISTRY_CLIENT_EMAIL=$(gcloud config list account --format "value(co
export APG_REGISTRY_TOKEN=$(gcloud auth print-identity-token ${APG_REGISTRY_CLIENT_EMAIL})

# Calls don't use an API key.
unset APG_REGISTRY_API_KEY
unset APG_REGISTRY_API_KEY

# Duplicate the client configuration for the Admin service.
unset APG_ADMIN_INSECURE
export APG_ADMIN_ADDRESS=$APG_REGISTRY_ADDRESS
export APG_ADMIN_AUDIENCES=$APG_REGISTRY_AUDIENCES
export APG_ADMIN_TOKEN=$APG_REGISTRY_TOKEN
unset APG_ADMIN_API_KEY
9 changes: 8 additions & 1 deletion auth/ENVOY.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,11 @@ export APG_REGISTRY_CLIENT_EMAIL=$(gcloud config list account --format "value(co
export APG_REGISTRY_TOKEN=$(gcloud auth print-identity-token ${APG_REGISTRY_CLIENT_EMAIL})

# Calls don't use an API key.
unset APG_REGISTRY_API_KEY
unset APG_REGISTRY_API_KEY

# Duplicate the client configuration for the Admin service.
export APG_ADMIN_ADDRESS=$APG_REGISTRY_ADDRESS
export APG_ADMIN_AUDIENCES=$APG_REGISTRY_AUDIENCES
export APG_ADMIN_INSECURE=$APG_REGISTRY_INSECURE
export APG_ADMIN_TOKEN=$APG_REGISTRY_TOKEN
unset APG_ADMIN_API_KEY
6 changes: 6 additions & 0 deletions auth/GKE.sh
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,9 @@ export APG_REGISTRY_TOKEN=$(gcloud auth print-identity-token ${APG_REGISTRY_CLIE
unset APG_REGISTRY_API_KEY
export APG_REGISTRY_INSECURE=1

# Duplicate the client configuration for the Admin service
export APG_ADMIN_ADDRESS=$APG_REGISTRY_ADDRESS
export APG_ADMIN_AUDIENCES=$APG_REGISTRY_AUDIENCES
export APG_ADMIN_TOKEN=$APG_REGISTRY_TOKEN
export APG_ADMIN_INSECURE=$APG_REGISTRY_INSECURE
unset APG_ADMIN_API_KEY
7 changes: 7 additions & 0 deletions auth/LOCAL.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,10 @@ export APG_REGISTRY_INSECURE=1
# Local calls don't need authentication.
unset APG_REGISTRY_TOKEN
unset APG_REGISTRY_API_KEY

# Duplicate the client configuration for the Admin service.
export APG_ADMIN_ADDRESS=$APG_REGISTRY_ADDRESS
export APG_ADMIN_AUDIENCES=$APG_REGISTRY_AUDIENCES
export APG_ADMIN_INSECURE=$APG_REGISTRY_INSECURE
unset APG_ADMIN_TOKEN
unset APG_ADMIN_API_KEY
92 changes: 92 additions & 0 deletions cmd/apg/admin_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Code generated. DO NOT EDIT.

package main

import (
"fmt"

"github.com/spf13/cobra"
"github.com/spf13/viper"
"golang.org/x/oauth2"
"google.golang.org/api/option"
"google.golang.org/grpc"

gapic "github.com/apigee/registry/gapic"
)

var AdminConfig *viper.Viper
var AdminClient *gapic.AdminClient
var AdminSubCommands []string = []string{
"get-status",
"list-projects",
"get-project",
"create-project",
"update-project",
"delete-project",
}

func init() {
rootCmd.AddCommand(AdminServiceCmd)

AdminConfig = viper.New()
AdminConfig.SetEnvPrefix("APG_ADMIN")
AdminConfig.AutomaticEnv()

AdminServiceCmd.PersistentFlags().Bool("insecure", false, "Make insecure client connection. Or use APG_ADMIN_INSECURE. Must be used with \"address\" option")
AdminConfig.BindPFlag("insecure", AdminServiceCmd.PersistentFlags().Lookup("insecure"))
AdminConfig.BindEnv("insecure")

AdminServiceCmd.PersistentFlags().String("address", "", "Set API address used by client. Or use APG_ADMIN_ADDRESS.")
AdminConfig.BindPFlag("address", AdminServiceCmd.PersistentFlags().Lookup("address"))
AdminConfig.BindEnv("address")

AdminServiceCmd.PersistentFlags().String("token", "", "Set Bearer token used by the client. Or use APG_ADMIN_TOKEN.")
AdminConfig.BindPFlag("token", AdminServiceCmd.PersistentFlags().Lookup("token"))
AdminConfig.BindEnv("token")

AdminServiceCmd.PersistentFlags().String("api_key", "", "Set API Key used by the client. Or use APG_ADMIN_API_KEY.")
AdminConfig.BindPFlag("api_key", AdminServiceCmd.PersistentFlags().Lookup("api_key"))
AdminConfig.BindEnv("api_key")
}

var AdminServiceCmd = &cobra.Command{
Use: "admin",
Short: "The Admin service supports setup and operation of...",
Long: "The Admin service supports setup and operation of an API registry. It is typically not included in hosted versions of the API.",
ValidArgs: AdminSubCommands,
PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) {
var opts []option.ClientOption

address := AdminConfig.GetString("address")
if address != "" {
opts = append(opts, option.WithEndpoint(address))
}

if AdminConfig.GetBool("insecure") {
if address == "" {
return fmt.Errorf("Missing address to use with insecure connection")
}

conn, err := grpc.Dial(address, grpc.WithInsecure())
if err != nil {
return err
}
opts = append(opts, option.WithGRPCConn(conn))
}

if token := AdminConfig.GetString("token"); token != "" {
opts = append(opts, option.WithTokenSource(oauth2.StaticTokenSource(
&oauth2.Token{
AccessToken: token,
TokenType: "Bearer",
})))
}

if key := AdminConfig.GetString("api_key"); key != "" {
opts = append(opts, option.WithAPIKey(key))
}

AdminClient, err = gapic.NewAdminClient(ctx, opts...)
return
},
}
6 changes: 3 additions & 3 deletions cmd/apg/create-project.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ var CreateProjectInput rpcpb.CreateProjectRequest
var CreateProjectFromFile string

func init() {
RegistryServiceCmd.AddCommand(CreateProjectCmd)
AdminServiceCmd.AddCommand(CreateProjectCmd)

CreateProjectInput.Project = new(rpcpb.Project)

Expand Down Expand Up @@ -64,9 +64,9 @@ var CreateProjectCmd = &cobra.Command{
}

if Verbose {
printVerboseInput("Registry", "CreateProject", &CreateProjectInput)
printVerboseInput("Admin", "CreateProject", &CreateProjectInput)
}
resp, err := RegistryClient.CreateProject(ctx, &CreateProjectInput)
resp, err := AdminClient.CreateProject(ctx, &CreateProjectInput)

if Verbose {
fmt.Print("Output: ")
Expand Down
6 changes: 3 additions & 3 deletions cmd/apg/delete-project.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var DeleteProjectInput rpcpb.DeleteProjectRequest
var DeleteProjectFromFile string

func init() {
RegistryServiceCmd.AddCommand(DeleteProjectCmd)
AdminServiceCmd.AddCommand(DeleteProjectCmd)

DeleteProjectCmd.Flags().StringVar(&DeleteProjectInput.Name, "name", "", "Required. The name of the project to delete. Format:...")

Expand Down Expand Up @@ -56,9 +56,9 @@ var DeleteProjectCmd = &cobra.Command{
}

if Verbose {
printVerboseInput("Registry", "DeleteProject", &DeleteProjectInput)
printVerboseInput("Admin", "DeleteProject", &DeleteProjectInput)
}
err = RegistryClient.DeleteProject(ctx, &DeleteProjectInput)
err = AdminClient.DeleteProject(ctx, &DeleteProjectInput)

return err
},
Expand Down
6 changes: 3 additions & 3 deletions cmd/apg/get-project.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ var GetProjectInput rpcpb.GetProjectRequest
var GetProjectFromFile string

func init() {
RegistryServiceCmd.AddCommand(GetProjectCmd)
AdminServiceCmd.AddCommand(GetProjectCmd)

GetProjectCmd.Flags().StringVar(&GetProjectInput.Name, "name", "", "Required. The name of the project to retrieve. Format:...")

Expand Down Expand Up @@ -58,9 +58,9 @@ var GetProjectCmd = &cobra.Command{
}

if Verbose {
printVerboseInput("Registry", "GetProject", &GetProjectInput)
printVerboseInput("Admin", "GetProject", &GetProjectInput)
}
resp, err := RegistryClient.GetProject(ctx, &GetProjectInput)
resp, err := AdminClient.GetProject(ctx, &GetProjectInput)

if Verbose {
fmt.Print("Output: ")
Expand Down
10 changes: 5 additions & 5 deletions cmd/apg/get-status.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,23 @@ import (
var GetStatusInput emptypb.Empty

func init() {
RegistryServiceCmd.AddCommand(GetStatusCmd)
AdminServiceCmd.AddCommand(GetStatusCmd)

}

var GetStatusCmd = &cobra.Command{
Use: "get-status",
Short: "GetStatus returns the status of the service. ...",
Long: "GetStatus returns the status of the service. GetStatus is for verifying open source deployments only and is not included in hosted versions of the...",
Short: "GetStatus returns the status of the service. (--...",
Long: "GetStatus returns the status of the service. (-- api-linter: core::0131::request-message-name=disabled aip.dev/not-precedent: Not in the...",
PreRun: func(cmd *cobra.Command, args []string) {

},
RunE: func(cmd *cobra.Command, args []string) (err error) {

if Verbose {
printVerboseInput("Registry", "GetStatus", &GetStatusInput)
printVerboseInput("Admin", "GetStatus", &GetStatusInput)
}
resp, err := RegistryClient.GetStatus(ctx, &GetStatusInput)
resp, err := AdminClient.GetStatus(ctx, &GetStatusInput)

if Verbose {
fmt.Print("Output: ")
Expand Down
6 changes: 3 additions & 3 deletions cmd/apg/list-projects.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ var ListProjectsInput rpcpb.ListProjectsRequest
var ListProjectsFromFile string

func init() {
RegistryServiceCmd.AddCommand(ListProjectsCmd)
AdminServiceCmd.AddCommand(ListProjectsCmd)

ListProjectsCmd.Flags().Int32Var(&ListProjectsInput.PageSize, "page_size", 10, "Default is 10. The maximum number of projects to return. The...")

Expand Down Expand Up @@ -62,9 +62,9 @@ var ListProjectsCmd = &cobra.Command{
}

if Verbose {
printVerboseInput("Registry", "ListProjects", &ListProjectsInput)
printVerboseInput("Admin", "ListProjects", &ListProjectsInput)
}
iter := RegistryClient.ListProjects(ctx, &ListProjectsInput)
iter := AdminClient.ListProjects(ctx, &ListProjectsInput)

// populate iterator with a page
_, err = iter.Next()
Expand Down
6 changes: 0 additions & 6 deletions cmd/apg/registry_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@ import (
var RegistryConfig *viper.Viper
var RegistryClient *gapic.RegistryClient
var RegistrySubCommands []string = []string{
"get-status",
"list-projects",
"get-project",
"create-project",
"update-project",
"delete-project",
"list-apis",
"get-api",
"create-api",
Expand Down
6 changes: 3 additions & 3 deletions cmd/apg/update-project.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ var UpdateProjectInput rpcpb.UpdateProjectRequest
var UpdateProjectFromFile string

func init() {
RegistryServiceCmd.AddCommand(UpdateProjectCmd)
AdminServiceCmd.AddCommand(UpdateProjectCmd)

UpdateProjectInput.Project = new(rpcpb.Project)

Expand Down Expand Up @@ -68,9 +68,9 @@ var UpdateProjectCmd = &cobra.Command{
}

if Verbose {
printVerboseInput("Registry", "UpdateProject", &UpdateProjectInput)
printVerboseInput("Admin", "UpdateProject", &UpdateProjectInput)
}
resp, err := RegistryClient.UpdateProject(ctx, &UpdateProjectInput)
resp, err := AdminClient.UpdateProject(ctx, &UpdateProjectInput)

if Verbose {
fmt.Print("Output: ")
Expand Down
1 change: 1 addition & 0 deletions cmd/registry-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ func main() {

reflection.Register(grpcServer)
rpc.RegisterRegistryServer(grpcServer, registryServer)
rpc.RegisterAdminServer(grpcServer, registryServer)

go func() {
_ = grpcServer.Serve(listener)
Expand Down
11 changes: 8 additions & 3 deletions cmd/registry/cmd/annotate/annotate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,20 @@ func TestAnnotate(t *testing.T) {
t.Fatalf("Error creating client: %+v", err)
}
defer registryClient.Close()
adminClient, err := connection.NewAdminClient(ctx)
if err != nil {
t.Fatalf("Error creating client: %+v", err)
}
defer adminClient.Close()
// Clear the test project.
err = registryClient.DeleteProject(ctx, &rpc.DeleteProjectRequest{
err = adminClient.DeleteProject(ctx, &rpc.DeleteProjectRequest{
Name: projectName,
})
if err != nil && status.Code(err) != codes.NotFound {
t.Fatalf("Error deleting test project: %+v", err)
}
// Create the test project.
_, err = registryClient.CreateProject(ctx, &rpc.CreateProjectRequest{
_, err = adminClient.CreateProject(ctx, &rpc.CreateProjectRequest{
ProjectId: projectID,
Project: &rpc.Project{
DisplayName: "Test",
Expand Down Expand Up @@ -168,7 +173,7 @@ func TestAnnotate(t *testing.T) {
req := &rpc.DeleteProjectRequest{
Name: projectName,
}
err = registryClient.DeleteProject(ctx, req)
err = adminClient.DeleteProject(ctx, req)
if err != nil {
t.Fatalf("Failed to delete test project: %s", err)
}
Expand Down
Loading

0 comments on commit e1616a8

Please sign in to comment.