github.com/snyk/vervet/v6@v6.2.4/internal/cmd/resource.go (about) 1 package cmd 2 3 import ( 4 "fmt" 5 "os" 6 "path/filepath" 7 "sort" 8 9 "github.com/olekukonko/tablewriter" 10 "github.com/urfave/cli/v2" 11 12 "github.com/snyk/vervet/v6" 13 "github.com/snyk/vervet/v6/config" 14 "github.com/snyk/vervet/v6/internal/compiler" 15 ) 16 17 // ResourceCommand is the `vervet resource` subcommand. 18 var ResourceCommand = cli.Command{ 19 Name: "resource", 20 Aliases: []string{"rc"}, 21 Flags: []cli.Flag{ 22 &cli.StringFlag{ 23 Name: "config", 24 Aliases: []string{"c", "conf"}, 25 Usage: "Project configuration file", 26 }, 27 }, 28 Subcommands: []*cli.Command{{ 29 Name: "files", 30 Usage: "List OpenAPI files of versioned resources in a vervet project", 31 ArgsUsage: "[api [resource]]", 32 Action: ResourceFiles, 33 }, { 34 Name: "info", 35 Usage: "Information about versioned resources in a vervet project", 36 ArgsUsage: "[api [resource]]", 37 Action: ResourceShow, 38 }}, 39 } 40 41 // ResourceShow is a command that lists all the versions of matching resources. 42 // It takes optional arguments to filter the output: api resource. 43 func ResourceShow(ctx *cli.Context) error { 44 projectDir, configFile, err := projectConfig(ctx) 45 if err != nil { 46 return err 47 } 48 f, err := os.Open(configFile) 49 if err != nil { 50 return err 51 } 52 defer f.Close() 53 proj, err := config.Load(f) 54 if err != nil { 55 return err 56 } 57 err = os.Chdir(projectDir) 58 if err != nil { 59 return err 60 } 61 table := tablewriter.NewWriter(os.Stdout) 62 table.SetHeader([]string{"API", "Resource", "Version", "Path", "Method", "Operation"}) 63 for _, apiName := range proj.APINames() { 64 if apiArg := ctx.Args().Get(0); apiArg != "" && apiArg != apiName { 65 continue 66 } 67 api := proj.APIs[apiName] 68 for _, rcConfig := range api.Resources { 69 specFiles, err := compiler.ResourceSpecFiles(rcConfig) 70 if err != nil { 71 return err 72 } 73 resources, err := vervet.LoadResourceVersionsFileset(specFiles) 74 if err != nil { 75 return err 76 } 77 for _, version := range resources.Versions() { 78 rc, err := resources.At(version.String()) 79 if err != nil { 80 return err 81 } 82 if rcArg := ctx.Args().Get(1); rcArg != "" && rcArg != rc.Name { 83 continue 84 } 85 var pathNames []string 86 for k := range rc.Paths { 87 pathNames = append(pathNames, k) 88 } 89 sort.Strings(pathNames) 90 for _, pathName := range pathNames { 91 pathSpec := rc.Paths[pathName] 92 if pathSpec.Get != nil { 93 table.Append([]string{apiName, rc.Name, version.String(), pathName, "GET", pathSpec.Get.OperationID}) 94 } 95 if pathSpec.Post != nil { 96 table.Append([]string{apiName, rc.Name, version.String(), pathName, "POST", pathSpec.Post.OperationID}) 97 } 98 if pathSpec.Put != nil { 99 table.Append([]string{apiName, rc.Name, version.String(), pathName, "PUT", pathSpec.Put.OperationID}) 100 } 101 if pathSpec.Patch != nil { 102 table.Append([]string{apiName, rc.Name, version.String(), pathName, "PATCH", pathSpec.Patch.OperationID}) 103 } 104 if pathSpec.Delete != nil { 105 table.Append([]string{apiName, rc.Name, version.String(), pathName, "DELETE", pathSpec.Delete.OperationID}) 106 } 107 } 108 } 109 } 110 } 111 table.Render() 112 return nil 113 } 114 115 // ResourceFiles is a command that lists all versioned OpenAPI spec files of 116 // matching resources. 117 // It takes optional arguments to filter the output: api resource. 118 func ResourceFiles(ctx *cli.Context) error { 119 projectDir, configFile, err := projectConfig(ctx) 120 if err != nil { 121 return err 122 } 123 f, err := os.Open(configFile) 124 if err != nil { 125 return err 126 } 127 defer f.Close() 128 proj, err := config.Load(f) 129 if err != nil { 130 return err 131 } 132 err = os.Chdir(projectDir) 133 if err != nil { 134 return err 135 } 136 for _, apiName := range proj.APINames() { 137 if apiArg := ctx.Args().Get(0); apiArg != "" && apiArg != apiName { 138 continue 139 } 140 api := proj.APIs[apiName] 141 for _, rcConfig := range api.Resources { 142 specFiles, err := compiler.ResourceSpecFiles(rcConfig) 143 if err != nil { 144 return err 145 } 146 sort.Strings(specFiles) 147 for i := range specFiles { 148 rcName := filepath.Base(filepath.Dir(filepath.Dir(specFiles[i]))) 149 if rcArg := ctx.Args().Get(1); rcArg != "" && rcArg != rcName { 150 continue 151 } 152 fmt.Println(specFiles[i]) 153 } 154 } 155 } 156 return nil 157 }