Skip to content

Commit

Permalink
feat: create placeholder for missing admin tools + merged challenges …
Browse files Browse the repository at this point in the history
…with ps
  • Loading branch information
moul committed Jul 26, 2020
1 parent 049ecae commit c888589
Show file tree
Hide file tree
Showing 18 changed files with 7,809 additions and 4,142 deletions.
8 changes: 8 additions & 0 deletions api/errcode.proto
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,14 @@ enum ErrCode {
ErrChallengeIncompleteValidation = 4069;
ErrChallengeJSONMarshalPassphrases = 4070;
ErrNotEnoughCash = 4071;
ErrListActivities = 4072;
ErrListUsers = 4073;
ErrListChallenges = 4074;
ErrListOrganizations = 4075;
ErrListTeams = 4076;
ErrListChallengeSubscriptions = 4077;
ErrListCoupons = 4078;
ErrListAgents = 4079;

//// Pathwar Server (starting at 5001)

Expand Down
58 changes: 53 additions & 5 deletions api/pwapi.proto
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,14 @@ service Service {
// Admin
//

rpc AdminPS(AdminPS.Input) returns (AdminPS.Output) { option (google.api.http) = {get: "/admin/ps"}; }; // admin only
rpc AdminListChallenges(AdminListChallenges.Input) returns (AdminListChallenges.Output) { option (google.api.http) = {get: "/admin/list-challenges"}; }; // admin only
rpc AdminListAgents(AdminListAgents.Input) returns (AdminListAgents.Output) { option (google.api.http) = {get: "/admin/list-agents"}; }; // admin only
rpc AdminListCoupons(AdminListCoupons.Input) returns (AdminListCoupons.Output) { option (google.api.http) = {get: "/admin/list-coupons"}; }; // admin only
rpc AdminListOrganizations(AdminListOrganizations.Input) returns (AdminListOrganizations.Output) { option (google.api.http) = {get: "/admin/list-organizations"}; }; // admin only
rpc AdminListTeams(AdminListTeams.Input) returns (AdminListTeams.Output) { option (google.api.http) = {get: "/admin/list-teams"}; }; // admin only
rpc AdminListUsers(AdminListUsers.Input) returns (AdminListUsers.Output) { option (google.api.http) = {get: "/admin/list-users"}; }; // admin only
rpc AdminListActivities(AdminListActivities.Input) returns (AdminListActivities.Output) { option (google.api.http) = {get: "/admin/list-activities"}; }; // admin only
rpc AdminListChallengeSubscriptions(AdminListChallengeSubscriptions.Input) returns (AdminListChallengeSubscriptions.Output) { option (google.api.http) = {get: "/admin/list-challenge-subscriptions"}; }; // admin only
rpc AdminRedump(AdminRedump.Input) returns (AdminRedump.Output) { option (google.api.http) = {post: "/admin/redump"; body: "*"}; }; // admin only
rpc AdminChallengeAdd(AdminChallengeAdd.Input) returns (AdminChallengeAdd.Output) { option (google.api.http) = {post: "/admin/challenge-add"; body: "*"}; }; // admin only
rpc AdminChallengeFlavorAdd(AdminChallengeFlavorAdd.Input) returns (AdminChallengeFlavorAdd.Output) { option (google.api.http) = {post: "/admin/challenge-flavor-add"; body: "*"}; }; // admin only
Expand All @@ -100,17 +106,59 @@ message AdminRedump {
message Output {}
}

message AdminPS {
message AdminListChallenges {
message Input {}
message Output {
repeated pathwar.db.ChallengeInstance instances = 1;
repeated pathwar.db.Challenge challenges = 1;
}
}

message AdminListChallenges {
message AdminListAgents {
message Input {}
message Output {
repeated pathwar.db.Challenge challenges = 1;
repeated pathwar.db.Agent agents = 1;
}
}

message AdminListCoupons {
message Input {}
message Output {
repeated pathwar.db.Coupon coupons = 1;
}
}

message AdminListOrganizations {
message Input {}
message Output {
repeated pathwar.db.Organization organizations = 1;
}
}

message AdminListUsers {
message Input {}
message Output {
repeated pathwar.db.User users = 1;
}
}

message AdminListChallengeSubscriptions {
message Input {}
message Output {
repeated pathwar.db.ChallengeSubscription subscriptions = 1;
}
}

message AdminListTeams {
message Input {}
message Output {
repeated pathwar.db.Team teams = 1;
}
}

message AdminListActivities {
message Input {}
message Output {
repeated pathwar.db.Activity activities = 1;
}
}

Expand Down
2 changes: 1 addition & 1 deletion docs/gen.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

112 changes: 53 additions & 59 deletions go/cmd/pathwar/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
func adminCommand() *ffcli.Command {
var (
adminFlags = flag.NewFlagSet("admin", flag.ExitOnError)
adminPSFlags = flag.NewFlagSet("admin ps", flag.ExitOnError)
adminChallengesFlags = flag.NewFlagSet("admin challenges", flag.ExitOnError)
adminRedumpFlags = flag.NewFlagSet("admin redump", flag.ExitOnError)
adminChallengeAddFlags = flag.NewFlagSet("admin challenge add", flag.ExitOnError)
Expand Down Expand Up @@ -48,9 +47,9 @@ func adminCommand() *ffcli.Command {
Name: "admin",
Usage: "pathwar [global flags] admin [admin flags] <subcommand> [flags] [args...]",
Subcommands: []*ffcli.Command{{
Name: "ps",
Usage: "pathwar [global flags] admin [admin flags] ps [flags]",
FlagSet: adminPSFlags,
Name: "challenges",
Usage: "pathwar [global flags] admin [admin flags] challenges [flags]",
FlagSet: adminChallengesFlags,
Exec: func(args []string) error {
if err := globalPreRun(); err != nil {
return err
Expand All @@ -62,7 +61,7 @@ func adminCommand() *ffcli.Command {
return errcode.TODO.Wrap(err)
}

ret, err := apiClient.AdminPS(ctx, &pwapi.AdminPS_Input{})
ret, err := apiClient.AdminListChallenges(ctx, &pwapi.AdminListChallenges_Input{})
if err != nil {
return errcode.TODO.Wrap(err)
}
Expand All @@ -72,63 +71,19 @@ func adminCommand() *ffcli.Command {
return nil
}

// table
// tree
{
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"ID", "STATUS", "FLAVOR", "CREATED", "UPDATED", "CONFIG", "SEASON CHALLENGES", "PRICE/REWARD"})
table.SetAlignment(tablewriter.ALIGN_CENTER)
table.SetBorder(false)

for _, instance := range ret.Instances {
//fmt.Println(godev.PrettyJSONPB(instance))
id := fmt.Sprintf("%d", instance.ID)
status := instance.Status.String()
switch status {
case "Available":
status += " 🟢"
default:
status += " 🔴"
}
flavor := fmt.Sprintf("%s@%s", instance.Flavor.Challenge.Slug, instance.Flavor.Slug)
createdAgo := humanize.Time(*instance.CreatedAt)
updatedAgo := humanize.Time(*instance.UpdatedAt)
configStruct, _ := instance.ParseInstanceConfig()
config := godev.JSONPB(configStruct)
seasonChallenges := fmt.Sprintf("%d", len(instance.Flavor.SeasonChallenges))
price := "free"
if instance.Flavor.PurchasePrice > 0 {
price = fmt.Sprintf("$%d", instance.Flavor.PurchasePrice)
fmt.Println("TREE")
for _, challenge := range ret.Challenges {
fmt.Printf("- %s (%d)\n", challenge.Slug, challenge.ID)
for _, flavor := range challenge.Flavors {
fmt.Printf(" - %s (%d)\n", flavor.Slug, flavor.ID)
for _, instance := range flavor.Instances {
fmt.Printf(" - %d\n", instance.ID)
}
}
priceReward := fmt.Sprintf("%s / $%d", price, instance.Flavor.ValidationReward)
table.Append([]string{id, status, flavor, createdAgo, updatedAgo, config, seasonChallenges, priceReward})
}
table.Render()
}
return nil
},
}, {
Name: "challenges",
Usage: "pathwar [global flags] admin [admin flags] challenges [flags]",
FlagSet: adminChallengesFlags,
Exec: func(args []string) error {
if err := globalPreRun(); err != nil {
return err
}

ctx := context.Background()
apiClient, err := httpClientFromEnv(ctx)
if err != nil {
return errcode.TODO.Wrap(err)
}

ret, err := apiClient.AdminListChallenges(ctx, &pwapi.AdminListChallenges_Input{})
if err != nil {
return errcode.TODO.Wrap(err)
}

if jsonFormat {
fmt.Println(godev.PrettyJSONPB(&ret))
return nil
fmt.Println("")
}

// challenges table
Expand Down Expand Up @@ -197,6 +152,45 @@ func adminCommand() *ffcli.Command {
}
}
table.Render()
fmt.Println("")
}

// instances
{
fmt.Println("INSTANCES")
table := tablewriter.NewWriter(os.Stdout)
table.SetHeader([]string{"INSTANCE", "FLAVOR", "STATUS", "CREATED", "UPDATED", "CONFIG", "SEASON CHALLENGES", "PRICE/REWARD"})
table.SetAlignment(tablewriter.ALIGN_CENTER)
table.SetBorder(false)

for _, challenge := range ret.Challenges {
for _, flavor := range challenge.Flavors {
for _, instance := range flavor.Instances {
//fmt.Println(godev.PrettyJSONPB(instance))
id := fmt.Sprintf("%d", instance.ID)
status := instance.Status.String()
switch status {
case "Available":
status += " 🟢"
default:
status += " 🔴"
}
flavorSlug := fmt.Sprintf("%s@%s", challenge.Slug, flavor.Slug)
createdAgo := humanize.Time(*instance.CreatedAt)
updatedAgo := humanize.Time(*instance.UpdatedAt)
configStruct, _ := instance.ParseInstanceConfig()
config := godev.JSONPB(configStruct)
seasonChallenges := fmt.Sprintf("%d", len(flavor.SeasonChallenges))
price := "free"
if flavor.PurchasePrice > 0 {
price = fmt.Sprintf("$%d", flavor.PurchasePrice)
}
priceReward := fmt.Sprintf("%s / $%d", price, flavor.ValidationReward)
table.Append([]string{id, flavorSlug, status, createdAgo, updatedAgo, config, seasonChallenges, priceReward})
}
}
}
table.Render()
}

return nil
Expand Down
4 changes: 2 additions & 2 deletions go/gen.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit c888589

Please sign in to comment.