fix comments for list api

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

@ -2,6 +2,7 @@ package main
import (
"fmt"
"github.com/gorilla/mux"
"net/http"
"helm.sh/helm/v3/pkg/action"
@ -24,9 +25,8 @@ func setContentType(next http.Handler) http.Handler {
}
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()
logger.Setup("debug")
@ -42,10 +42,10 @@ func startServer() {
api.NewUpgrader(actionUpgrade),
api.NewHistory(actionHistory))
router.Handle("/ping", setContentType(ping.Handler()))
router.Handle("/list", setContentType(api.List(service)))
router.Handle("/install", setContentType(api.Install(service)))
router.Handle("/upgrade", setContentType(api.Upgrade(service)))
router.Handle("/ping", setContentType(ping.Handler())).Methods(http.MethodGet)
router.Handle("/list", setContentType(api.List(service))).Methods(http.MethodPost)
router.Handle("/install", setContentType(api.Install(service))).Methods(http.MethodPost)
router.Handle("/upgrade", setContentType(api.Upgrade(service))).Methods(http.MethodPost)
err := http.ListenAndServe(fmt.Sprintf(":%d", 8080), router)
if err != nil {

@ -26,6 +26,7 @@ require (
github.com/golang/groupcache v0.0.0-20191027212112-611e8accdfc9 // indirect
github.com/google/go-cmp 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/gregjones/httpcache v0.0.0-20181110185634-c63ab54fda8f // 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/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.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 v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=

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

@ -2,6 +2,7 @@ package api
import (
"encoding/json"
"io"
"net/http"
"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) {
var response ListResponse
var request ListRequest
decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&request); err != nil {
logger.Errorf("[List] error decoding request: %v", err)
response.Error = err.Error()
payload, _ := json.Marshal(response)
if err := json.NewDecoder(r.Body).Decode(&request); err == io.EOF || err != nil {
logger.Errorf("[List] error decoding request: %v", err.Error())
w.WriteHeader(http.StatusBadRequest)
w.Write(payload)
response.Error = err.Error()
json.NewEncoder(w).Encode(response)
return
}
defer r.Body.Close()
helmReleases, err := svc.List(request.ReleaseStatus)
helmReleases, err := svc.List(request.ReleaseStatus, request.NameSpace)
if err != nil {
respondInstallError(w, "error while listing charts: %v", err)
return
}
response = ListResponse{"", helmReleases}
payload, err := json.Marshal(response)
err = json.NewEncoder(w).Encode(response)
if err != nil {
respondInstallError(w, "error writing response: %v", err)
return
}
w.Write(payload)
})
}

@ -1,8 +1,8 @@
package api_test
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"strings"
@ -42,8 +42,8 @@ func (m *mockList) SetStateMask() {
m.Called()
}
func (m *mockList) SetState(state action.ListStates) {
m.Called(state)
func (m *mockList) SetConfig(state action.ListStates, allNameSpaces bool) {
m.Called(state, allNameSpaces)
}
func (s *ListTestSuite) SetupSuite() {
@ -68,43 +68,53 @@ func (s *ListTestSuite) TestShouldReturnReleasesWhenSuccessfulAPICall() {
timeFromStr, _ := time.Parse(layout, str)
body := `{"release_status":"deployed"}`
req, _ := http.NewRequest("POST", fmt.Sprintf("%s/list", s.server.URL), strings.NewReader(body))
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"}},
},
}
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.mockList.On("SetStateMask")
s.mockList.On("SetState", action.ListDeployed)
s.mockList.On("SetConfig", action.ListDeployed, true)
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"}]}`
respBody, err := ioutil.ReadAll(resp.Body)
expectedResponse := api.ListResponse{Error: "",
Releases: []api.Release{{"test-release",
"test-namespace",
1,
timeFromStr,
release.StatusDeployed,
"test-release-0.1",
"0.1",
}}}
assert.Equal(s.T(), expectedResponse, string(respBody))
require.NoError(s.T(), httpErr)
assert.Equal(s.T(), expectedResponse.Releases[0], actualResponse.Releases[0])
require.NoError(s.T(), err)
s.mockList.AssertExpectations(s.T())
}
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))
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"}`
respBody, _ := ioutil.ReadAll(resp.Body)
assert.Equal(s.T(), expectedResponse, string(respBody))
assert.Equal(s.T(), expectedResponse, actualResponse.Error)
require.NoError(s.T(), err)
}

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

@ -4,7 +4,6 @@ import (
"context"
"errors"
"fmt"
"strings"
"helm.sh/helm/v3/pkg/action"
@ -140,7 +139,7 @@ func (s Service) validate(icfg ReleaseConfig, values ChartValues) error {
return nil
}
func (s Service) List(releaseStatus string) ([]Release, error) {
func (s Service) List(releaseStatus string, namespace string) ([]Release, error) {
listStates := new(action.ListStates)
state := action.ListAll
@ -152,8 +151,14 @@ func (s Service) List(releaseStatus string) ([]Release, error) {
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()
releases, err := s.ListRunner.Run()
if err != nil {
return nil, err

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

Loading…
Cancel
Save