github.com/minio/console@v1.3.0/api/admin_releases.go (about) 1 // This file is part of MinIO Console Server 2 // Copyright (c) 2023 MinIO, Inc. 3 // 4 // This program is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Affero General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Affero General Public License for more details. 13 // 14 // You should have received a copy of the GNU Affero General Public License 15 // along with this program. If not, see <http://www.gnu.org/licenses/>. 16 17 package api 18 19 import ( 20 "context" 21 "encoding/json" 22 "fmt" 23 "net/http" 24 "net/url" 25 "time" 26 27 "github.com/minio/console/pkg/utils" 28 29 "github.com/go-openapi/runtime/middleware" 30 "github.com/minio/console/api/operations" 31 release "github.com/minio/console/api/operations/release" 32 "github.com/minio/console/models" 33 "github.com/minio/pkg/v2/env" 34 ) 35 36 var ( 37 releaseServiceHostEnvVar = "RELEASE_SERVICE_HOST" 38 defaultReleaseServiceHost = "https://enterprise-updates.ic.min.dev" 39 ) 40 41 func registerReleasesHandlers(api *operations.ConsoleAPI) { 42 api.ReleaseListReleasesHandler = release.ListReleasesHandlerFunc(func(params release.ListReleasesParams, session *models.Principal) middleware.Responder { 43 resp, err := GetReleaseListResponse(session, params) 44 if err != nil { 45 return release.NewListReleasesDefault(err.Code).WithPayload(err.APIError) 46 } 47 return release.NewListReleasesOK().WithPayload(resp) 48 }) 49 } 50 51 func GetReleaseListResponse(_ *models.Principal, params release.ListReleasesParams) (*models.ReleaseListResponse, *CodedAPIError) { 52 ctx, cancel := context.WithCancel(params.HTTPRequest.Context()) 53 defer cancel() 54 repo := params.Repo 55 currentRelease := "" 56 if params.Current != nil { 57 currentRelease = *params.Current 58 } 59 search := "" 60 if params.Search != nil { 61 search = *params.Search 62 } 63 filter := "" 64 if params.Filter != nil { 65 filter = *params.Filter 66 } 67 ctx = context.WithValue(ctx, utils.ContextClientIP, getClientIP(params.HTTPRequest)) 68 return releaseList(ctx, repo, currentRelease, search, filter) 69 } 70 71 func releaseList(ctx context.Context, repo, currentRelease, search, filter string) (*models.ReleaseListResponse, *CodedAPIError) { 72 serviceURL := getReleaseServiceURL() 73 clientIP := utils.ClientIPFromContext(ctx) 74 releases, err := getReleases(serviceURL, repo, currentRelease, search, filter, clientIP) 75 if err != nil { 76 return nil, ErrorWithContext(ctx, err) 77 } 78 return releases, nil 79 } 80 81 func getReleaseServiceURL() string { 82 host := env.Get(releaseServiceHostEnvVar, defaultReleaseServiceHost) 83 return fmt.Sprintf("%s/releases", host) 84 } 85 86 func getReleases(endpoint, repo, currentRelease, search, filter, clientIP string) (*models.ReleaseListResponse, error) { 87 rl := &models.ReleaseListResponse{} 88 req, err := http.NewRequest(http.MethodGet, endpoint, nil) 89 if err != nil { 90 return nil, err 91 } 92 q := &url.Values{} 93 q.Add("repo", repo) 94 q.Add("search", search) 95 q.Add("filter", filter) 96 q.Add("current", currentRelease) 97 req.URL.RawQuery = q.Encode() 98 req.Header.Set("Content-Type", "application/json") 99 100 client := GetConsoleHTTPClient("", clientIP) 101 client.Timeout = time.Second * 5 102 103 resp, err := client.Do(req) 104 if err != nil { 105 return nil, err 106 } 107 defer resp.Body.Close() 108 if resp.StatusCode != http.StatusOK { 109 return nil, fmt.Errorf("error getting releases: %s", resp.Status) 110 } 111 err = json.NewDecoder(resp.Body).Decode(&rl) 112 if err != nil { 113 return nil, err 114 } 115 return rl, nil 116 }