Skip to content

Commit 4a2ec59

Browse files
committed
feat(iottwinmaker): add workspace, component type, entity, scene, syncjob
1 parent b830a09 commit 4a2ec59

6 files changed

+590
-0
lines changed

pkg/awsutil/session.go

+6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/aws/aws-sdk-go/aws/endpoints"
1616
"github.com/aws/aws-sdk-go/aws/request"
1717
"github.com/aws/aws-sdk-go/aws/session"
18+
"github.com/aws/aws-sdk-go/service/iottwinmaker"
1819
"github.com/aws/aws-sdk-go/service/s3control"
1920

2021
"github.com/ekristen/aws-nuke/v3/pkg/config"
@@ -242,6 +243,11 @@ func skipGlobalHandler(global bool) func(r *request.Request) {
242243
// Rewrite S3 Control ServiceName to proper EndpointsID
243244
// https://github.com/rebuy-de/aws-nuke/issues/708
244245
}
246+
if service == iottwinmaker.ServiceName {
247+
service = iottwinmaker.EndpointsID
248+
// IoTTwinMaker have two endpoints, must point on "api" one
249+
// https://docs.aws.amazon.com/iot-twinmaker/latest/guide/endpionts-and-quotas.html
250+
}
245251
rs, ok := endpoints.RegionsForService(endpoints.DefaultPartitions(), DefaultAWSPartitionID, service)
246252
if !ok {
247253
// This means that the service does not exist in the endpoints list.
+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package resources
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"strings"
7+
8+
"github.com/aws/aws-sdk-go/aws"
9+
"github.com/aws/aws-sdk-go/service/iottwinmaker"
10+
11+
"github.com/ekristen/libnuke/pkg/registry"
12+
"github.com/ekristen/libnuke/pkg/resource"
13+
"github.com/ekristen/libnuke/pkg/types"
14+
15+
"github.com/ekristen/aws-nuke/v3/pkg/nuke"
16+
)
17+
18+
const IoTTwinMakerComponentTypeResource = "IoTTwinMakerComponentType"
19+
20+
func init() {
21+
registry.Register(&registry.Registration{
22+
Name: IoTTwinMakerComponentTypeResource,
23+
Scope: nuke.Account,
24+
Lister: &IoTTwinMakerComponentTypeLister{},
25+
})
26+
}
27+
28+
type IoTTwinMakerComponentTypeLister struct{}
29+
30+
func (l *IoTTwinMakerComponentTypeLister) List(_ context.Context, o interface{}) ([]resource.Resource, error) {
31+
opts := o.(*nuke.ListerOpts)
32+
33+
svc := iottwinmaker.New(opts.Session)
34+
resources := make([]resource.Resource, 0)
35+
36+
// Require to have workspaces identifiers to query components
37+
workspaceListResponse, err := ListWorkspacesComponentType(svc)
38+
39+
if err != nil {
40+
return nil, err
41+
}
42+
43+
for _, workspaceResponse := range workspaceListResponse {
44+
params := &iottwinmaker.ListComponentTypesInput{
45+
WorkspaceId: workspaceResponse.WorkspaceId,
46+
MaxResults: aws.Int64(25),
47+
}
48+
49+
for {
50+
resp, err := svc.ListComponentTypes(params)
51+
if err != nil {
52+
return nil, err
53+
}
54+
55+
for _, item := range resp.ComponentTypeSummaries {
56+
// We must filter out amazon-owned component types when querying tags,
57+
// because their ARN format causes ListTagsForResource to fail with validation error
58+
tags := make(map[string]*string)
59+
if !strings.Contains(*item.Arn, "AmazonOwnedTypesWorkspace") {
60+
tagResp, err := svc.ListTagsForResource(
61+
&iottwinmaker.ListTagsForResourceInput{
62+
ResourceARN: item.Arn,
63+
})
64+
if err != nil {
65+
return nil, err
66+
}
67+
tags = tagResp.Tags
68+
}
69+
70+
resources = append(resources, &IoTTwinMakerComponentType{
71+
svc: svc,
72+
ID: item.ComponentTypeId,
73+
arn: item.Arn,
74+
Tags: tags,
75+
WorkspaceID: workspaceResponse.WorkspaceId,
76+
})
77+
}
78+
79+
if resp.NextToken == nil {
80+
break
81+
}
82+
83+
params.NextToken = resp.NextToken
84+
}
85+
}
86+
87+
return resources, nil
88+
}
89+
90+
// Utility function to list workspaces
91+
func ListWorkspacesComponentType(svc *iottwinmaker.IoTTwinMaker) ([]*iottwinmaker.WorkspaceSummary, error) {
92+
resources := make([]*iottwinmaker.WorkspaceSummary, 0)
93+
params := &iottwinmaker.ListWorkspacesInput{
94+
MaxResults: aws.Int64(25),
95+
}
96+
for {
97+
resp, err := svc.ListWorkspaces(params)
98+
if err != nil {
99+
return nil, err
100+
}
101+
resources = append(resources, resp.WorkspaceSummaries...)
102+
if resp.NextToken == nil {
103+
break
104+
}
105+
params.NextToken = resp.NextToken
106+
}
107+
return resources, nil
108+
}
109+
110+
type IoTTwinMakerComponentType struct {
111+
svc *iottwinmaker.IoTTwinMaker
112+
ID *string
113+
Tags map[string]*string
114+
WorkspaceID *string
115+
arn *string
116+
}
117+
118+
func (r *IoTTwinMakerComponentType) Filter() error {
119+
if strings.Contains(*r.arn, "AmazonOwnedTypesWorkspace") {
120+
return fmt.Errorf("cannot delete pre-defined component type")
121+
}
122+
return nil
123+
}
124+
125+
func (r *IoTTwinMakerComponentType) Properties() types.Properties {
126+
return types.NewPropertiesFromStruct(r)
127+
}
128+
129+
func (r *IoTTwinMakerComponentType) Remove(_ context.Context) error {
130+
_, err := r.svc.DeleteComponentType(&iottwinmaker.DeleteComponentTypeInput{
131+
ComponentTypeId: r.ID,
132+
WorkspaceId: r.WorkspaceID,
133+
})
134+
135+
return err
136+
}
137+
138+
func (r *IoTTwinMakerComponentType) String() string {
139+
return *r.ID
140+
}

