fix comments for list api

pull/8423/head
ys.achinta 5 years ago
parent daf8776453
commit 933652d56d

@ -2,6 +2,7 @@ package main
import ( import (
"fmt" "fmt"
"github.com/gorilla/mux"
"net/http" "net/http"
"helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/action"
@ -24,9 +25,8 @@ func setContentType(next http.Handler) http.Handler {
} }
func startServer() { func startServer() {
router := http.NewServeMux() router := mux.NewRouter()
//TODO: use gorilla mux and add middleware to write content type and other headers
app := servercontext.App() app := servercontext.App()
logger.Setup("debug") logger.Setup("debug")
@ -42,10 +42,10 @@ func startServer() {
api.NewUpgrader(actionUpgrade), api.NewUpgrader(actionUpgrade),
api.NewHistory(actionHistory)) api.NewHistory(actionHistory))
router.Handle("/ping", setContentType(ping.Handler())) router.Handle("/ping", setContentType(ping.Handler())).Methods(http.MethodGet)
router.Handle("/list", setContentType(api.List(service))) router.Handle("/list", setContentType(api.List(service))).Methods(http.MethodPost)
router.Handle("/install", setContentType(api.Install(service))) router.Handle("/install", setContentType(api.Install(service))).Methods(http.MethodPost)
router.Handle("/upgrade", setContentType(api.Upgrade(service))) router.Handle("/upgrade", setContentType(api.Upgrade(service))).Methods(http.MethodPost)
err := http.ListenAndServe(fmt.Sprintf(":%d", 8080), router) err := http.ListenAndServe(fmt.Sprintf(":%d", 8080), router)
if err != nil { if err != nil {

@ -26,6 +26,7 @@ require (
github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 // indirect github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 // indirect
github.com/google/go-cmp v0.3.1 // indirect github.com/google/go-cmp v0.3.1 // indirect
github.com/googleapis/gnostic v0.3.1 // indirect github.com/googleapis/gnostic v0.3.1 // indirect
github.com/gorilla/mux v1.7.4
github.com/gosuri/uitable v0.0.1 github.com/gosuri/uitable v0.0.1
github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f // indirect github.com/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f // indirect
github.com/hashicorp/golang-lru v0.5.3 // indirect github.com/hashicorp/golang-lru v0.5.3 // indirect

@ -286,6 +286,8 @@ github.com/gorilla/handlers v1.4.0 h1:XulKRWSQK5uChr4pEgSE4Tc/OcmnU9GJuSwdog/tZs
github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/handlers v1.4.0/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U= github.com/gorilla/mux v1.7.0 h1:tOSd0UKHQd6urX6ApfOn4XdBMY6Sh1MfxV3kmaazO+U=
github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc=
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=

@ -17,6 +17,7 @@ limitations under the License.
package action package action
import ( import (
"fmt"
"path" "path"
"regexp" "regexp"
@ -154,6 +155,8 @@ func (l *List) Run() ([]*release.Release, error) {
results, err := l.cfg.Releases.List(func(rel *release.Release) bool { results, err := l.cfg.Releases.List(func(rel *release.Release) bool {
// Skip anything that the mask doesn't cover // Skip anything that the mask doesn't cover
currentStatus := l.StateMask.FromName(rel.Info.Status.String()) currentStatus := l.StateMask.FromName(rel.Info.Status.String())
fmt.Println("state mask", l.StateMask)
fmt.Println("current status", currentStatus)
if l.StateMask&currentStatus == 0 { if l.StateMask&currentStatus == 0 {
return false return false
} }

@ -2,6 +2,7 @@ package api
import ( import (
"encoding/json" "encoding/json"
"io"
"net/http" "net/http"
"helm.sh/helm/v3/pkg/api/logger" "helm.sh/helm/v3/pkg/api/logger"
@ -33,32 +34,27 @@ func List(svc Service) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var response ListResponse var response ListResponse
var request ListRequest var request ListRequest
decoder := json.NewDecoder(r.Body) if err := json.NewDecoder(r.Body).Decode(&request); err == io.EOF || err != nil {
if err := decoder.Decode(&request); err != nil { logger.Errorf("[List] error decoding request: %v", err.Error())
logger.Errorf("[List] error decoding request: %v", err)
response.Error = err.Error()
payload, _ := json.Marshal(response)
w.WriteHeader(http.StatusBadRequest) w.WriteHeader(http.StatusBadRequest)
w.Write(payload) response.Error = err.Error()
json.NewEncoder(w).Encode(response)
return return
} }
defer r.Body.Close() defer r.Body.Close()
helmReleases, err := svc.List(request.ReleaseStatus) helmReleases, err := svc.List(request.ReleaseStatus, request.NameSpace)
if err != nil { if err != nil {
respondInstallError(w, "error while listing charts: %v", err) respondInstallError(w, "error while listing charts: %v", err)
return
} }
response = ListResponse{"", helmReleases} response = ListResponse{"", helmReleases}
payload, err := json.Marshal(response) err = json.NewEncoder(w).Encode(response)
if err != nil { if err != nil {
respondInstallError(w, "error writing response: %v", err) respondInstallError(w, "error writing response: %v", err)
return return
} }
w.Write(payload)
}) })
} }

@ -1,8 +1,8 @@
package api_test package api_test
import ( import (
"encoding/json"
"fmt" "fmt"
"io/ioutil"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"strings" "strings"
@ -42,8 +42,8 @@ func (m *mockList) SetStateMask() {
m.Called() m.Called()
} }
func (m *mockList) SetState(state action.ListStates) { func (m *mockList) SetConfig(state action.ListStates, allNameSpaces bool) {
m.Called(state) m.Called(state, allNameSpaces)
} }
func (s *ListTestSuite) SetupSuite() { func (s *ListTestSuite) SetupSuite() {
@ -68,43 +68,53 @@ func (s *ListTestSuite) TestShouldReturnReleasesWhenSuccessfulAPICall() {
timeFromStr, _ := time.Parse(layout, str) timeFromStr, _ := time.Parse(layout, str)
body := `{"release_status":"deployed"}` body := `{"release_status":"deployed"}`
req, _ := http.NewRequest("POST", fmt.Sprintf("%s/list", s.server.URL), strings.NewReader(body)) req, _ := http.NewRequest("POST", fmt.Sprintf("%s/list", s.server.URL), strings.NewReader(body))
releases := []*release.Release{
{ releases := []*release.Release{{Name: "test-release",
Name: "test-release", Namespace: "test-namespace",
Namespace: "test-namespace", Info: &release.Info{Status: release.StatusDeployed, LastDeployed: timeFromStr},
Info: &release.Info{Status: release.StatusDeployed, LastDeployed: timeFromStr}, Version: 1,
Version: 1, Chart: &chart.Chart{Metadata: &chart.Metadata{Name: "test-release", Version: "0.1", AppVersion: "0.1"}},
Chart: &chart.Chart{Metadata: &chart.Metadata{Name: "test-release", Version: "0.1", AppVersion: "0.1"}}, }}
},
}
s.mockList.On("SetStateMask") s.mockList.On("SetStateMask")
s.mockList.On("SetState", action.ListDeployed) s.mockList.On("SetConfig", action.ListDeployed, true)
s.mockList.On("Run").Return(releases, nil) s.mockList.On("Run").Return(releases, nil)
resp, httpErr := http.DefaultClient.Do(req) res, err := http.DefaultClient.Do(req)
assert.Equal(s.T(), 200, res.StatusCode)
assert.Equal(s.T(), 200, resp.StatusCode) var actualResponse api.ListResponse
err = json.NewDecoder(res.Body).Decode(&actualResponse)
expectedResponse := `{"releases":[{"name":"test-release","namespace":"test-namespace","revision":1,"updated_at":"2014-11-12T11:45:26.371Z","status":"deployed","chart":"test-release-0.1","app_version":"0.1"}]}` expectedResponse := api.ListResponse{Error: "",
respBody, err := ioutil.ReadAll(resp.Body) Releases: []api.Release{{"test-release",
"test-namespace",
1,
timeFromStr,
release.StatusDeployed,
"test-release-0.1",
"0.1",
}}}
assert.Equal(s.T(), expectedResponse, string(respBody)) assert.Equal(s.T(), expectedResponse.Releases[0], actualResponse.Releases[0])
require.NoError(s.T(), httpErr)
require.NoError(s.T(), err) require.NoError(s.T(), err)
s.mockList.AssertExpectations(s.T()) s.mockList.AssertExpectations(s.T())
} }
func (s *ListTestSuite) TestShouldReturnBadRequestErrorIfItHasInvalidCharacter() { func (s *ListTestSuite) TestShouldReturnBadRequestErrorIfItHasInvalidCharacter() {
body := `{"request_id":"test-request-id""""}` body := `{"release_status":"unknown""""}`
req, _ := http.NewRequest("POST", fmt.Sprintf("%s/list", s.server.URL), strings.NewReader(body)) req, _ := http.NewRequest("POST", fmt.Sprintf("%s/list", s.server.URL), strings.NewReader(body))
resp, err := http.DefaultClient.Do(req) res, err := http.DefaultClient.Do(req)
assert.Equal(s.T(), 400, res.StatusCode)
expectedResponse := "invalid character '\"' after object key:value pair"
assert.Equal(s.T(), 400, resp.StatusCode) var actualResponse api.ListResponse
err = json.NewDecoder(res.Body).Decode(&actualResponse)
expectedResponse := `{"error":"invalid character '\"' after object key:value pair"}` assert.Equal(s.T(), expectedResponse, actualResponse.Error)
respBody, _ := ioutil.ReadAll(resp.Body)
assert.Equal(s.T(), expectedResponse, string(respBody))
require.NoError(s.T(), err) require.NoError(s.T(), err)
} }

@ -12,13 +12,14 @@ type Lister struct {
type ListRunner interface { type ListRunner interface {
Run() ([]*release.Release, error) Run() ([]*release.Release, error)
SetStateMask() SetStateMask()
SetState(state action.ListStates) SetConfig(state action.ListStates, allNameSpaces bool)
} }
func NewList(action *action.List) *Lister { func NewList(action *action.List) *Lister {
return &Lister{action} return &Lister{action}
} }
func (l *Lister) SetState(state action.ListStates) { func (l *Lister) SetConfig(state action.ListStates, allNameSpaces bool) {
l.StateMask = state l.StateMask = state
l.AllNamespaces = allNameSpaces
} }

@ -4,7 +4,6 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"strings" "strings"
"helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/action"
@ -140,7 +139,7 @@ func (s Service) validate(icfg ReleaseConfig, values ChartValues) error {
return nil return nil
} }
func (s Service) List(releaseStatus string) ([]Release, error) { func (s Service) List(releaseStatus string, namespace string) ([]Release, error) {
listStates := new(action.ListStates) listStates := new(action.ListStates)
state := action.ListAll state := action.ListAll
@ -152,8 +151,14 @@ func (s Service) List(releaseStatus string) ([]Release, error) {
return nil, errors.New("invalid release status") return nil, errors.New("invalid release status")
} }
s.ListRunner.SetState(state) allNameSpaces := true
if namespace != "" {
allNameSpaces = false
}
s.ListRunner.SetConfig(state, allNameSpaces)
s.ListRunner.SetStateMask() s.ListRunner.SetStateMask()
releases, err := s.ListRunner.Run() releases, err := s.ListRunner.Run()
if err != nil { if err != nil {
return nil, err return nil, err

@ -277,11 +277,11 @@ func (s *ServiceTestSuite) TestUpgradeShouldReturnErrorOnInvalidChart() {
func (s *ServiceTestSuite) TestListShouldReturnErrorOnFailureOfListRun() { func (s *ServiceTestSuite) TestListShouldReturnErrorOnFailureOfListRun() {
var releases []*release.Release var releases []*release.Release
releaseStatus := "deployed" releaseStatus := "deployed"
s.lister.On("SetState", action.ListDeployed) s.lister.On("SetConfig", action.ListDeployed, false)
s.lister.On("SetStateMask") s.lister.On("SetStateMask")
s.lister.On("Run").Return(releases, errors.New("cluster issue")) s.lister.On("Run").Return(releases, errors.New("cluster issue"))
res, err := s.svc.List(releaseStatus) res, err := s.svc.List(releaseStatus, "test-namespace")
t := s.T() t := s.T()
assert.Error(t, err, "cluster issue") assert.Error(t, err, "cluster issue")
@ -293,51 +293,41 @@ func (s *ServiceTestSuite) TestListShouldReturnAllReleasesIfNoFilterIsPassed() {
layout := "2006-01-02T15:04:05.000Z" layout := "2006-01-02T15:04:05.000Z"
str := "2014-11-12T11:45:26.371Z" str := "2014-11-12T11:45:26.371Z"
releaseStatus := "" releaseStatus := ""
var releases []*release.Release
timeFromStr, _ := time.Parse(layout, str) timeFromStr, _ := time.Parse(layout, str)
releases = append(releases,
&release.Release{Name: "test-release",
Namespace: "test-namespace",
Info: &release.Info{Status: release.StatusDeployed, LastDeployed: timeFromStr},
Version: 1,
Chart: &chart.Chart{Metadata: &chart.Metadata{Name: "test-release", Version: "0.1", AppVersion: "0.1"}},
})
s.lister.On("SetState", action.ListAll)
s.lister.On("SetStateMask")
releases := []*release.Release{{Name: "test-release",
Namespace: "test-namespace",
Info: &release.Info{Status: release.StatusDeployed, LastDeployed: timeFromStr},
Version: 1,
Chart: &chart.Chart{Metadata: &chart.Metadata{Name: "test-release", Version: "0.1", AppVersion: "0.1"}},
}}
s.lister.On("SetConfig", action.ListAll, false)
s.lister.On("SetStateMask")
s.lister.On("Run").Return(releases, nil) s.lister.On("Run").Return(releases, nil)
res, err := s.svc.List(releaseStatus) res, err := s.svc.List(releaseStatus, "test-namespace")
t := s.T() t := s.T()
assert.NoError(t, err) assert.NoError(t, err)
require.NotNil(t, res) require.NotNil(t, res)
var response []api.Release response := []api.Release{{"test-release",
response = append(response, api.Release{Name: "test-release", "test-namespace",
Namespace: "test-namespace", 1,
Revision: 1, timeFromStr,
Updated: timeFromStr, release.StatusDeployed,
Status: release.StatusDeployed, "test-release-0.1",
Chart: "test-release-0.1", "0.1",
AppVersion: "0.1", }}
})
assert.Equal(t, response, res)
assert.Equal(t, 1, len(res))
assert.Equal(t, "test-release", response[0].Name)
assert.Equal(t, "test-namespace", response[0].Namespace)
assert.Equal(t, 1, response[0].Revision)
assert.Equal(t, timeFromStr, response[0].Updated)
assert.Equal(t, release.StatusDeployed, response[0].Status)
assert.Equal(t, "test-release-0.1", response[0].Chart)
assert.Equal(t, "0.1", response[0].AppVersion)
assert.Equal(t, response, releases[0])
s.lister.AssertExpectations(t) s.lister.AssertExpectations(t)
} }
func (s *ServiceTestSuite) TestListShouldReturnErrorIfInvalidStatusIsPassedAsFilter() { func (s *ServiceTestSuite) TestListShouldReturnErrorIfInvalidStatusIsPassedAsFilter() {
releaseStatus := "invalid" releaseStatus := "invalid"
_, err := s.svc.List(releaseStatus) _, err := s.svc.List(releaseStatus, "test-namespace")
t := s.T() t := s.T()
assert.EqualError(t, err, "invalid release status") assert.EqualError(t, err, "invalid release status")
@ -346,11 +336,11 @@ func (s *ServiceTestSuite) TestListShouldReturnErrorIfInvalidStatusIsPassedAsFil
func (s *ServiceTestSuite) TestListShouldReturnDeployedReleasesIfDeployedIsPassedAsFilter() { func (s *ServiceTestSuite) TestListShouldReturnDeployedReleasesIfDeployedIsPassedAsFilter() {
var releases []*release.Release var releases []*release.Release
releaseStatus := "deployed" releaseStatus := "deployed"
s.lister.On("SetState", action.ListDeployed) s.lister.On("SetConfig", action.ListDeployed, false)
s.lister.On("SetStateMask") s.lister.On("SetStateMask")
s.lister.On("Run").Return(releases, nil) s.lister.On("Run").Return(releases, nil)
_, err := s.svc.List(releaseStatus) _, err := s.svc.List(releaseStatus, "test-namespace")
t := s.T() t := s.T()
assert.NoError(t, err) assert.NoError(t, err)

Loading…
Cancel
Save