github.com/franc20/ayesa_sap@v7.0.0-beta.28.0.20200124003224-302d4d52fa6c+incompatible/integration/helpers/plugin_repo.go (about) 1 package helpers 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "io/ioutil" 8 "log" 9 "net/http" 10 "os" 11 "path/filepath" 12 13 "code.cloudfoundry.org/cli/util" 14 "code.cloudfoundry.org/cli/util/generic" 15 16 . "github.com/onsi/gomega" 17 . "github.com/onsi/gomega/ghttp" 18 ) 19 20 // Binary represents the metadata need to retrieve one of the binaries that makes up a plugin. 21 type Binary struct { 22 Checksum string `json:"checksum"` 23 Platform string `json:"platform"` 24 URL string `json:"url"` 25 } 26 27 // Plugin represents a plugin object provided by a plugin repo. 28 type Plugin struct { 29 Name string `json:"name"` 30 Version string `json:"version"` 31 Binaries []Binary `json:"binaries"` 32 } 33 34 // PluginRepository represents a repo response object describing a list of plugins available. 35 type PluginRepository struct { 36 Plugins []Plugin `json:"plugins"` 37 } 38 39 // PluginRepositoryServerWithPlugin represents a server used to provide downloadable plugins. 40 type PluginRepositoryServerWithPlugin struct { 41 server *Server 42 pluginPath string 43 } 44 45 // NewPluginRepositoryServer is used to configure and start a new plugin repo server, exposing the plugins contained 46 // in the pluginRepo. 47 func NewPluginRepositoryServer(pluginRepo PluginRepository) *Server { 48 return configurePluginRepositoryServer(NewTLSServer(), pluginRepo) 49 } 50 51 // NewPluginRepositoryServerWithPlugin is used to create a server to provide a single configurable_plugin 52 // with user provided name, version, and platform. 53 func NewPluginRepositoryServerWithPlugin(pluginType string, pluginName string, version string, platform string, shouldCalculateChecksum bool) *PluginRepositoryServerWithPlugin { 54 pluginRepoServer := PluginRepositoryServerWithPlugin{} 55 56 pluginRepoServer.Init(pluginType, pluginName, version, platform, shouldCalculateChecksum) 57 58 return &pluginRepoServer 59 } 60 61 // Init initializes a server to provide a single configurable_plugin with user provided name, version, and platform. 62 func (pluginRepoServer *PluginRepositoryServerWithPlugin) Init(pluginType string, pluginName string, version string, platform string, shouldCalculateChecksum bool) { 63 pluginPath := BuildConfigurablePlugin(pluginType, pluginName, version, 64 []PluginCommand{ 65 {Name: "some-command", Help: "some-command-help"}, 66 }, 67 ) 68 69 repoServer := NewServer() 70 71 pluginRepoServer.server = repoServer 72 pluginRepoServer.pluginPath = pluginPath 73 74 var ( 75 checksum []byte 76 err error 77 ) 78 79 if shouldCalculateChecksum { 80 checksum, err = util.NewSha1Checksum(pluginPath).ComputeFileSha1() 81 Expect(err).NotTo(HaveOccurred()) 82 } 83 84 baseFile := fmt.Sprintf("/%s", generic.ExecutableFilename(filepath.Base(pluginPath))) 85 downloadURL := fmt.Sprintf("%s%s", repoServer.URL(), baseFile) 86 pluginRepo := PluginRepository{ 87 Plugins: []Plugin{ 88 { 89 Name: pluginName, 90 Version: version, 91 Binaries: []Binary{ 92 { 93 Checksum: fmt.Sprintf("%x", checksum), 94 Platform: platform, 95 URL: downloadURL, 96 }, 97 }, 98 }, 99 }} 100 101 // Suppresses ginkgo server logs 102 repoServer.HTTPTestServer.Config.ErrorLog = log.New(&bytes.Buffer{}, "", 0) 103 104 jsonBytes, err := json.Marshal(pluginRepo) 105 Expect(err).ToNot(HaveOccurred()) 106 107 pluginData, err := ioutil.ReadFile(pluginPath) 108 Expect(err).ToNot(HaveOccurred()) 109 110 repoServer.AppendHandlers( 111 CombineHandlers( 112 VerifyRequest(http.MethodGet, "/list"), 113 RespondWith(http.StatusOK, jsonBytes), 114 ), 115 CombineHandlers( 116 VerifyRequest(http.MethodGet, "/list"), 117 RespondWith(http.StatusOK, jsonBytes), 118 ), 119 CombineHandlers( 120 VerifyRequest(http.MethodGet, baseFile), 121 RespondWith(http.StatusOK, pluginData), 122 ), 123 ) 124 } 125 126 // PluginSize is used to get the size in bytes of the single plugin provided by the pluginRepoServer 127 func (pluginRepoServer *PluginRepositoryServerWithPlugin) PluginSize() int64 { 128 fileinfo, err := os.Stat(pluginRepoServer.pluginPath) 129 Expect(err).NotTo(HaveOccurred()) 130 return fileinfo.Size() 131 } 132 133 // URL is used to get the pluginRepo's server url 134 func (pluginRepoServer *PluginRepositoryServerWithPlugin) URL() string { 135 return pluginRepoServer.server.URL() 136 } 137 138 // Close is used to destroy the repo server and cleanup any files 139 func (pluginRepoServer *PluginRepositoryServerWithPlugin) Cleanup() { 140 pluginRepoServer.server.Close() 141 Expect(os.RemoveAll(filepath.Dir(pluginRepoServer.pluginPath))).NotTo(HaveOccurred()) 142 } 143 144 // NewPluginRepositoryTLSServer is used to configure and start a new TLS plugin repo server, exposing the plugins contained 145 // in the pluginRepo. 146 func NewPluginRepositoryTLSServer(pluginRepo PluginRepository) *Server { 147 return configurePluginRepositoryServer(NewTLSServer(), pluginRepo) 148 } 149 150 func configurePluginRepositoryServer(server *Server, pluginRepo PluginRepository) *Server { 151 // Suppresses ginkgo server logs 152 server.HTTPTestServer.Config.ErrorLog = log.New(&bytes.Buffer{}, "", 0) 153 154 jsonBytes, err := json.Marshal(pluginRepo) 155 Expect(err).ToNot(HaveOccurred()) 156 157 server.AppendHandlers( 158 RespondWith(http.StatusOK, string(jsonBytes)), 159 RespondWith(http.StatusOK, string(jsonBytes)), 160 RespondWith(http.StatusOK, string(jsonBytes)), 161 RespondWith(http.StatusOK, string(jsonBytes)), 162 ) 163 164 return server 165 }