resources/iottwinmaker-entity.go

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package resources
2+
3+
import (
4+
"context"
5+
6+
"github.com/aws/aws-sdk-go/aws"
7+
"github.com/aws/aws-sdk-go/service/iottwinmaker"
8+
9+
"github.com/ekristen/libnuke/pkg/registry"
10+
"github.com/ekristen/libnuke/pkg/resource"
11+
"github.com/ekristen/libnuke/pkg/types"
12+
13+
"github.com/ekristen/aws-nuke/v3/pkg/nuke"
14+
)
15+
16+
const IoTTwinMakerEntityResource = "IoTTwinMakerEntity"
17+
18+
func init() {
19+
registry.Register(&registry.Registration{
20+
Name: IoTTwinMakerEntityResource,
21+
Scope: nuke.Account,
22+
Lister: &IoTTwinMakerEntityLister{},
23+
})
24+
}
25+
26+
type IoTTwinMakerEntityLister struct{}
27+
28+
func (l *IoTTwinMakerEntityLister) List(_ context.Context, o interface{}) ([]resource.Resource, error) {
29+
opts := o.(*nuke.ListerOpts)
30+
31+
svc := iottwinmaker.New(opts.Session)
32+
resources := make([]resource.Resource, 0)
33+
34+
// Require to have workspaces identifiers to query entities
35+
workspaceListResponse, err := ListWorkspacesEntities(svc)
36+
37+
if err != nil {
38+
return nil, err
39+
}
40+
41+
for _, workspaceResponse := range workspaceListResponse {
42+
params := &iottwinmaker.ListEntitiesInput{
43+
WorkspaceId: workspaceResponse.WorkspaceId,
44+
MaxResults: aws.Int64(25),
45+
}
46+
47+
for {
48+
resp, err := svc.ListEntities(params)
49+
if err != nil {
50+
return nil, err
51+
}
52+
53+
for _, item := range resp.EntitySummaries {
54+
// We must filter out amazon-owned component types when querying tags,
55+
// because their ARN format causes ListTagsForResource to vail with validation error
56+
resources = append(resources, &IoTTwinMakerEntity{
57+
svc: svc,
58+
ID: item.EntityId,
59+
Name: item.EntityName,
60+
Status: item.Status.State,
61+
WorkspaceID: workspaceResponse.WorkspaceId,
62+
})
63+
}
64+
65+
if resp.NextToken == nil {
66+
break
67+
}
68+
69+
params.NextToken = resp.NextToken
70+
}
71+
}
72+
73+
return resources, nil
74+
}
75+
76+
// Utility function to list workspaces
77+
func ListWorkspacesEntities(svc *iottwinmaker.IoTTwinMaker) ([]*iottwinmaker.WorkspaceSummary, error) {
78+
resources := make([]*iottwinmaker.WorkspaceSummary, 0)
79+
params := &iottwinmaker.ListWorkspacesInput{
80+
MaxResults: aws.Int64(25),
81+
}
82+
for {
83+
resp, err := svc.ListWorkspaces(params)
84+
if err != nil {
85+
return nil, err
86+
}
87+
resources = append(resources, resp.WorkspaceSummaries...)
88+
if resp.NextToken == nil {
89+
break
90+
}
91+
params.NextToken = resp.NextToken
92+
}
93+
return resources, nil
94+
}
95+
96+
type IoTTwinMakerEntity struct {
97+
svc *iottwinmaker.IoTTwinMaker
98+
ID *string
99+
Name *string
100+
Status *string
101+
WorkspaceID *string
102+
}
103+
104+
func (r *IoTTwinMakerEntity) Properties() types.Properties {
105+
return types.NewPropertiesFromStruct(r)
106+
}
107+
108+
func (r *IoTTwinMakerEntity) Remove(_ context.Context) error {
109+
_, err := r.svc.DeleteEntity(&iottwinmaker.DeleteEntityInput{
110+
EntityId: r.ID,
111+
WorkspaceId: r.WorkspaceID,
112+
IsRecursive: aws.Bool(true),
113+
})
114+
115+
return err
116+
}
117+
118+
func (r *IoTTwinMakerEntity) String() string {
119+
return *r.ID
120+
}

