diff --git a/pkg/sdk/es/resources_clients.go b/pkg/sdk/es/resources_clients.go index a42eb6f3..db6b2b74 100644 --- a/pkg/sdk/es/resources_clients.go +++ b/pkg/sdk/es/resources_clients.go @@ -19,7 +19,7 @@ type Client struct { type Project struct { ResourceID string `json:"resource_id"` PlatformID string `json:"platform_id"` - Description render.ProjectDescription `json:"description"` + Description render.ProjectDescription `json:"Description"` Metadata render.Metadata `json:"metadata"` DescribedBy string `json:"described_by"` ResourceType string `json:"resource_type"` @@ -94,7 +94,14 @@ func (p ProjectPaginator) NextPage(ctx context.Context) ([]Project, error) { return values, nil } -var listProjectFilters = map[string]string{} +var listProjectFilters = map[string]string{ + "createdAt": "Description.CreatedAt", + "environmentIds": "Description.EnvironmentIDs", + "id": "Description.ID", + "name": "Description.Name", + "owner": "Description.Owner", + "updatedAt": "Description.UpdatedAt", +} func ListProject(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("ListProject") @@ -156,7 +163,14 @@ func ListProject(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData return nil, nil } -var getProjectFilters = map[string]string{} +var getProjectFilters = map[string]string{ + "createdAt": "Description.CreatedAt", + "environmentIds": "Description.EnvironmentIDs", + "id": "Description.ID", + "name": "Description.Name", + "owner": "Description.Owner", + "updatedAt": "Description.UpdatedAt", +} func GetProject(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("GetProject") @@ -218,7 +232,7 @@ func GetProject(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) type Environment struct { ResourceID string `json:"resource_id"` PlatformID string `json:"platform_id"` - Description render.EnvironmentDescription `json:"description"` + Description render.EnvironmentDescription `json:"Description"` Metadata render.Metadata `json:"metadata"` DescribedBy string `json:"described_by"` ResourceType string `json:"resource_type"` @@ -293,7 +307,16 @@ func (p EnvironmentPaginator) NextPage(ctx context.Context) ([]Environment, erro return values, nil } -var listEnvironmentFilters = map[string]string{} +var listEnvironmentFilters = map[string]string{ + "databasesIds": "Description.DatabasesIDs", + "envGroupIds": "Description.EnvGroupIDs", + "id": "Description.ID", + "name": "Description.Name", + "projectId": "Description.ProjectID", + "protectedStatus": "Description.ProtectedStatus", + "redisIds": "Description.RedisIDs", + "serviceIds": "Description.ServiceIDs", +} func ListEnvironment(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("ListEnvironment") @@ -355,7 +378,16 @@ func ListEnvironment(ctx context.Context, d *plugin.QueryData, _ *plugin.Hydrate return nil, nil } -var getEnvironmentFilters = map[string]string{} +var getEnvironmentFilters = map[string]string{ + "databasesIds": "Description.DatabasesIDs", + "envGroupIds": "Description.EnvGroupIDs", + "id": "Description.ID", + "name": "Description.Name", + "projectId": "Description.ProjectID", + "protectedStatus": "Description.ProtectedStatus", + "redisIds": "Description.RedisIDs", + "serviceIds": "Description.ServiceIDs", +} func GetEnvironment(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("GetEnvironment") @@ -417,7 +449,7 @@ func GetEnvironment(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateD type Postgres struct { ResourceID string `json:"resource_id"` PlatformID string `json:"platform_id"` - Description render.PostgresDescription `json:"description"` + Description render.PostgresDescription `json:"Description"` Metadata render.Metadata `json:"metadata"` DescribedBy string `json:"described_by"` ResourceType string `json:"resource_type"` @@ -492,7 +524,30 @@ func (p PostgresPaginator) NextPage(ctx context.Context) ([]Postgres, error) { return values, nil } -var listPostgresFilters = map[string]string{} +var listPostgresFilters = map[string]string{ + "createdAt": "Description.CreatedAt", + "dashboardUrl": "Description.DashboardURL", + "databaseName": "Description.DatabaseName", + "databaseUser": "Description.DatabaseUser", + "diskSizeGB": "Description.DiskSizeGB", + "environmentId": "Description.EnvironmentID", + "expiresAt": "Description.ExpiresAt", + "highAvailabilityEnabled": "Description.HighAvailabilityEnabled", + "id": "Description.ID", + "ipAllowList": "Description.IPAllowList", + "name": "Description.Name", + "owner": "Description.Owner", + "plan": "Description.Plan", + "primaryPostgresID": "Description.PrimaryPostgresID", + "readReplicas": "Description.ReadReplicas", + "region": "Description.Region", + "role": "Description.Role", + "status": "Description.Status", + "suspended": "Description.Suspended", + "suspenders": "Description.Suspenders", + "updatedAt": "Description.UpdatedAt", + "version": "Description.Version", +} func ListPostgres(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("ListPostgres") @@ -554,7 +609,30 @@ func ListPostgres(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateDat return nil, nil } -var getPostgresFilters = map[string]string{} +var getPostgresFilters = map[string]string{ + "createdAt": "Description.CreatedAt", + "dashboardUrl": "Description.DashboardURL", + "databaseName": "Description.DatabaseName", + "databaseUser": "Description.DatabaseUser", + "diskSizeGB": "Description.DiskSizeGB", + "environmentId": "Description.EnvironmentID", + "expiresAt": "Description.ExpiresAt", + "highAvailabilityEnabled": "Description.HighAvailabilityEnabled", + "id": "Description.ID", + "ipAllowList": "Description.IPAllowList", + "name": "Description.Name", + "owner": "Description.Owner", + "plan": "Description.Plan", + "primaryPostgresID": "Description.PrimaryPostgresID", + "readReplicas": "Description.ReadReplicas", + "region": "Description.Region", + "role": "Description.Role", + "status": "Description.Status", + "suspended": "Description.Suspended", + "suspenders": "Description.Suspenders", + "updatedAt": "Description.UpdatedAt", + "version": "Description.Version", +} func GetPostgres(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("GetPostgres") @@ -616,7 +694,7 @@ func GetPostgres(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData type Service struct { ResourceID string `json:"resource_id"` PlatformID string `json:"platform_id"` - Description render.ServiceDescription `json:"description"` + Description render.ServiceDescription `json:"Description"` Metadata render.Metadata `json:"metadata"` DescribedBy string `json:"described_by"` ResourceType string `json:"resource_type"` @@ -691,7 +769,28 @@ func (p ServicePaginator) NextPage(ctx context.Context) ([]Service, error) { return values, nil } -var listServiceFilters = map[string]string{} +var listServiceFilters = map[string]string{ + "autoDeploy": "Description.AutoDeploy", + "branch": "Description.Branch", + "buildFilter": "Description.BuildFilter", + "createdAt": "Description.CreatedAt", + "dashboardUrl": "Description.DashboardURL", + "environmentId": "Description.EnvironmentID", + "id": "Description.ID", + "imagePath": "Description.ImagePath", + "name": "Description.Name", + "notifyOnFail": "Description.NotifyOnFail", + "ownerId": "Description.OwnerID", + "registryCredential": "Description.RegistryCredential", + "repo": "Description.Repo", + "rootDir": "Description.RootDir", + "serviceDetails": "Description.ServiceDetails", + "slug": "Description.Slug", + "suspended": "Description.Suspended", + "suspenders": "Description.Suspenders", + "type": "Description.Type", + "updatedAt": "Description.UpdatedAt", +} func ListService(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("ListService") @@ -753,7 +852,28 @@ func ListService(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData return nil, nil } -var getServiceFilters = map[string]string{} +var getServiceFilters = map[string]string{ + "autoDeploy": "Description.AutoDeploy", + "branch": "Description.Branch", + "buildFilter": "Description.BuildFilter", + "createdAt": "Description.CreatedAt", + "dashboardUrl": "Description.DashboardURL", + "environmentId": "Description.EnvironmentID", + "id": "Description.ID", + "imagePath": "Description.ImagePath", + "name": "Description.Name", + "notifyOnFail": "Description.NotifyOnFail", + "ownerId": "Description.OwnerID", + "registryCredential": "Description.RegistryCredential", + "repo": "Description.Repo", + "rootDir": "Description.RootDir", + "serviceDetails": "Description.ServiceDetails", + "slug": "Description.Slug", + "suspended": "Description.Suspended", + "suspenders": "Description.Suspenders", + "type": "Description.Type", + "updatedAt": "Description.UpdatedAt", +} func GetService(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("GetService") @@ -815,7 +935,7 @@ func GetService(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) type Job struct { ResourceID string `json:"resource_id"` PlatformID string `json:"platform_id"` - Description render.JobDescription `json:"description"` + Description render.JobDescription `json:"Description"` Metadata render.Metadata `json:"metadata"` DescribedBy string `json:"described_by"` ResourceType string `json:"resource_type"` @@ -890,7 +1010,16 @@ func (p JobPaginator) NextPage(ctx context.Context) ([]Job, error) { return values, nil } -var listJobFilters = map[string]string{} +var listJobFilters = map[string]string{ + "createdAt": "Description.CreatedAt", + "finishedAt": "Description.FinishedAt", + "id": "Description.ID", + "planId": "Description.PlanID", + "serviceId": "Description.ServiceID", + "startCommand": "Description.StartCommand", + "startedAt": "Description.StartedAt", + "status": "Description.Status", +} func ListJob(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("ListJob") @@ -952,7 +1081,16 @@ func ListJob(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (i return nil, nil } -var getJobFilters = map[string]string{} +var getJobFilters = map[string]string{ + "createdAt": "Description.CreatedAt", + "finishedAt": "Description.FinishedAt", + "id": "Description.ID", + "planId": "Description.PlanID", + "serviceId": "Description.ServiceID", + "startCommand": "Description.StartCommand", + "startedAt": "Description.StartedAt", + "status": "Description.Status", +} func GetJob(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("GetJob") @@ -1014,7 +1152,7 @@ func GetJob(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (in type Disk struct { ResourceID string `json:"resource_id"` PlatformID string `json:"platform_id"` - Description render.DiskDescription `json:"description"` + Description render.DiskDescription `json:"Description"` Metadata render.Metadata `json:"metadata"` DescribedBy string `json:"described_by"` ResourceType string `json:"resource_type"` @@ -1089,7 +1227,15 @@ func (p DiskPaginator) NextPage(ctx context.Context) ([]Disk, error) { return values, nil } -var listDiskFilters = map[string]string{} +var listDiskFilters = map[string]string{ + "createdAt": "Description.CreatedAt", + "id": "Description.ID", + "mountPath": "Description.MountPath", + "name": "Description.Name", + "serviceId": "Description.ServiceID", + "sizeGB": "Description.SizeGB", + "updatedAt": "Description.UpdatedAt", +} func ListDisk(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("ListDisk") @@ -1151,7 +1297,15 @@ func ListDisk(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) ( return nil, nil } -var getDiskFilters = map[string]string{} +var getDiskFilters = map[string]string{ + "createdAt": "Description.CreatedAt", + "id": "Description.ID", + "mountPath": "Description.MountPath", + "name": "Description.Name", + "serviceId": "Description.ServiceID", + "sizeGB": "Description.SizeGB", + "updatedAt": "Description.UpdatedAt", +} func GetDisk(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("GetDisk") @@ -1213,7 +1367,7 @@ func GetDisk(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (i type Deploy struct { ResourceID string `json:"resource_id"` PlatformID string `json:"platform_id"` - Description render.DeployDescription `json:"description"` + Description render.DeployDescription `json:"Description"` Metadata render.Metadata `json:"metadata"` DescribedBy string `json:"described_by"` ResourceType string `json:"resource_type"` @@ -1288,7 +1442,16 @@ func (p DeployPaginator) NextPage(ctx context.Context) ([]Deploy, error) { return values, nil } -var listDeployFilters = map[string]string{} +var listDeployFilters = map[string]string{ + "commit": "Description.Commit", + "createdAt": "Description.CreatedAt", + "finishedAt": "Description.FinishedAt", + "id": "Description.ID", + "image": "Description.Image", + "status": "Description.Status", + "trigger": "Description.Trigger", + "updatedAt": "Description.UpdatedAt", +} func ListDeploy(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("ListDeploy") @@ -1350,7 +1513,16 @@ func ListDeploy(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) return nil, nil } -var getDeployFilters = map[string]string{} +var getDeployFilters = map[string]string{ + "commit": "Description.Commit", + "createdAt": "Description.CreatedAt", + "finishedAt": "Description.FinishedAt", + "id": "Description.ID", + "image": "Description.Image", + "status": "Description.Status", + "trigger": "Description.Trigger", + "updatedAt": "Description.UpdatedAt", +} func GetDeploy(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("GetDeploy") @@ -1412,7 +1584,7 @@ func GetDeploy(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) type Blueprint struct { ResourceID string `json:"resource_id"` PlatformID string `json:"platform_id"` - Description render.BlueprintDescription `json:"description"` + Description render.BlueprintDescription `json:"Description"` Metadata render.Metadata `json:"metadata"` DescribedBy string `json:"described_by"` ResourceType string `json:"resource_type"` @@ -1487,7 +1659,15 @@ func (p BlueprintPaginator) NextPage(ctx context.Context) ([]Blueprint, error) { return values, nil } -var listBlueprintFilters = map[string]string{} +var listBlueprintFilters = map[string]string{ + "autoSync": "Description.AutoSync", + "branch": "Description.Branch", + "id": "Description.ID", + "lastSync": "Description.LastSync", + "name": "Description.Name", + "repo": "Description.Repo", + "status": "Description.Status", +} func ListBlueprint(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("ListBlueprint") @@ -1549,7 +1729,15 @@ func ListBlueprint(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateDa return nil, nil } -var getBlueprintFilters = map[string]string{} +var getBlueprintFilters = map[string]string{ + "autoSync": "Description.AutoSync", + "branch": "Description.Branch", + "id": "Description.ID", + "lastSync": "Description.LastSync", + "name": "Description.Name", + "repo": "Description.Repo", + "status": "Description.Status", +} func GetBlueprint(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("GetBlueprint") @@ -1611,7 +1799,7 @@ func GetBlueprint(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateDat type EnvGroup struct { ResourceID string `json:"resource_id"` PlatformID string `json:"platform_id"` - Description render.EnvGroupDescription `json:"description"` + Description render.EnvGroupDescription `json:"Description"` Metadata render.Metadata `json:"metadata"` DescribedBy string `json:"described_by"` ResourceType string `json:"resource_type"` @@ -1686,7 +1874,15 @@ func (p EnvGroupPaginator) NextPage(ctx context.Context) ([]EnvGroup, error) { return values, nil } -var listEnvGroupFilters = map[string]string{} +var listEnvGroupFilters = map[string]string{ + "createdAt": "Description.CreatedAt", + "environmentId": "Description.EnvironmentID", + "id": "Description.ID", + "name": "Description.Name", + "ownerId": "Description.OwnerID", + "serviceLinks": "Description.ServiceLinks", + "updatedAt": "Description.UpdatedAt", +} func ListEnvGroup(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("ListEnvGroup") @@ -1748,7 +1944,15 @@ func ListEnvGroup(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateDat return nil, nil } -var getEnvGroupFilters = map[string]string{} +var getEnvGroupFilters = map[string]string{ + "createdAt": "Description.CreatedAt", + "environmentId": "Description.EnvironmentID", + "id": "Description.ID", + "name": "Description.Name", + "ownerId": "Description.OwnerID", + "serviceLinks": "Description.ServiceLinks", + "updatedAt": "Description.UpdatedAt", +} func GetEnvGroup(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("GetEnvGroup") @@ -1810,7 +2014,7 @@ func GetEnvGroup(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData type Header struct { ResourceID string `json:"resource_id"` PlatformID string `json:"platform_id"` - Description render.HeaderDescription `json:"description"` + Description render.HeaderDescription `json:"Description"` Metadata render.Metadata `json:"metadata"` DescribedBy string `json:"described_by"` ResourceType string `json:"resource_type"` @@ -1885,7 +2089,12 @@ func (p HeaderPaginator) NextPage(ctx context.Context) ([]Header, error) { return values, nil } -var listHeaderFilters = map[string]string{} +var listHeaderFilters = map[string]string{ + "id": "Description.ID", + "name": "Description.Name", + "path": "Description.Path", + "value": "Description.Value", +} func ListHeader(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("ListHeader") @@ -1947,7 +2156,12 @@ func ListHeader(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) return nil, nil } -var getHeaderFilters = map[string]string{} +var getHeaderFilters = map[string]string{ + "id": "Description.ID", + "name": "Description.Name", + "path": "Description.Path", + "value": "Description.Value", +} func GetHeader(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("GetHeader") @@ -2009,7 +2223,7 @@ func GetHeader(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) type Route struct { ResourceID string `json:"resource_id"` PlatformID string `json:"platform_id"` - Description render.RouteDescription `json:"description"` + Description render.RouteDescription `json:"Description"` Metadata render.Metadata `json:"metadata"` DescribedBy string `json:"described_by"` ResourceType string `json:"resource_type"` @@ -2084,7 +2298,13 @@ func (p RoutePaginator) NextPage(ctx context.Context) ([]Route, error) { return values, nil } -var listRouteFilters = map[string]string{} +var listRouteFilters = map[string]string{ + "destination": "Description.Destination", + "id": "Description.ID", + "priority": "Description.Priority", + "source": "Description.Source", + "type": "Description.Type", +} func ListRoute(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("ListRoute") @@ -2146,7 +2366,13 @@ func ListRoute(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) return nil, nil } -var getRouteFilters = map[string]string{} +var getRouteFilters = map[string]string{ + "destination": "Description.Destination", + "id": "Description.ID", + "priority": "Description.Priority", + "source": "Description.Source", + "type": "Description.Type", +} func GetRoute(ctx context.Context, d *plugin.QueryData, _ *plugin.HydrateData) (interface{}, error) { plugin.Logger(ctx).Trace("GetRoute") diff --git a/pkg/sdk/runable/steampipe_es_client_generator/main.go b/pkg/sdk/runable/steampipe_es_client_generator/main.go index 2c0ea08c..0f6bc817 100755 --- a/pkg/sdk/runable/steampipe_es_client_generator/main.go +++ b/pkg/sdk/runable/steampipe_es_client_generator/main.go @@ -81,7 +81,7 @@ func main() { type {{ .Name }} struct { ResourceID string ` + "`json:\"resource_id\"`" + ` PlatformID string ` + "`json:\"platform_id\"`" + ` - Description {{ .IntegrationType }}.{{ .Name }}Description ` + "`json:\"description\"`" + ` + Description {{ .IntegrationType }}.{{ .Name }}Description ` + "`json:\"Description\"`" + ` Metadata {{ .IntegrationType }}.Metadata ` + "`json:\"metadata\"`" + ` DescribedBy string ` + "`json:\"described_by\"`" + ` ResourceType string ` + "`json:\"resource_type\"`" + ` diff --git a/provider/describer/blueprints.go b/provider/describer/blueprints.go index 976697a9..dba61612 100644 --- a/provider/describer/blueprints.go +++ b/provider/describer/blueprints.go @@ -54,14 +54,22 @@ func GetBlueprint(ctx context.Context, handler *RenderAPIHandler, resourceID str ID: blueprint.ID, Name: blueprint.Name, Description: JSONAllFieldsMarshaller{ - Value: blueprint, + Value: model.BlueprintDescription{ + ID: blueprint.ID, + Name: blueprint.Name, + Status: blueprint.Status, + AutoSync: blueprint.AutoSync, + Repo: blueprint.Repo, + Branch: blueprint.Branch, + LastSync: blueprint.LastSync, + }, }, } return &value, nil } func processBlueprints(ctx context.Context, handler *RenderAPIHandler, renderChan chan<- models.Resource, wg *sync.WaitGroup) error { - var blueprints []model.BlueprintDescription + var blueprints []model.BlueprintJSON var blueprintListResponse []model.BlueprintResponse var resp *http.Response baseURL := "https://api.render.com/v1/blueprints" @@ -110,13 +118,21 @@ func processBlueprints(ctx context.Context, handler *RenderAPIHandler, renderCha } for _, blueprint := range blueprints { wg.Add(1) - go func(blueprint model.BlueprintDescription) { + go func(blueprint model.BlueprintJSON) { defer wg.Done() value := models.Resource{ ID: blueprint.ID, Name: blueprint.Name, Description: JSONAllFieldsMarshaller{ - Value: blueprint, + Value: model.BlueprintDescription{ + ID: blueprint.ID, + Name: blueprint.Name, + Status: blueprint.Status, + AutoSync: blueprint.AutoSync, + Repo: blueprint.Repo, + Branch: blueprint.Branch, + LastSync: blueprint.LastSync, + }, }, } renderChan <- value @@ -125,8 +141,8 @@ func processBlueprints(ctx context.Context, handler *RenderAPIHandler, renderCha return nil } -func processBlueprint(ctx context.Context, handler *RenderAPIHandler, resourceID string) (*model.ProjectDescription, error) { - var project model.ProjectDescription +func processBlueprint(ctx context.Context, handler *RenderAPIHandler, resourceID string) (*model.BlueprintJSON, error) { + var blueprint model.BlueprintJSON var resp *http.Response baseURL := "https://api.render.com/v1/blueprints/" @@ -144,7 +160,7 @@ func processBlueprint(ctx context.Context, handler *RenderAPIHandler, resourceID } defer resp.Body.Close() - if e = json.NewDecoder(resp.Body).Decode(&project); e != nil { + if e = json.NewDecoder(resp.Body).Decode(&blueprint); e != nil { return nil, fmt.Errorf("failed to decode response: %w", e) } return resp, e @@ -154,5 +170,5 @@ func processBlueprint(ctx context.Context, handler *RenderAPIHandler, resourceID if err != nil { return nil, fmt.Errorf("error during request handling: %w", err) } - return &project, nil + return &blueprint, nil } diff --git a/provider/describer/deploys.go b/provider/describer/deploys.go index 3205c99a..e3e64142 100644 --- a/provider/describer/deploys.go +++ b/provider/describer/deploys.go @@ -52,7 +52,7 @@ func ListDeploys(ctx context.Context, handler *RenderAPIHandler, stream *models. } func processDeploys(ctx context.Context, handler *RenderAPIHandler, serviceID string, renderChan chan<- models.Resource, wg *sync.WaitGroup) error { - var deploys []model.DeployDescription + var deploys []model.DeployJSON var deployListResponse []model.DeployResponse var resp *http.Response baseURL := "https://api.render.com/v1/services/" @@ -100,13 +100,32 @@ func processDeploys(ctx context.Context, handler *RenderAPIHandler, serviceID st } for _, deploy := range deploys { wg.Add(1) - go func(deploy model.DeployDescription) { + go func(deploy model.DeployJSON) { defer wg.Done() + commit := model.Commit{ + ID: deploy.Commit.ID, + Message: deploy.Commit.Message, + CreatedAt: deploy.Commit.CreatedAt, + } + image := model.Image{ + Ref: deploy.Image.Ref, + SHA: deploy.Image.SHA, + RegistryCredential: deploy.Image.RegistryCredential, + } value := models.Resource{ ID: deploy.ID, Name: deploy.Status, Description: JSONAllFieldsMarshaller{ - Value: deploy, + Value: model.DeployDescription{ + ID: deploy.ID, + Commit: commit, + Image: image, + Status: deploy.Status, + Trigger: deploy.Trigger, + FinishedAt: deploy.FinishedAt, + CreatedAt: deploy.CreatedAt, + UpdatedAt: deploy.UpdatedAt, + }, }, } renderChan <- value diff --git a/provider/describer/disks.go b/provider/describer/disks.go index b801be0f..ac80a50e 100644 --- a/provider/describer/disks.go +++ b/provider/describer/disks.go @@ -54,14 +54,22 @@ func GetDisk(ctx context.Context, handler *RenderAPIHandler, resourceID string) ID: disk.ID, Name: disk.Name, Description: JSONAllFieldsMarshaller{ - Value: disk, + Value: model.DiskDescription{ + ID: disk.ID, + Name: disk.Name, + SizeGB: disk.SizeGB, + MountPath: disk.MountPath, + ServiceID: disk.ServiceID, + CreatedAt: disk.CreatedAt, + UpdatedAt: disk.UpdatedAt, + }, }, } return &value, nil } func processDisks(ctx context.Context, handler *RenderAPIHandler, renderChan chan<- models.Resource, wg *sync.WaitGroup) error { - var disks []model.DiskDescription + var disks []model.DiskJSON var diskListResponse []model.DiskResponse var resp *http.Response baseURL := "https://api.render.com/v1/disks" @@ -110,13 +118,21 @@ func processDisks(ctx context.Context, handler *RenderAPIHandler, renderChan cha } for _, disk := range disks { wg.Add(1) - go func(disk model.DiskDescription) { + go func(disk model.DiskJSON) { defer wg.Done() value := models.Resource{ ID: disk.ID, Name: disk.Name, Description: JSONAllFieldsMarshaller{ - Value: disk, + Value: model.DiskDescription{ + ID: disk.ID, + Name: disk.Name, + SizeGB: disk.SizeGB, + MountPath: disk.MountPath, + ServiceID: disk.ServiceID, + CreatedAt: disk.CreatedAt, + UpdatedAt: disk.UpdatedAt, + }, }, } renderChan <- value @@ -125,8 +141,8 @@ func processDisks(ctx context.Context, handler *RenderAPIHandler, renderChan cha return nil } -func processDisk(ctx context.Context, handler *RenderAPIHandler, resourceID string) (*model.DiskDescription, error) { - var disk model.DiskDescription +func processDisk(ctx context.Context, handler *RenderAPIHandler, resourceID string) (*model.DiskJSON, error) { + var disk model.DiskJSON var resp *http.Response baseURL := "https://api.render.com/v1/disks/" diff --git a/provider/describer/env_groups.go b/provider/describer/env_groups.go index d2208ae9..605e2fbb 100644 --- a/provider/describer/env_groups.go +++ b/provider/describer/env_groups.go @@ -50,18 +50,34 @@ func GetEnvGroup(ctx context.Context, handler *RenderAPIHandler, resourceID stri if err != nil { return nil, err } + var serviceLinks []model.ServiceLink + for _, serviceLink := range envGroup.ServiceLinks { + serviceLinks = append(serviceLinks, model.ServiceLink{ + ID: serviceLink.ID, + Name: serviceLink.Name, + Type: serviceLink.Type, + }) + } value := models.Resource{ ID: envGroup.ID, Name: envGroup.Name, Description: JSONAllFieldsMarshaller{ - Value: envGroup, + Value: model.EnvGroupDescription{ + ID: envGroup.ID, + Name: envGroup.Name, + OwnerID: envGroup.OwnerID, + CreatedAt: envGroup.CreatedAt, + UpdatedAt: envGroup.UpdatedAt, + ServiceLinks: serviceLinks, + EnvironmentID: envGroup.EnvironmentID, + }, }, } return &value, nil } func processEnvGroups(ctx context.Context, handler *RenderAPIHandler, renderChan chan<- models.Resource, wg *sync.WaitGroup) error { - var envGroups []model.EnvGroupDescription + var envGroups []model.EnvGroupJSON var envGroupResp []model.EnvGroupResponse var resp *http.Response baseURL := "https://api.render.com/v1/env-groups" @@ -110,13 +126,29 @@ func processEnvGroups(ctx context.Context, handler *RenderAPIHandler, renderChan } for _, envGroup := range envGroups { wg.Add(1) - go func(envGroup model.EnvGroupDescription) { + go func(envGroup model.EnvGroupJSON) { defer wg.Done() + var serviceLinks []model.ServiceLink + for _, serviceLink := range envGroup.ServiceLinks { + serviceLinks = append(serviceLinks, model.ServiceLink{ + ID: serviceLink.ID, + Name: serviceLink.Name, + Type: serviceLink.Type, + }) + } value := models.Resource{ ID: envGroup.ID, Name: envGroup.Name, Description: JSONAllFieldsMarshaller{ - Value: envGroup, + Value: model.EnvGroupDescription{ + ID: envGroup.ID, + Name: envGroup.Name, + OwnerID: envGroup.OwnerID, + CreatedAt: envGroup.CreatedAt, + UpdatedAt: envGroup.UpdatedAt, + ServiceLinks: serviceLinks, + EnvironmentID: envGroup.EnvironmentID, + }, }, } renderChan <- value @@ -125,8 +157,8 @@ func processEnvGroups(ctx context.Context, handler *RenderAPIHandler, renderChan return nil } -func processEnvGroup(ctx context.Context, handler *RenderAPIHandler, resourceID string) (*model.EnvGroupDescription, error) { - var envGroup model.EnvGroupDescription +func processEnvGroup(ctx context.Context, handler *RenderAPIHandler, resourceID string) (*model.EnvGroupJSON, error) { + var envGroup model.EnvGroupJSON var resp *http.Response baseURL := "https://api.render.com/v1/env-groups/" diff --git a/provider/describer/environments.go b/provider/describer/environments.go index f6a90bfb..ab25210b 100644 --- a/provider/describer/environments.go +++ b/provider/describer/environments.go @@ -60,14 +60,23 @@ func GetEnvironment(ctx context.Context, handler *RenderAPIHandler, resourceID s ID: environment.ID, Name: environment.Name, Description: JSONAllFieldsMarshaller{ - Value: environment, + Value: model.EnvironmentDescription{ + ID: environment.ID, + Name: environment.Name, + ProjectID: resourceID, + DatabasesIDs: environment.DatabasesIDs, + RedisIDs: environment.RedisIDs, + ServiceIDs: environment.ServiceIDs, + EnvGroupIDs: environment.EnvGroupIDs, + ProtectedStatus: environment.ProtectedStatus, + }, }, } return &value, nil } func processEnvironments(ctx context.Context, handler *RenderAPIHandler, projectID string, renderChan chan<- models.Resource, wg *sync.WaitGroup) error { - var environments []model.EnvironmentDescription + var environments []model.EnvironmentJSON var environmentListResponse []model.EnvironmentResponse var resp *http.Response baseURL := "https://api.render.com/v1/environments" @@ -117,13 +126,22 @@ func processEnvironments(ctx context.Context, handler *RenderAPIHandler, project } for _, environment := range environments { wg.Add(1) - go func(environment model.EnvironmentDescription) { + go func(environment model.EnvironmentJSON) { defer wg.Done() value := models.Resource{ ID: environment.ID, Name: environment.Name, Description: JSONAllFieldsMarshaller{ - Value: environment, + Value: model.EnvironmentDescription{ + ID: environment.ID, + Name: environment.Name, + ProjectID: projectID, + DatabasesIDs: environment.DatabasesIDs, + RedisIDs: environment.RedisIDs, + ServiceIDs: environment.ServiceIDs, + EnvGroupIDs: environment.EnvGroupIDs, + ProtectedStatus: environment.ProtectedStatus, + }, }, } renderChan <- value @@ -132,8 +150,8 @@ func processEnvironments(ctx context.Context, handler *RenderAPIHandler, project return nil } -func processEnvironment(ctx context.Context, handler *RenderAPIHandler, resourceID string) (*model.EnvironmentDescription, error) { - var environment model.EnvironmentDescription +func processEnvironment(ctx context.Context, handler *RenderAPIHandler, resourceID string) (*model.EnvironmentJSON, error) { + var environment model.EnvironmentJSON var resp *http.Response baseURL := "https://api.render.com/v1/environments/" diff --git a/provider/describer/headers.go b/provider/describer/headers.go index ac6811ba..a386ea4c 100644 --- a/provider/describer/headers.go +++ b/provider/describer/headers.go @@ -54,7 +54,7 @@ func ListHeaders(ctx context.Context, handler *RenderAPIHandler, stream *models. } func processHeaders(ctx context.Context, handler *RenderAPIHandler, serviceID string, renderChan chan<- models.Resource, wg *sync.WaitGroup) error { - var headers []model.HeaderDescription + var headers []model.HeaderJSON var headerListResponse []model.HeaderResponse var resp *http.Response baseURL := "https://api.render.com/v1/services/" @@ -102,13 +102,18 @@ func processHeaders(ctx context.Context, handler *RenderAPIHandler, serviceID st } for _, header := range headers { wg.Add(1) - go func(header model.HeaderDescription) { + go func(header model.HeaderJSON) { defer wg.Done() value := models.Resource{ ID: header.ID, Name: header.Name, Description: JSONAllFieldsMarshaller{ - Value: header, + Value: model.HeaderDescription{ + ID: header.ID, + Path: header.Path, + Name: header.Name, + Value: header.Value, + }, }, } renderChan <- value diff --git a/provider/describer/jobs.go b/provider/describer/jobs.go index 8dd8ad58..1cbfd97d 100644 --- a/provider/describer/jobs.go +++ b/provider/describer/jobs.go @@ -52,7 +52,7 @@ func ListJobs(ctx context.Context, handler *RenderAPIHandler, stream *models.Str } func processJobs(ctx context.Context, handler *RenderAPIHandler, serviceID string, renderChan chan<- models.Resource, wg *sync.WaitGroup) error { - var jobs []model.JobDescription + var jobs []model.JobJSON var jobListResponse []model.JobResponse var resp *http.Response baseURL := "https://api.render.com/v1/services/" @@ -101,13 +101,22 @@ func processJobs(ctx context.Context, handler *RenderAPIHandler, serviceID strin } for _, job := range jobs { wg.Add(1) - go func(job model.JobDescription) { + go func(job model.JobJSON) { defer wg.Done() value := models.Resource{ ID: job.ID, Name: job.Status, Description: JSONAllFieldsMarshaller{ - Value: job, + Value: model.JobDescription{ + ID: job.ID, + ServiceID: serviceID, + StartCommand: job.StartCommand, + PlanID: job.PlanID, + Status: job.Status, + CreatedAt: job.CreatedAt, + StartedAt: job.StartedAt, + FinishedAt: job.FinishedAt, + }, }, } renderChan <- value diff --git a/provider/describer/postgres_instances.go b/provider/describer/postgres_instances.go index 2895c38b..fd1cb1c4 100644 --- a/provider/describer/postgres_instances.go +++ b/provider/describer/postgres_instances.go @@ -50,18 +50,62 @@ func GetPostgresInstance(ctx context.Context, handler *RenderAPIHandler, resourc if err != nil { return nil, err } + var ipAllowList []model.IPAllow + for _, ipAllow := range postgres.IPAllowList { + ipAllowList = append(ipAllowList, model.IPAllow{ + CIDRBlock: ipAllow.CIDRBlock, + Description: ipAllow.Description, + }) + } + owner := model.Owner{ + ID: postgres.Owner.ID, + Name: postgres.Owner.Name, + Email: postgres.Owner.Email, + TwoFactorAuthEnabled: postgres.Owner.TwoFactorAuthEnabled, + Type: postgres.Owner.Type, + } + var readReplicas []model.ReadReplica + for _, readReplica := range postgres.ReadReplicas { + readReplicas = append(readReplicas, model.ReadReplica{ + ID: readReplica.ID, + Name: readReplica.Name, + }) + } value := models.Resource{ ID: postgres.ID, Name: postgres.Name, Description: JSONAllFieldsMarshaller{ - Value: postgres, + Value: model.PostgresDescription{ + ID: postgres.ID, + IPAllowList: ipAllowList, + CreatedAt: postgres.CreatedAt, + UpdatedAt: postgres.UpdatedAt, + ExpiresAt: postgres.ExpiresAt, + DatabaseName: postgres.DatabaseName, + DatabaseUser: postgres.DatabaseUser, + EnvironmentID: postgres.EnvironmentID, + HighAvailabilityEnabled: postgres.HighAvailabilityEnabled, + Name: postgres.Name, + Owner: owner, + Plan: postgres.Plan, + DiskSizeGB: postgres.DiskSizeGB, + PrimaryPostgresID: postgres.PrimaryPostgresID, + Region: postgres.Region, + ReadReplicas: readReplicas, + Role: postgres.Role, + Status: postgres.Status, + Version: postgres.Version, + Suspended: postgres.Suspended, + Suspenders: postgres.Suspenders, + DashboardURL: postgres.DashboardURL, + }, }, } return &value, nil } func processPostgresInstances(ctx context.Context, handler *RenderAPIHandler, renderChan chan<- models.Resource, wg *sync.WaitGroup) error { - var postgresInstances []model.PostgresDescription + var postgresInstances []model.PostgresJSON var postgresListResponse []model.PostgresResponse var resp *http.Response baseURL := "https://api.render.com/v1/postgres" @@ -111,13 +155,57 @@ func processPostgresInstances(ctx context.Context, handler *RenderAPIHandler, re } for _, postgres := range postgresInstances { wg.Add(1) - go func(postgres model.PostgresDescription) { + go func(postgres model.PostgresJSON) { defer wg.Done() + var ipAllowList []model.IPAllow + for _, ipAllow := range postgres.IPAllowList { + ipAllowList = append(ipAllowList, model.IPAllow{ + CIDRBlock: ipAllow.CIDRBlock, + Description: ipAllow.Description, + }) + } + owner := model.Owner{ + ID: postgres.Owner.ID, + Name: postgres.Owner.Name, + Email: postgres.Owner.Email, + TwoFactorAuthEnabled: postgres.Owner.TwoFactorAuthEnabled, + Type: postgres.Owner.Type, + } + var readReplicas []model.ReadReplica + for _, readReplica := range postgres.ReadReplicas { + readReplicas = append(readReplicas, model.ReadReplica{ + ID: readReplica.ID, + Name: readReplica.Name, + }) + } value := models.Resource{ ID: postgres.ID, Name: postgres.Name, Description: JSONAllFieldsMarshaller{ - Value: postgres, + Value: model.PostgresDescription{ + ID: postgres.ID, + IPAllowList: ipAllowList, + CreatedAt: postgres.CreatedAt, + UpdatedAt: postgres.UpdatedAt, + ExpiresAt: postgres.ExpiresAt, + DatabaseName: postgres.DatabaseName, + DatabaseUser: postgres.DatabaseUser, + EnvironmentID: postgres.EnvironmentID, + HighAvailabilityEnabled: postgres.HighAvailabilityEnabled, + Name: postgres.Name, + Owner: owner, + Plan: postgres.Plan, + DiskSizeGB: postgres.DiskSizeGB, + PrimaryPostgresID: postgres.PrimaryPostgresID, + Region: postgres.Region, + ReadReplicas: readReplicas, + Role: postgres.Role, + Status: postgres.Status, + Version: postgres.Version, + Suspended: postgres.Suspended, + Suspenders: postgres.Suspenders, + DashboardURL: postgres.DashboardURL, + }, }, } renderChan <- value @@ -126,8 +214,8 @@ func processPostgresInstances(ctx context.Context, handler *RenderAPIHandler, re return nil } -func processPostgresInstance(ctx context.Context, handler *RenderAPIHandler, resourceID string) (*model.PostgresDescription, error) { - var postgres model.PostgresDescription +func processPostgresInstance(ctx context.Context, handler *RenderAPIHandler, resourceID string) (*model.PostgresJSON, error) { + var postgres model.PostgresJSON var resp *http.Response baseURL := "https://api.render.com/v1/postgres/" diff --git a/provider/describer/projects.go b/provider/describer/projects.go index a94128b1..598c4817 100644 --- a/provider/describer/projects.go +++ b/provider/describer/projects.go @@ -50,18 +50,32 @@ func GetProject(ctx context.Context, handler *RenderAPIHandler, resourceID strin if err != nil { return nil, err } + owner := model.Owner{ + ID: project.Owner.ID, + Name: project.Owner.Name, + Email: project.Owner.Email, + TwoFactorAuthEnabled: project.Owner.TwoFactorAuthEnabled, + Type: project.Owner.Type, + } value := models.Resource{ ID: project.ID, Name: project.Name, Description: JSONAllFieldsMarshaller{ - Value: project, + Value: model.ProjectDescription{ + ID: project.ID, + CreatedAt: project.CreatedAt, + UpdatedAt: project.UpdatedAt, + Name: project.Name, + Owner: owner, + EnvironmentIDs: project.EnvironmentIDs, + }, }, } return &value, nil } func processProjects(ctx context.Context, handler *RenderAPIHandler, renderChan chan<- models.Resource, wg *sync.WaitGroup) error { - var projects []model.ProjectDescription + var projects []model.ProjectJSON var projectListResponse []model.ProjectResponse var resp *http.Response baseURL := "https://api.render.com/v1/projects" @@ -110,13 +124,27 @@ func processProjects(ctx context.Context, handler *RenderAPIHandler, renderChan } for _, project := range projects { wg.Add(1) - go func(project model.ProjectDescription) { + go func(project model.ProjectJSON) { defer wg.Done() + owner := model.Owner{ + ID: project.Owner.ID, + Name: project.Owner.Name, + Email: project.Owner.Email, + TwoFactorAuthEnabled: project.Owner.TwoFactorAuthEnabled, + Type: project.Owner.Type, + } value := models.Resource{ ID: project.ID, Name: project.Name, Description: JSONAllFieldsMarshaller{ - Value: project, + Value: model.ProjectDescription{ + ID: project.ID, + CreatedAt: project.CreatedAt, + UpdatedAt: project.UpdatedAt, + Name: project.Name, + Owner: owner, + EnvironmentIDs: project.EnvironmentIDs, + }, }, } renderChan <- value @@ -125,8 +153,8 @@ func processProjects(ctx context.Context, handler *RenderAPIHandler, renderChan return nil } -func processProject(ctx context.Context, handler *RenderAPIHandler, resourceID string) (*model.ProjectDescription, error) { - var project model.ProjectDescription +func processProject(ctx context.Context, handler *RenderAPIHandler, resourceID string) (*model.ProjectJSON, error) { + var project model.ProjectJSON var resp *http.Response baseURL := "https://api.render.com/v1/projects/" diff --git a/provider/describer/routes.go b/provider/describer/routes.go index e21c9589..cdea119a 100644 --- a/provider/describer/routes.go +++ b/provider/describer/routes.go @@ -54,7 +54,7 @@ func ListRoutes(ctx context.Context, handler *RenderAPIHandler, stream *models.S } func processRoutes(ctx context.Context, handler *RenderAPIHandler, serviceID string, renderChan chan<- models.Resource, wg *sync.WaitGroup) error { - var routes []model.RouteDescription + var routes []model.RouteJSON var routeListResponse []model.RouteResponse var resp *http.Response baseURL := "https://api.render.com/v1/services/" @@ -103,13 +103,19 @@ func processRoutes(ctx context.Context, handler *RenderAPIHandler, serviceID str } for _, route := range routes { wg.Add(1) - go func(route model.RouteDescription) { + go func(route model.RouteJSON) { defer wg.Done() value := models.Resource{ ID: route.ID, Name: route.Type, Description: JSONAllFieldsMarshaller{ - Value: route, + Value: model.RouteDescription{ + ID: route.ID, + Type: route.Type, + Source: route.Source, + Destination: route.Destination, + Priority: route.Priority, + }, }, } renderChan <- value diff --git a/provider/describer/services.go b/provider/describer/services.go index 1a6d0f0d..476b7470 100644 --- a/provider/describer/services.go +++ b/provider/describer/services.go @@ -50,18 +50,62 @@ func GetService(ctx context.Context, handler *RenderAPIHandler, resourceID strin if err != nil { return nil, err } + buildFilter := model.BuildFilter{ + Paths: service.BuildFilter.Paths, + IgnoredPaths: service.BuildFilter.IgnoredPaths, + } + registryCredential := model.RegistryCredential{ + ID: service.RegistryCredential.ID, + Name: service.RegistryCredential.Name, + } + parentServer := model.ParentServer{ + ID: service.ServiceDetails.ParentServer.ID, + Name: service.ServiceDetails.ParentServer.Name, + } + previews := model.Previews{ + Generation: service.ServiceDetails.Previews.Generation, + } + serviceDetails := model.ServiceDetails{ + BuildCommand: service.ServiceDetails.BuildCommand, + ParentServer: parentServer, + PublishPath: service.ServiceDetails.PublishPath, + Previews: previews, + URL: service.ServiceDetails.URL, + BuildPlan: service.ServiceDetails.BuildPlan, + } value := models.Resource{ ID: service.ID, Name: service.Name, Description: JSONAllFieldsMarshaller{ - Value: service, + Value: model.ServiceDescription{ + ID: service.ID, + AutoDeploy: service.AutoDeploy, + Branch: service.Branch, + BuildFilter: buildFilter, + CreatedAt: service.CreatedAt, + DashboardURL: service.DashboardURL, + EnvironmentID: service.EnvironmentID, + ImagePath: service.ImagePath, + Name: service.Name, + NotifyOnFail: service.NotifyOnFail, + OwnerID: service.OwnerID, + RegistryCredential: registryCredential, + Repo: service.Repo, + RootDir: service.RootDir, + Slug: service.Slug, + Suspended: service.Suspended, + Suspenders: service.Suspenders, + Type: service.Type, + UpdatedAt: service.UpdatedAt, + ServiceDetails: serviceDetails, + }, }, } return &value, nil } func processServices(ctx context.Context, handler *RenderAPIHandler, renderChan chan<- models.Resource, wg *sync.WaitGroup) error { - var services []model.ServiceDescription + var services []model.ServiceJSON var serviceListResponse []model.ServiceResponse var resp *http.Response baseURL := "https://api.render.com/v1/services" @@ -111,13 +155,57 @@ func processServices(ctx context.Context, handler *RenderAPIHandler, renderChan } for _, service := range services { wg.Add(1) - go func(service model.ServiceDescription) { + go func(service model.ServiceJSON) { defer wg.Done() + buildFilter := model.BuildFilter{ + Paths: service.BuildFilter.Paths, + IgnoredPaths: service.BuildFilter.IgnoredPaths, + } + registryCredential := model.RegistryCredential{ + ID: service.RegistryCredential.ID, + Name: service.RegistryCredential.Name, + } + parentServer := model.ParentServer{ + ID: service.ServiceDetails.ParentServer.ID, + Name: service.ServiceDetails.ParentServer.Name, + } + previews := model.Previews{ + Generation: service.ServiceDetails.Previews.Generation, + } + serviceDetails := model.ServiceDetails{ + BuildCommand: service.ServiceDetails.BuildCommand, + ParentServer: parentServer, + PublishPath: service.ServiceDetails.PublishPath, + Previews: previews, + URL: service.ServiceDetails.URL, + BuildPlan: service.ServiceDetails.BuildPlan, + } value := models.Resource{ ID: service.ID, Name: service.Name, Description: JSONAllFieldsMarshaller{ - Value: service, + Value: model.ServiceDescription{ + ID: service.ID, + AutoDeploy: service.AutoDeploy, + Branch: service.Branch, + BuildFilter: buildFilter, + CreatedAt: service.CreatedAt, + DashboardURL: service.DashboardURL, + EnvironmentID: service.EnvironmentID, + ImagePath: service.ImagePath, + Name: service.Name, + NotifyOnFail: service.NotifyOnFail, + OwnerID: service.OwnerID, + RegistryCredential: registryCredential, + Repo: service.Repo, + RootDir: service.RootDir, + Slug: service.Slug, + Suspended: service.Suspended, + Suspenders: service.Suspenders, + Type: service.Type, + UpdatedAt: service.UpdatedAt, + ServiceDetails: serviceDetails, + }, }, } renderChan <- value @@ -126,8 +214,8 @@ func processServices(ctx context.Context, handler *RenderAPIHandler, renderChan return nil } -func processService(ctx context.Context, handler *RenderAPIHandler, resourceID string) (*model.ServiceDescription, error) { - var service model.ServiceDescription +func processService(ctx context.Context, handler *RenderAPIHandler, resourceID string) (*model.ServiceJSON, error) { + var service model.ServiceJSON var resp *http.Response baseURL := "https://api.render.com/v1/services/" diff --git a/provider/model/model.go b/provider/model/model.go index 93afd0b8..97258651 100755 --- a/provider/model/model.go +++ b/provider/model/model.go @@ -8,7 +8,7 @@ import "time" type Metadata struct{} -type Owner struct { +type OwnerJSON struct { ID string `json:"id"` Name string `json:"name"` Email string `json:"email"` @@ -16,23 +16,51 @@ type Owner struct { Type string `json:"type"` } +type Owner struct { + ID string + Name string + Email string + TwoFactorAuthEnabled bool + Type string +} + type ProjectResponse struct { - Project ProjectDescription `json:"project"` - Cursor string `json:"cursor"` + Project ProjectJSON `json:"project"` + Cursor string `json:"cursor"` } -type ProjectDescription struct { +type ProjectJSON struct { ID string `json:"id"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` Name string `json:"name"` - Owner Owner `json:"owner"` + Owner OwnerJSON `json:"owner"` EnvironmentIDs []string `json:"environmentIds"` } +type ProjectDescription struct { + ID string + CreatedAt time.Time + UpdatedAt time.Time + Name string + Owner Owner + EnvironmentIDs []string +} + type EnvironmentResponse struct { - Environment EnvironmentDescription `json:"environment"` - Cursor string `json:"cursor"` + Environment EnvironmentJSON `json:"environment"` + Cursor string `json:"cursor"` +} + +type EnvironmentJSON struct { + ID string `json:"id"` + Name string `json:"name"` + ProjectID string `json:"projectId"` + DatabasesIDs []string `json:"databasesIds"` + RedisIDs []string `json:"redisIds"` + ServiceIDs []string `json:"serviceIds"` + EnvGroupIDs []string `json:"envGroupIds"` + ProtectedStatus string `json:"protectedStatus"` } type EnvironmentDescription struct { @@ -46,108 +74,194 @@ type EnvironmentDescription struct { ProtectedStatus string `json:"protectedStatus"` } +type IPAllowJSON struct { + CIDRBlock string `json:"cidrBlock"` + Description string `json:"description"` +} + type IPAllow struct { CIDRBlock string `json:"cidrBlock"` Description string `json:"description"` } +type ReadReplicaJSON struct { + ID string `json:"id"` + Name string `json:"name"` +} + type ReadReplica struct { ID string `json:"id"` Name string `json:"name"` } type PostgresResponse struct { - Postgres PostgresDescription `json:"postgres"` - Cursor string `json:"cursor"` + Postgres PostgresJSON `json:"postgres"` + Cursor string `json:"cursor"` +} + +type PostgresJSON struct { + ID string `json:"id"` + IPAllowList []IPAllowJSON `json:"ipAllowList"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` + ExpiresAt time.Time `json:"expiresAt"` + DatabaseName string `json:"databaseName"` + DatabaseUser string `json:"databaseUser"` + EnvironmentID string `json:"environmentId"` + HighAvailabilityEnabled bool `json:"highAvailabilityEnabled"` + Name string `json:"name"` + Owner OwnerJSON `json:"owner"` + Plan string `json:"plan"` + DiskSizeGB int `json:"diskSizeGB"` + PrimaryPostgresID string `json:"primaryPostgresID"` + Region string `json:"region"` + ReadReplicas []ReadReplicaJSON `json:"readReplicas"` + Role string `json:"role"` + Status string `json:"status"` + Version string `json:"version"` + Suspended string `json:"suspended"` + Suspenders []string `json:"suspenders"` + DashboardURL string `json:"dashboardUrl"` } type PostgresDescription struct { - ID string `json:"id"` - IPAllowList []IPAllow `json:"ipAllowList"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` - ExpiresAt time.Time `json:"expiresAt"` - DatabaseName string `json:"databaseName"` - DatabaseUser string `json:"databaseUser"` - EnvironmentID string `json:"environmentId"` - HighAvailabilityEnabled bool `json:"highAvailabilityEnabled"` - Name string `json:"name"` - Owner Owner `json:"owner"` - Plan string `json:"plan"` - DiskSizeGB int `json:"diskSizeGB"` - PrimaryPostgresID string `json:"primaryPostgresID"` - Region string `json:"region"` - ReadReplicas []ReadReplica `json:"readReplicas"` - Role string `json:"role"` - Status string `json:"status"` - Version string `json:"version"` - Suspended string `json:"suspended"` - Suspenders []string `json:"suspenders"` - DashboardURL string `json:"dashboardUrl"` + ID string + IPAllowList []IPAllow + CreatedAt time.Time + UpdatedAt time.Time + ExpiresAt time.Time + DatabaseName string + DatabaseUser string + EnvironmentID string + HighAvailabilityEnabled bool + Name string + Owner Owner + Plan string + DiskSizeGB int + PrimaryPostgresID string + Region string + ReadReplicas []ReadReplica + Role string + Status string + Version string + Suspended string + Suspenders []string + DashboardURL string +} + +type BuildFilterJSON struct { + Paths []string `json:"paths"` + IgnoredPaths []string `json:"ignoredPaths"` } type BuildFilter struct { - Paths []string `json:"paths"` - IgnoredPaths []string `json:"ignoredPaths"` + Paths []string + IgnoredPaths []string } -type RegistryCredential struct { +type RegistryCredentialJSON struct { ID string `json:"id"` Name string `json:"name"` } +type RegistryCredential struct { + ID string + Name string +} + +type ServiceDetailsJSON struct { + BuildCommand string `json:"buildCommand"` + ParentServer ParentServerJSON `json:"parentServer"` + PublishPath string `json:"publishPath"` + Previews PreviewsJSON `json:"previews"` + URL string `json:"url"` + BuildPlan string `json:"buildPlan"` +} + type ServiceDetails struct { - BuildCommand string `json:"buildCommand"` - ParentServer ParentServer `json:"parentServer"` - PublishPath string `json:"publishPath"` - Previews Previews `json:"previews"` - URL string `json:"url"` - BuildPlan string `json:"buildPlan"` + BuildCommand string + ParentServer ParentServer + PublishPath string + Previews Previews + URL string + BuildPlan string } -type ParentServer struct { +type ParentServerJSON struct { ID string `json:"id"` Name string `json:"name"` } -type Previews struct { +type ParentServer struct { + ID string + Name string +} + +type PreviewsJSON struct { Generation string `json:"generation"` } +type Previews struct { + Generation string +} + type ServiceResponse struct { - Service ServiceDescription `json:"service"` - Cursor string `json:"cursor"` + Service ServiceJSON `json:"service"` + Cursor string `json:"cursor"` +} + +type ServiceJSON struct { + ID string `json:"id"` + AutoDeploy string `json:"autoDeploy"` + Branch string `json:"branch"` + BuildFilter BuildFilterJSON `json:"buildFilter"` + CreatedAt time.Time `json:"createdAt"` + DashboardURL string `json:"dashboardUrl"` + EnvironmentID string `json:"environmentId"` + ImagePath string `json:"imagePath"` + Name string `json:"name"` + NotifyOnFail string `json:"notifyOnFail"` + OwnerID string `json:"ownerId"` + RegistryCredential RegistryCredentialJSON `json:"registryCredential"` + Repo string `json:"repo"` + RootDir string `json:"rootDir"` + Slug string `json:"slug"` + Suspended string `json:"suspended"` + Suspenders []string `json:"suspenders"` + Type string `json:"type"` + UpdatedAt time.Time `json:"updatedAt"` + ServiceDetails ServiceDetailsJSON `json:"serviceDetails"` } type ServiceDescription struct { - ID string `json:"id"` - AutoDeploy string `json:"autoDeploy"` - Branch string `json:"branch"` - BuildFilter BuildFilter `json:"buildFilter"` - CreatedAt time.Time `json:"createdAt"` - DashboardURL string `json:"dashboardUrl"` - EnvironmentID string `json:"environmentId"` - ImagePath string `json:"imagePath"` - Name string `json:"name"` - NotifyOnFail string `json:"notifyOnFail"` - OwnerID string `json:"ownerId"` - RegistryCredential RegistryCredential `json:"registryCredential"` - Repo string `json:"repo"` - RootDir string `json:"rootDir"` - Slug string `json:"slug"` - Suspended string `json:"suspended"` - Suspenders []string `json:"suspenders"` - Type string `json:"type"` - UpdatedAt time.Time `json:"updatedAt"` - ServiceDetails ServiceDetails `json:"serviceDetails"` + ID string + AutoDeploy string + Branch string + BuildFilter BuildFilter + CreatedAt time.Time + DashboardURL string + EnvironmentID string + ImagePath string + Name string + NotifyOnFail string + OwnerID string + RegistryCredential RegistryCredential + Repo string + RootDir string + Slug string + Suspended string + Suspenders []string + Type string + UpdatedAt time.Time + ServiceDetails ServiceDetails } type JobResponse struct { - Job JobDescription `json:"job"` - Cursor string `json:"cursor"` + Job JobJSON `json:"job"` + Cursor string `json:"cursor"` } -type JobDescription struct { +type JobJSON struct { ID string `json:"id"` ServiceID string `json:"serviceId"` StartCommand string `json:"startCommand"` @@ -158,12 +272,23 @@ type JobDescription struct { FinishedAt time.Time `json:"finishedAt"` } +type JobDescription struct { + ID string + ServiceID string + StartCommand string + PlanID string + Status string + CreatedAt time.Time + StartedAt time.Time + FinishedAt time.Time +} + type DiskResponse struct { - Disk DiskDescription `json:"disk"` - Cursor string `json:"cursor"` + Disk DiskJSON `json:"disk"` + Cursor string `json:"cursor"` } -type DiskDescription struct { +type DiskJSON struct { ID string `json:"id"` Name string `json:"name"` SizeGB int `json:"sizeGB"` @@ -173,40 +298,73 @@ type DiskDescription struct { UpdatedAt time.Time `json:"updatedAt"` } -type Commit struct { +type DiskDescription struct { + ID string + Name string + SizeGB int + MountPath string + ServiceID string + CreatedAt time.Time + UpdatedAt time.Time +} + +type CommitJSON struct { ID string `json:"id"` Message string `json:"message"` CreatedAt time.Time `json:"createdAt"` } -type Image struct { +type Commit struct { + ID string + Message string + CreatedAt time.Time +} + +type ImageJSON struct { Ref string `json:"ref"` SHA string `json:"sha"` RegistryCredential string `json:"registryCredential"` } +type Image struct { + Ref string + SHA string + RegistryCredential string +} + type DeployResponse struct { - Deploy DeployDescription `json:"deploy"` - Cursor string `json:"cursor"` + Deploy DeployJSON `json:"deploy"` + Cursor string `json:"cursor"` +} + +type DeployJSON struct { + ID string `json:"id"` + Commit CommitJSON `json:"commit"` + Image ImageJSON `json:"image"` + Status string `json:"status"` + Trigger string `json:"trigger"` + FinishedAt time.Time `json:"finishedAt"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` } type DeployDescription struct { - ID string `json:"id"` - Commit Commit `json:"commit"` - Image Image `json:"image"` - Status string `json:"status"` - Trigger string `json:"trigger"` - FinishedAt time.Time `json:"finishedAt"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` + ID string + Commit Commit + Image Image + Status string + Trigger string + FinishedAt time.Time + CreatedAt time.Time + UpdatedAt time.Time } type BlueprintResponse struct { - BluePrint BlueprintDescription `json:"blueprint"` - Cursor string `json:"cursor"` + BluePrint BlueprintJSON `json:"blueprint"` + Cursor string `json:"cursor"` } -type BlueprintDescription struct { +type BlueprintJSON struct { ID string `json:"id"` Name string `json:"name"` Status string `json:"status"` @@ -216,48 +374,89 @@ type BlueprintDescription struct { LastSync time.Time `json:"lastSync"` } -type ServiceLink struct { +type BlueprintDescription struct { + ID string + Name string + Status string + AutoSync bool + Repo string + Branch string + LastSync time.Time +} + +type ServiceLinkJSON struct { ID string `json:"id"` Name string `json:"name"` Type string `json:"type"` } +type ServiceLink struct { + ID string + Name string + Type string +} + type EnvGroupResponse struct { - EnvGroup EnvGroupDescription `json:"envGroup"` - Cursor string `json:"cursor"` + EnvGroup EnvGroupJSON `json:"envGroup"` + Cursor string `json:"cursor"` +} + +type EnvGroupJSON struct { + ID string `json:"id"` + Name string `json:"name"` + OwnerID string `json:"ownerId"` + CreatedAt time.Time `json:"createdAt"` + UpdatedAt time.Time `json:"updatedAt"` + ServiceLinks []ServiceLinkJSON `json:"serviceLinks"` + EnvironmentID string `json:"environmentId"` } type EnvGroupDescription struct { - ID string `json:"id"` - Name string `json:"name"` - OwnerID string `json:"ownerId"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` - ServiceLinks []ServiceLink `json:"serviceLinks"` - EnvironmentID string `json:"environmentId"` + ID string + Name string + OwnerID string + CreatedAt time.Time + UpdatedAt time.Time + ServiceLinks []ServiceLink + EnvironmentID string } type HeaderResponse struct { - Header HeaderDescription `json:"header"` - Cursor string `json:"cursor"` + Header HeaderJSON `json:"header"` + Cursor string `json:"cursor"` } -type HeaderDescription struct { +type HeaderJSON struct { ID string `json:"id"` Path string `json:"path"` Name string `json:"name"` Value string `json:"value"` } +type HeaderDescription struct { + ID string + Path string + Name string + Value string +} + type RouteResponse struct { - Route RouteDescription `json:"route"` - Cursor string `json:"cursor"` + Route RouteJSON `json:"route"` + Cursor string `json:"cursor"` } -type RouteDescription struct { +type RouteJSON struct { ID string `json:"id"` Type string `json:"type"` Source string `json:"source"` Destination string `json:"destination"` Priority int `json:"priority"` } + +type RouteDescription struct { + ID string + Type string + Source string + Destination string + Priority int +} diff --git a/provider/resource_types.go b/provider/resource_types.go index 754479c0..75152b0e 100644 --- a/provider/resource_types.go +++ b/provider/resource_types.go @@ -1,120 +1,151 @@ package provider - import ( - model "github.com/opengovern/og-describer-render/pkg/sdk/models" - "github.com/opengovern/og-describer-render/provider/configs" "github.com/opengovern/og-describer-render/provider/describer" + "github.com/opengovern/og-describer-render/provider/configs" + model "github.com/opengovern/og-describer-render/pkg/sdk/models" ) - var ResourceTypes = map[string]model.ResourceType{ "Render/Blueprint": { - IntegrationType: configs.IntegrationName, - ResourceName: "Render/Blueprint", - Tags: map[string][]string{}, - Labels: map[string]string{}, - Annotations: map[string]string{}, - ListDescriber: DescribeListByRender(describer.ListBlueprints), - GetDescriber: DescribeSingleByRender(describer.GetBlueprint), + IntegrationType: configs.IntegrationName, + ResourceName: "Render/Blueprint", + Tags: map[string][]string{ + }, + Labels: map[string]string{ + }, + Annotations: map[string]string{ + }, + ListDescriber: DescribeListByRender(describer.ListBlueprints), + GetDescriber: DescribeSingleByRender(describer.GetBlueprint), }, "Render/Deploy": { - IntegrationType: configs.IntegrationName, - ResourceName: "Render/Deploy", - Tags: map[string][]string{}, - Labels: map[string]string{}, - Annotations: map[string]string{}, - ListDescriber: DescribeListByRender(describer.ListDeploys), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Render/Deploy", + Tags: map[string][]string{ + }, + Labels: map[string]string{ + }, + Annotations: map[string]string{ + }, + ListDescriber: DescribeListByRender(describer.ListDeploys), + GetDescriber: nil, }, "Render/Disk": { - IntegrationType: configs.IntegrationName, - ResourceName: "Render/Disk", - Tags: map[string][]string{}, - Labels: map[string]string{}, - Annotations: map[string]string{}, - ListDescriber: DescribeListByRender(describer.ListDisks), - GetDescriber: DescribeSingleByRender(describer.GetDisk), + IntegrationType: configs.IntegrationName, + ResourceName: "Render/Disk", + Tags: map[string][]string{ + }, + Labels: map[string]string{ + }, + Annotations: map[string]string{ + }, + ListDescriber: DescribeListByRender(describer.ListDisks), + GetDescriber: DescribeSingleByRender(describer.GetDisk), }, "Render/EnvGroup": { - IntegrationType: configs.IntegrationName, - ResourceName: "Render/EnvGroup", - Tags: map[string][]string{}, - Labels: map[string]string{}, - Annotations: map[string]string{}, - ListDescriber: DescribeListByRender(describer.ListEnvGroups), - GetDescriber: DescribeSingleByRender(describer.GetEnvGroup), + IntegrationType: configs.IntegrationName, + ResourceName: "Render/EnvGroup", + Tags: map[string][]string{ + }, + Labels: map[string]string{ + }, + Annotations: map[string]string{ + }, + ListDescriber: DescribeListByRender(describer.ListEnvGroups), + GetDescriber: DescribeSingleByRender(describer.GetEnvGroup), }, "Render/Environment": { - IntegrationType: configs.IntegrationName, - ResourceName: "Render/Environment", - Tags: map[string][]string{}, - Labels: map[string]string{}, - Annotations: map[string]string{}, - ListDescriber: DescribeListByRender(describer.ListEnvironments), - GetDescriber: DescribeSingleByRender(describer.GetEnvironment), + IntegrationType: configs.IntegrationName, + ResourceName: "Render/Environment", + Tags: map[string][]string{ + }, + Labels: map[string]string{ + }, + Annotations: map[string]string{ + }, + ListDescriber: DescribeListByRender(describer.ListEnvironments), + GetDescriber: DescribeSingleByRender(describer.GetEnvironment), }, "Render/Header": { - IntegrationType: configs.IntegrationName, - ResourceName: "Render/Header", - Tags: map[string][]string{}, - Labels: map[string]string{}, - Annotations: map[string]string{}, - ListDescriber: DescribeListByRender(describer.ListHeaders), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Render/Header", + Tags: map[string][]string{ + }, + Labels: map[string]string{ + }, + Annotations: map[string]string{ + }, + ListDescriber: DescribeListByRender(describer.ListHeaders), + GetDescriber: nil, }, "Render/Job": { - IntegrationType: configs.IntegrationName, - ResourceName: "Render/Job", - Tags: map[string][]string{}, - Labels: map[string]string{}, - Annotations: map[string]string{}, - ListDescriber: DescribeListByRender(describer.ListJobs), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Render/Job", + Tags: map[string][]string{ + }, + Labels: map[string]string{ + }, + Annotations: map[string]string{ + }, + ListDescriber: DescribeListByRender(describer.ListJobs), + GetDescriber: nil, }, "Render/PostgresInstance": { - IntegrationType: configs.IntegrationName, - ResourceName: "Render/PostgresInstance", - Tags: map[string][]string{}, - Labels: map[string]string{}, - Annotations: map[string]string{}, - ListDescriber: DescribeListByRender(describer.ListPostgresInstances), - GetDescriber: DescribeSingleByRender(describer.GetPostgresInstance), + IntegrationType: configs.IntegrationName, + ResourceName: "Render/PostgresInstance", + Tags: map[string][]string{ + }, + Labels: map[string]string{ + }, + Annotations: map[string]string{ + }, + ListDescriber: DescribeListByRender(describer.ListPostgresInstances), + GetDescriber: DescribeSingleByRender(describer.GetPostgresInstance), }, "Render/Project": { - IntegrationType: configs.IntegrationName, - ResourceName: "Render/Project", - Tags: map[string][]string{}, - Labels: map[string]string{}, - Annotations: map[string]string{}, - ListDescriber: DescribeListByRender(describer.ListProjects), - GetDescriber: DescribeSingleByRender(describer.GetProject), + IntegrationType: configs.IntegrationName, + ResourceName: "Render/Project", + Tags: map[string][]string{ + }, + Labels: map[string]string{ + }, + Annotations: map[string]string{ + }, + ListDescriber: DescribeListByRender(describer.ListProjects), + GetDescriber: DescribeSingleByRender(describer.GetProject), }, "Render/Route": { - IntegrationType: configs.IntegrationName, - ResourceName: "Render/Route", - Tags: map[string][]string{}, - Labels: map[string]string{}, - Annotations: map[string]string{}, - ListDescriber: DescribeListByRender(describer.ListRoutes), - GetDescriber: nil, + IntegrationType: configs.IntegrationName, + ResourceName: "Render/Route", + Tags: map[string][]string{ + }, + Labels: map[string]string{ + }, + Annotations: map[string]string{ + }, + ListDescriber: DescribeListByRender(describer.ListRoutes), + GetDescriber: nil, }, "Render/Service": { - IntegrationType: configs.IntegrationName, - ResourceName: "Render/Service", - Tags: map[string][]string{}, - Labels: map[string]string{}, - Annotations: map[string]string{}, - ListDescriber: DescribeListByRender(describer.ListServices), - GetDescriber: DescribeSingleByRender(describer.GetService), + IntegrationType: configs.IntegrationName, + ResourceName: "Render/Service", + Tags: map[string][]string{ + }, + Labels: map[string]string{ + }, + Annotations: map[string]string{ + }, + ListDescriber: DescribeListByRender(describer.ListServices), + GetDescriber: DescribeSingleByRender(describer.GetService), }, } diff --git a/resource_types_list.go b/resource_types_list.go new file mode 100644 index 00000000..d987c9e1 --- /dev/null +++ b/resource_types_list.go @@ -0,0 +1,15 @@ +package configs + +var ResourceTypesList = []string{ + "Render/Blueprint", + "Render/Deploy", + "Render/Disk", + "Render/EnvGroup", + "Render/Environment", + "Render/Header", + "Render/Job", + "Render/PostgresInstance", + "Render/Project", + "Render/Route", + "Render/Service", +} \ No newline at end of file