diff --git a/resources/iotsitewise-access-policy.go b/resources/iotsitewise-access-policy.go new file mode 100644 index 00000000..02c5e751 --- /dev/null +++ b/resources/iotsitewise-access-policy.go @@ -0,0 +1,150 @@ +package resources + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/iotsitewise" + + "github.com/ekristen/libnuke/pkg/registry" + "github.com/ekristen/libnuke/pkg/resource" + "github.com/ekristen/libnuke/pkg/types" + + "github.com/ekristen/aws-nuke/v3/pkg/nuke" +) + +const IoTSiteWiseAccessPolicyResource = "IoTSiteWiseAccessPolicy" + +func init() { + registry.Register(®istry.Registration{ + Name: IoTSiteWiseAccessPolicyResource, + Scope: nuke.Account, + Lister: &IoTSiteWiseAccessPolicyLister{}, + }) +} + +type IoTSiteWiseAccessPolicyLister struct{} + +func (l *IoTSiteWiseAccessPolicyLister) List(_ context.Context, o interface{}) ([]resource.Resource, error) { //nolint:gocyclo + opts := o.(*nuke.ListerOpts) + + svc := iotsitewise.New(opts.Session) + resources := make([]resource.Resource, 0) + + // Policies can be attached either to portal or projects + // List portal and portal policies + listPortalsParams := &iotsitewise.ListPortalsInput{ + MaxResults: aws.Int64(25), + } + for { + listPortalsResp, err := svc.ListPortals(listPortalsParams) + if err != nil { + return nil, err + } + for _, portalItem := range listPortalsResp.PortalSummaries { + // Got portals + listProjectsParams := &iotsitewise.ListProjectsInput{ + PortalId: portalItem.Id, + MaxResults: aws.Int64(25), + } + + // List portal policies + listPortalPoliciesParam := &iotsitewise.ListAccessPoliciesInput{ + ResourceId: portalItem.Id, + ResourceType: &([]string{string(iotsitewise.ResourceTypePortal)}[0]), + MaxResults: aws.Int64(25), + } + + for { + listPortalPoliciesResp, err := svc.ListAccessPolicies(listPortalPoliciesParam) + if err != nil { + return nil, err + } + for _, item := range listPortalPoliciesResp.AccessPolicySummaries { + resources = append(resources, &IoTSiteWiseAccessPolicy{ + svc: svc, + ID: item.Id, + }) + } + + if listPortalPoliciesResp.NextToken == nil { + break + } + + listPortalPoliciesParam.NextToken = listPortalPoliciesResp.NextToken + } + + // will also search inside projects + for { + listProjectsResp, err := svc.ListProjects(listProjectsParams) + if err != nil { + return nil, err + } + for _, projectItem := range listProjectsResp.ProjectSummaries { + // List project policies + listProjectPoliciesParams := &iotsitewise.ListAccessPoliciesInput{ + ResourceId: projectItem.Id, + ResourceType: &([]string{string(iotsitewise.ResourceTypeProject)}[0]), + MaxResults: aws.Int64(25), + } + + for { + listProjectPoliciesResp, err := svc.ListAccessPolicies(listProjectPoliciesParams) + if err != nil { + return nil, err + } + for _, item := range listProjectPoliciesResp.AccessPolicySummaries { + resources = append(resources, &IoTSiteWiseAccessPolicy{ + svc: svc, + ID: item.Id, + }) + } + + if listProjectPoliciesResp.NextToken == nil { + break + } + + listProjectPoliciesParams.NextToken = listProjectPoliciesResp.NextToken + } + } + + if listProjectsResp.NextToken == nil { + break + } + + listProjectsParams.NextToken = listProjectsResp.NextToken + } + } + + if listPortalsResp.NextToken == nil { + break + } + + listPortalsParams.NextToken = listPortalsResp.NextToken + } + + return resources, nil +} + +type IoTSiteWiseAccessPolicy struct { + svc *iotsitewise.IoTSiteWise + ID *string +} + +func (f *IoTSiteWiseAccessPolicy) Properties() types.Properties { + properties := types.NewProperties() + properties.Set("id", f.ID) + return properties +} + +func (f *IoTSiteWiseAccessPolicy) Remove(_ context.Context) error { + _, err := f.svc.DeleteAccessPolicy(&iotsitewise.DeleteAccessPolicyInput{ + AccessPolicyId: f.ID, + }) + + return err +} + +func (f *IoTSiteWiseAccessPolicy) String() string { + return *f.ID +} diff --git a/resources/iotsitewise-asset-model.go b/resources/iotsitewise-asset-model.go new file mode 100644 index 00000000..af46612c --- /dev/null +++ b/resources/iotsitewise-asset-model.go @@ -0,0 +1,102 @@ +package resources + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/iotsitewise" + + "github.com/ekristen/libnuke/pkg/registry" + "github.com/ekristen/libnuke/pkg/resource" + "github.com/ekristen/libnuke/pkg/types" + + "github.com/ekristen/aws-nuke/v3/pkg/nuke" +) + +const IoTSiteWiseAssetModelResource = "IoTSiteWiseAssetModel" + +func init() { + registry.Register(®istry.Registration{ + Name: IoTSiteWiseAssetModelResource, + Scope: nuke.Account, + Lister: &IoTSiteWiseAssetModelLister{}, + }) +} + +type IoTSiteWiseAssetModelLister struct{} + +func (l *IoTSiteWiseAssetModelLister) List(_ context.Context, o interface{}) ([]resource.Resource, error) { + opts := o.(*nuke.ListerOpts) + + svc := iotsitewise.New(opts.Session) + resources := make([]resource.Resource, 0) + + params := &iotsitewise.ListAssetModelsInput{ + MaxResults: aws.Int64(25), + } + + for { + resp, err := svc.ListAssetModels(params) + if err != nil { + return nil, err + } + for _, item := range resp.AssetModelSummaries { + tagResp, err := svc.ListTagsForResource( + &iotsitewise.ListTagsForResourceInput{ + ResourceArn: item.Arn, + }) + if err != nil { + return nil, err + } + + resources = append(resources, &IoTSiteWiseAssetModel{ + svc: svc, + ID: item.Id, + name: item.Name, + status: item.Status.State, + tags: tagResp.Tags, + }) + } + + if resp.NextToken == nil { + break + } + + params.NextToken = resp.NextToken + } + + return resources, nil +} + +type IoTSiteWiseAssetModel struct { + svc *iotsitewise.IoTSiteWise + ID *string + name *string + status *string + tags map[string]*string +} + +func (f *IoTSiteWiseAssetModel) Properties() types.Properties { + properties := types.NewProperties() + + for key, tag := range f.tags { + properties.SetTag(&key, tag) + } + + properties.Set("name", f.name) + properties.Set("status", f.status) + + return properties +} + +func (f *IoTSiteWiseAssetModel) Remove(_ context.Context) error { + _, err := f.svc.DeleteAssetModel(&iotsitewise.DeleteAssetModelInput{ + AssetModelId: f.ID, + }) + + return err +} + +func (f *IoTSiteWiseAssetModel) String() string { + return *f.ID +} diff --git a/resources/iotsitewise-asset.go b/resources/iotsitewise-asset.go new file mode 100644 index 00000000..2e69bb25 --- /dev/null +++ b/resources/iotsitewise-asset.go @@ -0,0 +1,103 @@ +package resources + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/iotsitewise" + + "github.com/ekristen/libnuke/pkg/registry" + "github.com/ekristen/libnuke/pkg/resource" + "github.com/ekristen/libnuke/pkg/types" + + "github.com/ekristen/aws-nuke/v3/pkg/nuke" +) + +const IoTSiteWiseAssetResource = "IoTSiteWiseAsset" + +func init() { + registry.Register(®istry.Registration{ + Name: IoTSiteWiseAssetResource, + Scope: nuke.Account, + Lister: &IoTSiteWiseAssetLister{}, + }) +} + +type IoTSiteWiseAssetLister struct{} + +func (l *IoTSiteWiseAssetLister) List(_ context.Context, o interface{}) ([]resource.Resource, error) { + opts := o.(*nuke.ListerOpts) + + svc := iotsitewise.New(opts.Session) + resources := make([]resource.Resource, 0) + + params := &iotsitewise.ListAssetsInput{ + Filter: &([]string{string(iotsitewise.ListAssetsFilterTopLevel)}[0]), + MaxResults: aws.Int64(25), + } + + for { + resp, err := svc.ListAssets(params) + if err != nil { + return nil, err + } + for _, item := range resp.AssetSummaries { + tagResp, err := svc.ListTagsForResource( + &iotsitewise.ListTagsForResourceInput{ + ResourceArn: item.Arn, + }) + if err != nil { + return nil, err + } + + resources = append(resources, &IoTSiteWiseAsset{ + svc: svc, + ID: item.Id, + name: item.Name, + status: item.Status.State, + tags: tagResp.Tags, + }) + } + + if resp.NextToken == nil { + break + } + + params.NextToken = resp.NextToken + } + + return resources, nil +} + +type IoTSiteWiseAsset struct { + svc *iotsitewise.IoTSiteWise + ID *string + name *string + status *string + tags map[string]*string +} + +func (f *IoTSiteWiseAsset) Properties() types.Properties { + properties := types.NewProperties() + + for key, tag := range f.tags { + properties.SetTag(&key, tag) + } + + properties.Set("name", f.name) + properties.Set("status", f.status) + + return properties +} + +func (f *IoTSiteWiseAsset) Remove(_ context.Context) error { + _, err := f.svc.DeleteAsset(&iotsitewise.DeleteAssetInput{ + AssetId: f.ID, + }) + + return err +} + +func (f *IoTSiteWiseAsset) String() string { + return *f.ID +} diff --git a/resources/iotsitewise-dashboard.go b/resources/iotsitewise-dashboard.go new file mode 100644 index 00000000..1781840b --- /dev/null +++ b/resources/iotsitewise-dashboard.go @@ -0,0 +1,125 @@ +package resources + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/iotsitewise" + + "github.com/ekristen/libnuke/pkg/registry" + "github.com/ekristen/libnuke/pkg/resource" + "github.com/ekristen/libnuke/pkg/types" + + "github.com/ekristen/aws-nuke/v3/pkg/nuke" +) + +const IoTSiteWiseDashboardResource = "IoTSiteWiseDashboard" + +func init() { + registry.Register(®istry.Registration{ + Name: IoTSiteWiseDashboardResource, + Scope: nuke.Account, + Lister: &IoTSiteWiseDashboardLister{}, + }) +} + +type IoTSiteWiseDashboardLister struct{} + +func (l *IoTSiteWiseDashboardLister) List(_ context.Context, o interface{}) ([]resource.Resource, error) { + opts := o.(*nuke.ListerOpts) + + svc := iotsitewise.New(opts.Session) + resources := make([]resource.Resource, 0) + + // Dashboards can be listed from each project + // To get projects, we must list all portals + listPortalsParams := &iotsitewise.ListPortalsInput{ + MaxResults: aws.Int64(25), + } + for { + listPortalsResp, err := svc.ListPortals(listPortalsParams) + if err != nil { + return nil, err + } + for _, portalItem := range listPortalsResp.PortalSummaries { + // Got portals, will search for projects + listProjectsParams := &iotsitewise.ListProjectsInput{ + PortalId: portalItem.Id, + MaxResults: aws.Int64(25), + } + + for { + listProjectsResp, err := svc.ListProjects(listProjectsParams) + if err != nil { + return nil, err + } + for _, projectItem := range listProjectsResp.ProjectSummaries { + // Got projects, finally get dashboards + listDashboardParams := &iotsitewise.ListDashboardsInput{ + ProjectId: projectItem.Id, + MaxResults: aws.Int64(25), + } + + for { + listDashboardResp, err := svc.ListDashboards(listDashboardParams) + if err != nil { + return nil, err + } + for _, dashboardItem := range listDashboardResp.DashboardSummaries { + resources = append(resources, &IoTSiteWiseDashboard{ + svc: svc, + ID: dashboardItem.Id, + name: dashboardItem.Name, + }) + } + + if listDashboardResp.NextToken == nil { + break + } + + listDashboardParams.NextToken = listDashboardResp.NextToken + } + } + + if listProjectsResp.NextToken == nil { + break + } + + listProjectsParams.NextToken = listProjectsResp.NextToken + } + } + + if listPortalsResp.NextToken == nil { + break + } + + listPortalsParams.NextToken = listPortalsResp.NextToken + } + + return resources, nil +} + +type IoTSiteWiseDashboard struct { + svc *iotsitewise.IoTSiteWise + ID *string + name *string +} + +func (f *IoTSiteWiseDashboard) Properties() types.Properties { + properties := types.NewProperties() + properties.Set("name", f.name) + + return properties +} + +func (f *IoTSiteWiseDashboard) Remove(_ context.Context) error { + _, err := f.svc.DeleteDashboard(&iotsitewise.DeleteDashboardInput{ + DashboardId: f.ID, + }) + + return err +} + +func (f *IoTSiteWiseDashboard) String() string { + return *f.ID +} diff --git a/resources/iotsitewise-gateway.go b/resources/iotsitewise-gateway.go new file mode 100644 index 00000000..59a4a0fe --- /dev/null +++ b/resources/iotsitewise-gateway.go @@ -0,0 +1,84 @@ +package resources + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/iotsitewise" + + "github.com/ekristen/libnuke/pkg/registry" + "github.com/ekristen/libnuke/pkg/resource" + "github.com/ekristen/libnuke/pkg/types" + + "github.com/ekristen/aws-nuke/v3/pkg/nuke" +) + +const IoTSiteWiseGatewayResource = "IoTSiteWiseGateway" + +func init() { + registry.Register(®istry.Registration{ + Name: IoTSiteWiseGatewayResource, + Scope: nuke.Account, + Lister: &IoTSiteWiseGatewayLister{}, + }) +} + +type IoTSiteWiseGatewayLister struct{} + +func (l *IoTSiteWiseGatewayLister) List(_ context.Context, o interface{}) ([]resource.Resource, error) { + opts := o.(*nuke.ListerOpts) + + svc := iotsitewise.New(opts.Session) + resources := make([]resource.Resource, 0) + + params := &iotsitewise.ListGatewaysInput{ + MaxResults: aws.Int64(25), + } + + for { + resp, err := svc.ListGateways(params) + if err != nil { + return nil, err + } + for _, item := range resp.GatewaySummaries { + resources = append(resources, &IoTSiteWiseGateway{ + svc: svc, + ID: item.GatewayId, + name: item.GatewayName, + }) + } + + if resp.NextToken == nil { + break + } + + params.NextToken = resp.NextToken + } + + return resources, nil +} + +type IoTSiteWiseGateway struct { + svc *iotsitewise.IoTSiteWise + ID *string + name *string +} + +func (f *IoTSiteWiseGateway) Properties() types.Properties { + properties := types.NewProperties() + properties.Set("name", f.name) + + return properties +} + +func (f *IoTSiteWiseGateway) Remove(_ context.Context) error { + _, err := f.svc.DeleteGateway(&iotsitewise.DeleteGatewayInput{ + GatewayId: f.ID, + }) + + return err +} + +func (f *IoTSiteWiseGateway) String() string { + return *f.ID +} diff --git a/resources/iotsitewise-portal.go b/resources/iotsitewise-portal.go new file mode 100644 index 00000000..2991c110 --- /dev/null +++ b/resources/iotsitewise-portal.go @@ -0,0 +1,88 @@ +package resources + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/iotsitewise" + + "github.com/ekristen/libnuke/pkg/registry" + "github.com/ekristen/libnuke/pkg/resource" + "github.com/ekristen/libnuke/pkg/types" + + "github.com/ekristen/aws-nuke/v3/pkg/nuke" +) + +const IoTSiteWisePortalResource = "IoTSiteWisePortal" + +func init() { + registry.Register(®istry.Registration{ + Name: IoTSiteWisePortalResource, + Scope: nuke.Account, + Lister: &IoTSiteWisePortalLister{}, + DependsOn: []string{ + IoTSiteWiseProjectResource, + IoTSiteWiseAccessPolicyResource, + }, + }) +} + +type IoTSiteWisePortalLister struct{} + +func (l *IoTSiteWisePortalLister) List(_ context.Context, o interface{}) ([]resource.Resource, error) { + opts := o.(*nuke.ListerOpts) + + svc := iotsitewise.New(opts.Session) + resources := make([]resource.Resource, 0) + + params := &iotsitewise.ListPortalsInput{ + MaxResults: aws.Int64(25), + } + + for { + resp, err := svc.ListPortals(params) + if err != nil { + return nil, err + } + for _, item := range resp.PortalSummaries { + resources = append(resources, &IoTSiteWisePortal{ + svc: svc, + ID: item.Id, + name: item.Name, + }) + } + + if resp.NextToken == nil { + break + } + + params.NextToken = resp.NextToken + } + + return resources, nil +} + +type IoTSiteWisePortal struct { + svc *iotsitewise.IoTSiteWise + ID *string + name *string +} + +func (f *IoTSiteWisePortal) Properties() types.Properties { + properties := types.NewProperties() + properties.Set("name", f.name) + + return properties +} + +func (f *IoTSiteWisePortal) Remove(_ context.Context) error { + _, err := f.svc.DeletePortal(&iotsitewise.DeletePortalInput{ + PortalId: f.ID, + }) + + return err +} + +func (f *IoTSiteWisePortal) String() string { + return *f.ID +} diff --git a/resources/iotsitewise-project.go b/resources/iotsitewise-project.go new file mode 100644 index 00000000..049023d2 --- /dev/null +++ b/resources/iotsitewise-project.go @@ -0,0 +1,108 @@ +package resources + +import ( + "context" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/service/iotsitewise" + + "github.com/ekristen/libnuke/pkg/registry" + "github.com/ekristen/libnuke/pkg/resource" + "github.com/ekristen/libnuke/pkg/types" + + "github.com/ekristen/aws-nuke/v3/pkg/nuke" +) + +const IoTSiteWiseProjectResource = "IoTSiteWiseProject" + +func init() { + registry.Register(®istry.Registration{ + Name: IoTSiteWiseProjectResource, + Scope: nuke.Account, + Lister: &IoTSiteWiseProjectLister{}, + DependsOn: []string{ + IoTSiteWiseDashboardResource, + IoTSiteWiseAccessPolicyResource, + }, + }) +} + +type IoTSiteWiseProjectLister struct{} + +func (l *IoTSiteWiseProjectLister) List(_ context.Context, o interface{}) ([]resource.Resource, error) { + opts := o.(*nuke.ListerOpts) + + svc := iotsitewise.New(opts.Session) + resources := make([]resource.Resource, 0) + + // To get projects, we must list all portals + listPortalsParams := &iotsitewise.ListPortalsInput{ + MaxResults: aws.Int64(25), + } + for { + listPortalsResp, err := svc.ListPortals(listPortalsParams) + if err != nil { + return nil, err + } + for _, portalItem := range listPortalsResp.PortalSummaries { + // Got portals, will search for projects + listProjectsParams := &iotsitewise.ListProjectsInput{ + PortalId: portalItem.Id, + MaxResults: aws.Int64(25), + } + + for { + listProjectsResp, err := svc.ListProjects(listProjectsParams) + if err != nil { + return nil, err + } + for _, projectItem := range listProjectsResp.ProjectSummaries { + resources = append(resources, &IoTSiteWiseProject{ + svc: svc, + ID: projectItem.Id, + name: projectItem.Name, + }) + } + + if listProjectsResp.NextToken == nil { + break + } + + listProjectsParams.NextToken = listProjectsResp.NextToken + } + } + + if listPortalsResp.NextToken == nil { + break + } + + listPortalsParams.NextToken = listPortalsResp.NextToken + } + + return resources, nil +} + +type IoTSiteWiseProject struct { + svc *iotsitewise.IoTSiteWise + ID *string + name *string +} + +func (f *IoTSiteWiseProject) Properties() types.Properties { + properties := types.NewProperties() + properties.Set("name", f.name) + + return properties +} + +func (f *IoTSiteWiseProject) Remove(_ context.Context) error { + _, err := f.svc.DeleteProject(&iotsitewise.DeleteProjectInput{ + ProjectId: f.ID, + }) + + return err +} + +func (f *IoTSiteWiseProject) String() string { + return *f.ID +}