Skip to content

Commit 895853b

Browse files
author
Paola Nicosia
committed
feat: get and delete cmds
1 parent ac95346 commit 895853b

File tree

8 files changed

+656
-4
lines changed

8 files changed

+656
-4
lines changed

internal/clioptions/clioptions.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ type CLIOptions struct {
7979
MarketplaceItemObjectID string
8080
MarketplaceFetchPublicItems bool
8181

82+
ItemTypeDefinitionName string
83+
8284
FromCronJob string
8385

8486
FollowLogs bool
@@ -262,6 +264,12 @@ func (o *CLIOptions) AddMarketplaceVersionFlag(flags *pflag.FlagSet) (flagName s
262264
return
263265
}
264266

267+
func (o *CLIOptions) AddItemTypeDefinitionNameFlag(flags *pflag.FlagSet) (flagName string) {
268+
flagName = "name"
269+
flags.StringVarP(&o.ItemTypeDefinitionName, flagName, "i", "", "The name of the Item Type Definition")
270+
return
271+
}
272+
265273
func (o *CLIOptions) AddCreateJobFlags(flags *pflag.FlagSet) {
266274
flags.StringVar(&o.FromCronJob, "from", "", "name of the cronjob to create a Job from")
267275
}

internal/cmd/catalog/get.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const (
3636
3737
This command works with Mia-Platform Console v14.0.0 or later.
3838
39-
You need to specify the companyId, itemId and version, via the respective flags. The company-id flag can be omitted if it is already set in the context.
39+
You need to specify the itemId, via the respective flag. The company-id flag can be omitted if it is already set in the context.
4040
`
4141
cmdGetUse = "get { --item-id item-id --version version }"
4242
)

internal/cmd/item-type-definition.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,8 @@ func ItemTypeDefinitionCmd(options *clioptions.CLIOptions) *cobra.Command {
3535

3636
// add sub commands
3737
cmd.AddCommand(itd.ListCmd(options))
38-
// TODO
39-
// cmd.AddCommand(itd.GetCmd(options))
40-
// cmd.AddCommand(itd.DeleteCmd(options))
38+
cmd.AddCommand(itd.GetCmd(options))
39+
cmd.AddCommand(itd.DeleteCmd(options))
4140
// cmd.AddCommand(itd.ApplyCmd(options))
4241

4342
return cmd
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// Copyright Mia srl
2+
// SPDX-License-Identifier: Apache-2.0
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
package itd
17+
18+
import (
19+
"context"
20+
"errors"
21+
"fmt"
22+
"net/http"
23+
24+
"github.com/mia-platform/miactl/internal/client"
25+
"github.com/mia-platform/miactl/internal/clioptions"
26+
"github.com/mia-platform/miactl/internal/resources/catalog"
27+
"github.com/mia-platform/miactl/internal/resources/marketplace"
28+
"github.com/mia-platform/miactl/internal/util"
29+
"github.com/spf13/cobra"
30+
)
31+
32+
var (
33+
ErrServerDeleteItem = errors.New("server error while deleting item type definition")
34+
ErrUnexpectedDeleteItem = errors.New("unexpected response while deleting item")
35+
)
36+
37+
const (
38+
deleteItdEndpoint = "/api/tenants/%s/marketplace/item-type-definitions/%s/"
39+
40+
cmdDeleteLongDescription = `Delete an Item Type Definition. It works with Mia-Platform Console v14.1.0 or later.
41+
42+
You need to specify the companyId and the item type definition name via the respective flags (recommended). The company-id flag can be omitted if it is already set in the context.
43+
`
44+
cmdUse = "delete { --name name --version version }"
45+
)
46+
47+
func DeleteCmd(options *clioptions.CLIOptions) *cobra.Command {
48+
cmd := &cobra.Command{
49+
Use: cmdUse,
50+
Short: "Delete a Catalog item",
51+
Long: cmdDeleteLongDescription,
52+
SuggestFor: []string{"rm"},
53+
RunE: func(cmd *cobra.Command, _ []string) error {
54+
restConfig, err := options.ToRESTConfig()
55+
cobra.CheckErr(err)
56+
client, err := client.APIClientForConfig(restConfig)
57+
cobra.CheckErr(err)
58+
59+
canUseNewAPI, versionError := util.VersionCheck(cmd.Context(), client, 14, 0)
60+
if !canUseNewAPI || versionError != nil {
61+
return catalog.ErrUnsupportedCompanyVersion
62+
}
63+
64+
companyID := restConfig.CompanyID
65+
if len(companyID) == 0 {
66+
return marketplace.ErrMissingCompanyID
67+
}
68+
69+
if options.MarketplaceItemVersion != "" && options.MarketplaceItemID != "" {
70+
err = deleteITD(
71+
cmd.Context(),
72+
client,
73+
companyID,
74+
options.ItemTypeDefinitionName,
75+
)
76+
cobra.CheckErr(err)
77+
return nil
78+
}
79+
80+
return errors.New("invalid input parameters")
81+
},
82+
}
83+
84+
ITDFlagName := options.AddItemTypeDefinitionNameFlag(cmd.Flags())
85+
86+
cmd.MarkFlagRequired(ITDFlagName)
87+
88+
return cmd
89+
}
90+
91+
func deleteITD(ctx context.Context, client *client.APIClient, companyID, name string) error {
92+
resp, err := client.
93+
Delete().
94+
APIPath(fmt.Sprintf(deleteItdEndpoint, companyID, name)).
95+
Do(ctx)
96+
97+
if err != nil {
98+
return fmt.Errorf("error executing request: %w", err)
99+
}
100+
101+
switch resp.StatusCode() {
102+
case http.StatusNoContent:
103+
fmt.Println("item deleted successfully")
104+
return nil
105+
case http.StatusNotFound:
106+
return marketplace.ErrItemNotFound
107+
default:
108+
if resp.StatusCode() >= http.StatusInternalServerError {
109+
return ErrServerDeleteItem
110+
}
111+
return fmt.Errorf("%w: %d", ErrUnexpectedDeleteItem, resp.StatusCode())
112+
}
113+
}
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
// Copyright Mia srl
2+
// SPDX-License-Identifier: Apache-2.0
3+
//
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
//
8+
// http://www.apache.org/licenses/LICENSE-2.0
9+
//
10+
// Unless required by applicable law or agreed to in writing, software
11+
// distributed under the License is distributed on an "AS IS" BASIS,
12+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
// See the License for the specific language governing permissions and
14+
// limitations under the License.
15+
16+
package itd
17+
18+
import (
19+
"fmt"
20+
"net/http"
21+
"net/http/httptest"
22+
"testing"
23+
24+
"github.com/mia-platform/miactl/internal/client"
25+
"github.com/mia-platform/miactl/internal/clioptions"
26+
itd "github.com/mia-platform/miactl/internal/resources/item-type-definition"
27+
"github.com/mia-platform/miactl/internal/resources/marketplace"
28+
"github.com/stretchr/testify/require"
29+
)
30+
31+
const (
32+
mockDeleteCompanyID = "company-id"
33+
)
34+
35+
func TestDeleteResourceCmd(t *testing.T) {
36+
t.Run("test command creation", func(t *testing.T) {
37+
opts := clioptions.NewCLIOptions()
38+
cmd := DeleteCmd(opts)
39+
require.NotNil(t, cmd)
40+
})
41+
42+
t.Run("should not run command when Console version is lower than 14.0.0", func(t *testing.T) {
43+
server := httptest.NewServer(unexecutedCmdMockServer(t))
44+
defer server.Close()
45+
46+
opts := clioptions.NewCLIOptions()
47+
opts.CompanyID = mockDeleteCompanyID
48+
opts.Endpoint = server.URL
49+
50+
cmd := DeleteCmd(opts)
51+
cmd.SetArgs([]string{"delete", "--item-id", "some-item-id", "--version", "1.0.0"})
52+
53+
err := cmd.Execute()
54+
require.ErrorIs(t, err, itd.ErrUnsupportedCompanyVersion)
55+
})
56+
}
57+
58+
func deleteByItemIDAndVersionMockServer(t *testing.T,
59+
statusCode int,
60+
mockName string,
61+
callsCount *int,
62+
) *httptest.Server {
63+
t.Helper()
64+
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
65+
require.Equal(t,
66+
fmt.Sprintf(deleteItdEndpoint, mockDeleteCompanyID, mockName),
67+
r.RequestURI,
68+
)
69+
require.Equal(t, http.MethodDelete, r.Method)
70+
w.WriteHeader(statusCode)
71+
if statusCode != http.StatusNoContent {
72+
w.Write([]byte(`
73+
{
74+
"message": "some error message"
75+
}
76+
`))
77+
}
78+
*callsCount++
79+
}))
80+
}
81+
82+
func TestDeleteItemByItemIDAndVersion(t *testing.T) {
83+
mockClientConfig := &client.Config{
84+
Transport: http.DefaultTransport,
85+
}
86+
testCases := []struct {
87+
testName string
88+
89+
statusCode int
90+
91+
name string
92+
93+
expectedErr error
94+
expectedCalls int
95+
}{
96+
{
97+
testName: "should not return error if deletion is successful",
98+
statusCode: http.StatusNoContent,
99+
name: "plugin",
100+
101+
expectedErr: nil,
102+
expectedCalls: 1,
103+
},
104+
{
105+
testName: "should return not found error in case the item is not found",
106+
name: "plugin",
107+
108+
statusCode: http.StatusNotFound,
109+
110+
expectedErr: marketplace.ErrItemNotFound,
111+
expectedCalls: 1,
112+
},
113+
{
114+
testName: "should return generic error in case the server responds 500",
115+
name: "plugin",
116+
117+
statusCode: http.StatusInternalServerError,
118+
119+
expectedErr: ErrServerDeleteItem,
120+
expectedCalls: 1,
121+
},
122+
{
123+
testName: "should return unexpected response error in case of bad request response",
124+
name: "plugin",
125+
126+
statusCode: http.StatusBadRequest,
127+
128+
expectedErr: ErrUnexpectedDeleteItem,
129+
expectedCalls: 1,
130+
},
131+
}
132+
133+
for _, tt := range testCases {
134+
t.Run(tt.testName, func(t *testing.T) {
135+
callsCount := new(int)
136+
*callsCount = 0
137+
testServer := deleteByItemIDAndVersionMockServer(
138+
t,
139+
tt.statusCode,
140+
tt.name,
141+
callsCount,
142+
)
143+
defer testServer.Close()
144+
145+
mockClientConfig.Host = testServer.URL
146+
client, err := client.APIClientForConfig(mockClientConfig)
147+
require.NoError(t, err)
148+
149+
err = deleteITD(
150+
t.Context(),
151+
client,
152+
mockDeleteCompanyID,
153+
tt.name,
154+
)
155+
156+
require.Equal(t, tt.expectedCalls, *callsCount, "did not match number of calls")
157+
158+
if tt.expectedErr != nil {
159+
require.ErrorIs(t, err, tt.expectedErr)
160+
} else {
161+
require.NoError(t, err)
162+
}
163+
})
164+
}
165+
}

0 commit comments

Comments
 (0)