resources/iottwinmaker-scene.go

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package resources
2+
3+
import (
4+
"context"
5+
6+
"github.com/aws/aws-sdk-go/aws"
7+
"github.com/aws/aws-sdk-go/service/iottwinmaker"
8+
9+
"github.com/ekristen/libnuke/pkg/registry"
10+
"github.com/ekristen/libnuke/pkg/resource"
11+
"github.com/ekristen/libnuke/pkg/types"
12+
13+
"github.com/ekristen/aws-nuke/v3/pkg/nuke"
14+
)
15+
16+
const IoTTwinMakerSceneResource = "IoTTwinMakerScene"
17+
18+
func init() {
19+
registry.Register(&registry.Registration{
20+
Name: IoTTwinMakerSceneResource,
21+
Scope: nuke.Account,
22+
Lister: &IoTTwinMakerSceneLister{},
23+
})
24+
}
25+
26+
type IoTTwinMakerSceneLister struct{}
27+
28+
func (l *IoTTwinMakerSceneLister) List(_ context.Context, o interface{}) ([]resource.Resource, error) {
29+
opts := o.(*nuke.ListerOpts)
30+
31+
svc := iottwinmaker.New(opts.Session)
32+
resources := make([]resource.Resource, 0)
33+
34+
// Require to have workspaces identifiers to query scenes
35+
workspaceListResponse, err := ListWorkspacesScene(svc)
36+
37+
if err != nil {
38+
return nil, err
39+
}
40+
41+
for _, workspaceResponse := range workspaceListResponse {
42+
params := &iottwinmaker.ListScenesInput{
43+
WorkspaceId: workspaceResponse.WorkspaceId,
44+
MaxResults: aws.Int64(25),
45+
}
46+
47+
for {
48+
resp, err := svc.ListScenes(params)
49+
if err != nil {
50+
return nil, err
51+
}
52+
53+
for _, item := range resp.SceneSummaries {
54+
resources = append(resources, &IoTTwinMakerScene{
55+
svc: svc,
56+
ID: item.SceneId,
57+
WorkspaceID: workspaceResponse.WorkspaceId,
58+
})
59+
}
60+
61+
if resp.NextToken == nil {
62+
break
63+
}
64+
65+
params.NextToken = resp.NextToken
66+
}
67+
}
68+
69+
return resources, nil
70+
}
71+
72+
// Utility function to list workspaces
73+
func ListWorkspacesScene(svc *iottwinmaker.IoTTwinMaker) ([]*iottwinmaker.WorkspaceSummary, error) {
74+
resources := make([]*iottwinmaker.WorkspaceSummary, 0)
75+
params := &iottwinmaker.ListWorkspacesInput{
76+
MaxResults: aws.Int64(25),
77+
}
78+
for {
79+
resp, err := svc.ListWorkspaces(params)
80+
if err != nil {
81+
return nil, err
82+
}
83+
resources = append(resources, resp.WorkspaceSummaries...)
84+
if resp.NextToken == nil {
85+
break
86+
}
87+
params.NextToken = resp.NextToken
88+
}
89+
return resources, nil
90+
}
91+
92+
type IoTTwinMakerScene struct {
93+
svc *iottwinmaker.IoTTwinMaker
94+
ID *string
95+
WorkspaceID *string
96+
}
97+
98+
func (r *IoTTwinMakerScene) Properties() types.Properties {
99+
return types.NewPropertiesFromStruct(r)
100+
}
101+
102+
func (r *IoTTwinMakerScene) Remove(_ context.Context) error {
103+
_, err := r.svc.DeleteScene(&iottwinmaker.DeleteSceneInput{
104+
SceneId: r.ID,
105+
WorkspaceId: r.WorkspaceID,
106+
})
107+
108+
return err
109+
}
110+
111+
func (r *IoTTwinMakerScene) String() string {
112+
return *r.ID
113+
}

0 commit comments

Comments
 (0)