diff --git a/app/events/gitspace/category.go b/app/events/gitspace/category.go new file mode 100644 index 000000000..1f40a0eff --- /dev/null +++ b/app/events/gitspace/category.go @@ -0,0 +1,20 @@ +// Copyright 2023 Harness, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package events + +const ( + // category defines the event category used for this package. + category = "gitspace" +) diff --git a/app/events/gitspace/events.go b/app/events/gitspace/events.go new file mode 100644 index 000000000..5fbe00a8f --- /dev/null +++ b/app/events/gitspace/events.go @@ -0,0 +1,60 @@ +// Copyright 2023 Harness, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package events + +import ( + "context" + + "github.com/harness/gitness/events" + "github.com/harness/gitness/types/enum" + + "github.com/rs/zerolog/log" +) + +const ( + // List all Gitspace events below. + + GitspaceEvent events.EventType = "gitspace_event" +) + +type ( + GitspaceEventPayload struct { + EntityID int64 `json:"entity_id,omitempty"` + EntityIdentifier string `json:"entity_identifier,omitempty"` + EntityType enum.GitspaceEntityType `json:"entity_type,omitempty"` + EventType enum.GitspaceEventType `json:"event_type,omitempty"` + Created int64 `json:"created,omitempty"` + } +) + +func (r *Reporter) EmitGitspaceEvent(ctx context.Context, event events.EventType, payload *GitspaceEventPayload) { + if payload == nil { + return + } + eventID, err := events.ReporterSendEvent(r.innerReporter, ctx, event, payload) + if err != nil { + log.Ctx(ctx).Err(err).Msgf("failed to send %v event", event) + return + } + + log.Ctx(ctx).Debug().Msgf("reported %v event with id '%s'", event, eventID) +} + +func (r *Reader) RegisterGitspaceEvent( + fn events.HandlerFunc[*GitspaceEventPayload], + opts ...events.HandlerOption, +) error { + return events.ReaderRegisterEvent(r.innerReader, GitspaceEvent, fn, opts...) +} diff --git a/app/events/gitspace/reader.go b/app/events/gitspace/reader.go new file mode 100644 index 000000000..27b39a9c5 --- /dev/null +++ b/app/events/gitspace/reader.go @@ -0,0 +1,38 @@ +// Copyright 2023 Harness, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package events + +import ( + "github.com/harness/gitness/events" +) + +func NewReaderFactory(eventsSystem *events.System) (*events.ReaderFactory[*Reader], error) { + readerFactoryFunc := func(innerReader *events.GenericReader) (*Reader, error) { + return &Reader{ + innerReader: innerReader, + }, nil + } + + return events.NewReaderFactory(eventsSystem, category, readerFactoryFunc) +} + +// Reader is the event reader for this package. +type Reader struct { + innerReader *events.GenericReader +} + +func (r *Reader) Configure(opts ...events.ReaderOption) { + r.innerReader.Configure(opts...) +} diff --git a/app/events/gitspace/reporter.go b/app/events/gitspace/reporter.go new file mode 100644 index 000000000..68fdecaad --- /dev/null +++ b/app/events/gitspace/reporter.go @@ -0,0 +1,37 @@ +// Copyright 2023 Harness, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package events + +import ( + "errors" + + "github.com/harness/gitness/events" +) + +// Reporter is the event reporter for this package. +type Reporter struct { + innerReporter *events.GenericReporter +} + +func NewReporter(eventsSystem *events.System) (*Reporter, error) { + innerReporter, err := events.NewReporter(eventsSystem, category) + if err != nil { + return nil, errors.New("failed to create new GenericReporter from event system") + } + + return &Reporter{ + innerReporter: innerReporter, + }, nil +} diff --git a/app/events/gitspace/wire.go b/app/events/gitspace/wire.go new file mode 100644 index 000000000..215800d79 --- /dev/null +++ b/app/events/gitspace/wire.go @@ -0,0 +1,35 @@ +// Copyright 2023 Harness, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package events + +import ( + "github.com/harness/gitness/events" + + "github.com/google/wire" +) + +// WireSet provides a wire set for this package. +var WireSet = wire.NewSet( + ProvideReaderFactory, + ProvideReporter, +) + +func ProvideReaderFactory(eventsSystem *events.System) (*events.ReaderFactory[*Reader], error) { + return NewReaderFactory(eventsSystem) +} + +func ProvideReporter(eventsSystem *events.System) (*Reporter, error) { + return NewReporter(eventsSystem) +} diff --git a/app/services/gitspaceevent/handler.go b/app/services/gitspaceevent/handler.go new file mode 100644 index 000000000..981605c67 --- /dev/null +++ b/app/services/gitspaceevent/handler.go @@ -0,0 +1,44 @@ +// Copyright 2023 Harness, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gitspaceevent + +import ( + "context" + "fmt" + + gitspaceevents "github.com/harness/gitness/app/events/gitspace" + "github.com/harness/gitness/events" + "github.com/harness/gitness/types" +) + +func (s *Service) handleGitspaceEvent( + ctx context.Context, + event *events.Event[*gitspaceevents.GitspaceEventPayload], +) error { + gitspaceEvent := &types.GitspaceEvent{ + Event: event.Payload.EventType, + EntityID: event.Payload.EntityID, + EntityIdentifier: event.Payload.EntityIdentifier, + EntityType: event.Payload.EntityType, + Created: event.Payload.Created, + } + + err := s.gitspaceEventStore.Create(ctx, gitspaceEvent) + if err != nil { + return fmt.Errorf("failed to create gitspace event: %w", err) + } + + return nil +} diff --git a/app/services/gitspaceevent/service.go b/app/services/gitspaceevent/service.go new file mode 100644 index 000000000..4b96a0ae4 --- /dev/null +++ b/app/services/gitspaceevent/service.go @@ -0,0 +1,92 @@ +// Copyright 2023 Harness, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gitspaceevent + +import ( + "context" + "errors" + "fmt" + "time" + + gitspaceevents "github.com/harness/gitness/app/events/gitspace" + "github.com/harness/gitness/app/store" + "github.com/harness/gitness/events" + "github.com/harness/gitness/stream" +) + +const groupGitspaceEvents = "gitness:gitspace" + +type Config struct { + EventReaderName string + Concurrency int + MaxRetries int +} + +func (c *Config) Sanitize() error { + if c == nil { + return errors.New("config is required") + } + if c.EventReaderName == "" { + return errors.New("config.EventReaderName is required") + } + if c.Concurrency < 1 { + return errors.New("config.Concurrency has to be a positive number") + } + if c.MaxRetries < 0 { + return errors.New("config.MaxRetries can't be negative") + } + return nil +} + +type Service struct { + config Config + gitspaceEventStore store.GitspaceEventStore +} + +func NewService( + ctx context.Context, + config Config, + gitspaceEventReaderFactory *events.ReaderFactory[*gitspaceevents.Reader], + gitspaceEventStore store.GitspaceEventStore, +) (*Service, error) { + if err := config.Sanitize(); err != nil { + return nil, fmt.Errorf("provided gitspace event service config is invalid: %w", err) + } + service := &Service{ + config: config, + gitspaceEventStore: gitspaceEventStore, + } + + _, err := gitspaceEventReaderFactory.Launch(ctx, groupGitspaceEvents, config.EventReaderName, + func(r *gitspaceevents.Reader) error { + const idleTimeout = 1 * time.Minute + r.Configure( + stream.WithConcurrency(config.Concurrency), + stream.WithHandlerOptions( + stream.WithIdleTimeout(idleTimeout), + stream.WithMaxRetries(config.MaxRetries), + )) + + // register gitspace config events + _ = r.RegisterGitspaceEvent(service.handleGitspaceEvent) + + return nil + }) + if err != nil { + return nil, fmt.Errorf("failed to launch gitspace event reader: %w", err) + } + + return service, nil +} diff --git a/app/services/gitspaceevent/wire.go b/app/services/gitspaceevent/wire.go new file mode 100644 index 000000000..2c24452f6 --- /dev/null +++ b/app/services/gitspaceevent/wire.go @@ -0,0 +1,43 @@ +// Copyright 2023 Harness, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gitspaceevent + +import ( + "context" + + gitspaceevents "github.com/harness/gitness/app/events/gitspace" + "github.com/harness/gitness/app/store" + "github.com/harness/gitness/events" + + "github.com/google/wire" +) + +// WireSet provides a wire set for this package. +var WireSet = wire.NewSet( + ProvideService, +) + +func ProvideService(ctx context.Context, + config Config, + gitspaceEventReaderFactory *events.ReaderFactory[*gitspaceevents.Reader], + gitspaceEventStore store.GitspaceEventStore, +) (*Service, error) { + return NewService( + ctx, + config, + gitspaceEventReaderFactory, + gitspaceEventStore, + ) +} diff --git a/app/store/database.go b/app/store/database.go index ec590e23e..a6263f4f8 100644 --- a/app/store/database.go +++ b/app/store/database.go @@ -832,4 +832,18 @@ type ( // ListByFingerprint returns public keys given a fingerprint and key usage. ListByFingerprint(ctx context.Context, fingerprint string) ([]types.PublicKey, error) } + + GitspaceEventStore interface { + // Create creates a new record for the given gitspace event. + Create(ctx context.Context, gitspaceEvent *types.GitspaceEvent) error + // List returns all events for the given query filter. + List(ctx context.Context, filter *types.GitspaceEventFilter) ([]*types.GitspaceEvent, error) + // FindLatestByTypeAndGitspaceConfigID returns the latest gitspace event for the given config ID and event type + // where the entity type is gitspace config. + FindLatestByTypeAndGitspaceConfigID( + ctx context.Context, + eventType enum.GitspaceEventType, + gitspaceConfigID int64, + ) (*types.GitspaceEvent, error) + } ) diff --git a/app/store/database/gitspace_event.go b/app/store/database/gitspace_event.go new file mode 100644 index 000000000..2885372ff --- /dev/null +++ b/app/store/database/gitspace_event.go @@ -0,0 +1,150 @@ +// Copyright 2023 Harness, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package database + +import ( + "context" + "fmt" + + "github.com/harness/gitness/app/store" + "github.com/harness/gitness/store/database" + "github.com/harness/gitness/store/database/dbtx" + "github.com/harness/gitness/types" + "github.com/harness/gitness/types/enum" + + "github.com/jmoiron/sqlx" +) + +var _ store.GitspaceEventStore = (*gitspaceEventStore)(nil) + +const ( + gitspaceEventIDColumn = `geven_id` + gitspaceEventsColumns = ` + geven_event, + geven_created, + geven_entity_type, + geven_entity_uid, + geven_entity_id + ` + gitspaceEventsColumnsWithID = gitspaceEventIDColumn + `, + ` + gitspaceEventsColumns + gitspaceEventsTable = `gitspace_events` +) + +type gitspaceEventStore struct { + db *sqlx.DB +} + +type gitspaceEvent struct { + ID int64 `db:"geven_id"` + Event enum.GitspaceEventType `db:"geven_event"` + Created int64 `db:"geven_created"` + EntityType enum.GitspaceEntityType `db:"geven_entity_type"` + EntityIdentifier string `db:"geven_entity_uid"` + EntityID int64 `db:"geven_entity_id"` +} + +func NewGitspaceEventStore(db *sqlx.DB) store.GitspaceEventStore { + return &gitspaceEventStore{ + db: db, + } +} + +func (g gitspaceEventStore) FindLatestByTypeAndGitspaceConfigID( + ctx context.Context, + eventType enum.GitspaceEventType, + gitspaceConfigID int64, +) (*types.GitspaceEvent, error) { + stmt := database.Builder. + Select(gitspaceEventsColumnsWithID). + From(gitspaceEventsTable). + Where("geven_event = $1", eventType). + Where("geven_entity_id = $2", gitspaceConfigID). + OrderBy("geven_created DESC") + sql, args, err := stmt.ToSql() + if err != nil { + return nil, fmt.Errorf("failed to convert squirrel builder to sql: %w", err) + } + db := dbtx.GetAccessor(ctx, g.db) + gitspaceEventEntity := new(gitspaceEvent) + if err = db.GetContext(ctx, gitspaceEventEntity, sql, args...); err != nil { + return nil, database.ProcessSQLErrorf(ctx, err, "Failed to find gitspaceEvent") + } + return g.mapGitspaceEvent(gitspaceEventEntity), nil +} + +func (g gitspaceEventStore) Create(ctx context.Context, gitspaceEvent *types.GitspaceEvent) error { + stmt := database.Builder. + Insert(gitspaceEventsTable). + Columns(gitspaceEventsColumns). + Values( + gitspaceEvent.Event, + gitspaceEvent.Created, + gitspaceEvent.EntityType, + gitspaceEvent.EntityIdentifier, + gitspaceEvent.EntityID, + ). + Suffix("RETURNING " + gitspaceEventIDColumn) + db := dbtx.GetAccessor(ctx, g.db) + sql, args, err := stmt.ToSql() + if err != nil { + return fmt.Errorf("failed to convert squirrel builder to sql: %w", err) + } + if err = db.QueryRowContext(ctx, sql, args...).Scan(&gitspaceEvent.ID); err != nil { + return database.ProcessSQLErrorf(ctx, err, "%s query failed", gitspaceEventsTable) + } + return nil +} + +func (g gitspaceEventStore) List( + ctx context.Context, + filter *types.GitspaceEventFilter, +) ([]*types.GitspaceEvent, error) { + stmt := database.Builder. + Select(gitspaceEventsColumnsWithID). + From(gitspaceEventsTable). + Where("geven_entity_id = $1", filter.EntityID). + Where("geven_entity_type = $2", filter.EntityType) + sql, args, err := stmt.ToSql() + if err != nil { + return nil, fmt.Errorf("failed to convert squirrel builder to sql: %w", err) + } + db := dbtx.GetAccessor(ctx, g.db) + gitspaceEventEntities := make([]*gitspaceEvent, 0) + if err = db.SelectContext(ctx, gitspaceEventEntities, sql, args...); err != nil { + return nil, database.ProcessSQLErrorf(ctx, err, "Failed to find gitspaceEvent") + } + gitspaceEvents := g.mapGitspaceEvents(gitspaceEventEntities) + return gitspaceEvents, nil +} + +func (g gitspaceEventStore) mapGitspaceEvents(gitspaceEventEntities []*gitspaceEvent) []*types.GitspaceEvent { + gitspaceEvents := make([]*types.GitspaceEvent, len(gitspaceEventEntities)) + for index, gitspaceEventEntity := range gitspaceEventEntities { + currentEntity := gitspaceEventEntity + gitspaceEvents[index] = g.mapGitspaceEvent(currentEntity) + } + return gitspaceEvents +} + +func (g gitspaceEventStore) mapGitspaceEvent(event *gitspaceEvent) *types.GitspaceEvent { + return &types.GitspaceEvent{ + Event: event.Event, + Created: event.Created, + EntityType: event.EntityType, + EntityIdentifier: event.EntityIdentifier, + EntityID: event.EntityID, + } +} diff --git a/cli/operations/server/config.go b/cli/operations/server/config.go index 064175054..be5491d00 100644 --- a/cli/operations/server/config.go +++ b/cli/operations/server/config.go @@ -25,6 +25,7 @@ import ( "github.com/harness/gitness/app/gitspace/orchestrator/container" "github.com/harness/gitness/app/services/cleanup" "github.com/harness/gitness/app/services/codeowners" + "github.com/harness/gitness/app/services/gitspaceevent" "github.com/harness/gitness/app/services/keywordsearch" "github.com/harness/gitness/app/services/notification" "github.com/harness/gitness/app/services/trigger" @@ -415,3 +416,12 @@ func ProvideGitspaceContainerOrchestratorConfig(config *types.Config) (*containe DefaultBindMountSourceBasePath: bindMountSourceBasePath, }, nil } + +// ProvideGitspaceEventConfig loads the gitspace event service config from the main config. +func ProvideGitspaceEventConfig(config *types.Config) gitspaceevent.Config { + return gitspaceevent.Config{ + EventReaderName: config.InstanceID, + Concurrency: config.Gitspace.Events.Concurrency, + MaxRetries: config.Gitspace.Events.MaxRetries, + } +} diff --git a/types/config.go b/types/config.go index 43ae6c754..dbcf81cea 100644 --- a/types/config.go +++ b/types/config.go @@ -403,5 +403,10 @@ type Config struct { // Sub-directories will be created from this eg /gitspace/space1/space2/config1 // If left blank, it will be set to $HOME/.gitness DefaultBindMountSourceBasePath string `envconfig:"GITNESS_GITSPACE_DEFAULT_BIND_MOUNT_SOURCE_BASE_PATH"` + + Events struct { + Concurrency int `envconfig:"GITNESS_GITSPACE_EVENTS_CONCURRENCY" default:"4"` + MaxRetries int `envconfig:"GITNESS_GITSPACE_EVENTS_MAX_RETRIES" default:"3"` + } } } diff --git a/types/enum/gitspace_entity_type.go b/types/enum/gitspace_entity_type.go new file mode 100644 index 000000000..828698197 --- /dev/null +++ b/types/enum/gitspace_entity_type.go @@ -0,0 +1,28 @@ +// Copyright 2023 Harness, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package enum + +type GitspaceEntityType string + +func (GitspaceEntityType) Enum() []interface{} { return toInterfaceSlice(gitspaceEntityTypes) } + +var gitspaceEntityTypes = []GitspaceEntityType{ + GitspaceEntityTypeGitspaceConfig, GitspaceEntityTypeGitspaceInstance, +} + +const ( + GitspaceEntityTypeGitspaceConfig GitspaceEntityType = "gitspace_config" + GitspaceEntityTypeGitspaceInstance GitspaceEntityType = "gitspace_instance" +) diff --git a/types/enum/gitspace_event_type.go b/types/enum/gitspace_event_type.go new file mode 100644 index 000000000..73d08937a --- /dev/null +++ b/types/enum/gitspace_event_type.go @@ -0,0 +1,133 @@ +// Copyright 2023 Harness, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package enum + +type GitspaceEventType string + +func (GitspaceEventType) Enum() []interface{} { + return toInterfaceSlice(gitspaceEventTypes) +} + +var gitspaceEventTypes = []GitspaceEventType{ + GitspaceEventTypeGitspaceActionStart, + GitspaceEventTypeGitspaceActionStartCompleted, + GitspaceEventTypeGitspaceActionStartFailed, + + GitspaceEventTypeGitspaceActionStop, + GitspaceEventTypeGitspaceActionStopCompleted, + GitspaceEventTypeGitspaceActionStopFailed, + + GitspaceEventTypeInfraProvisioningStart, + GitspaceEventTypeInfraProvisioningCompleted, + GitspaceEventTypeInfraProvisioningFailed, + + GitspaceEventTypeInfraUnprovisioningStart, + GitspaceEventTypeInfraUnprovisioningCompleted, + GitspaceEventTypeInfraUnprovisioningFailed, + + GitspaceEventTypeAgentConnectStart, + GitspaceEventTypeAgentConnectCompleted, + GitspaceEventTypeAgentConnectFailed, + + GitspaceEventTypeAgentGitspaceCreationStart, + GitspaceEventTypeAgentGitspaceCreationCompleted, + GitspaceEventTypeAgentGitspaceCreationFailed, + + GitspaceEventTypeAgentGitspaceStateReportRunning, + GitspaceEventTypeAgentGitspaceStateReportError, + GitspaceEventTypeAgentGitspaceStateReportStopped, + GitspaceEventTypeAgentGitspaceStateReportUnknown, +} + +var eventsMessageMap = eventsMessageMapping() + +const ( + // Start action events. + GitspaceEventTypeGitspaceActionStart GitspaceEventType = "gitspace_action_start" + GitspaceEventTypeGitspaceActionStartCompleted GitspaceEventType = "gitspace_action_start_completed" + GitspaceEventTypeGitspaceActionStartFailed GitspaceEventType = "gitspace_action_start_failed" + + // Stop action events. + GitspaceEventTypeGitspaceActionStop GitspaceEventType = "gitspace_action_stop" + GitspaceEventTypeGitspaceActionStopCompleted GitspaceEventType = "gitspace_action_stop_completed" + GitspaceEventTypeGitspaceActionStopFailed GitspaceEventType = "gitspace_action_stop_failed" + + // Infra provisioning events. + GitspaceEventTypeInfraProvisioningStart GitspaceEventType = "infra_provisioning_start" + GitspaceEventTypeInfraProvisioningCompleted GitspaceEventType = "infra_provisioning_completed" + GitspaceEventTypeInfraProvisioningFailed GitspaceEventType = "infra_provisioning_failed" + + // Infra unprovisioning events. + GitspaceEventTypeInfraUnprovisioningStart GitspaceEventType = "infra_unprovisioning_start" + GitspaceEventTypeInfraUnprovisioningCompleted GitspaceEventType = "infra_unprovisioning_completed" + GitspaceEventTypeInfraUnprovisioningFailed GitspaceEventType = "infra_unprovisioning_failed" + + // Agent connection events. + GitspaceEventTypeAgentConnectStart GitspaceEventType = "agent_connect_start" + GitspaceEventTypeAgentConnectCompleted GitspaceEventType = "agent_connect_completed" + GitspaceEventTypeAgentConnectFailed GitspaceEventType = "agent_connect_failed" + + // Gitspace creation events. + GitspaceEventTypeAgentGitspaceCreationStart GitspaceEventType = "agent_gitspace_creation_start" + GitspaceEventTypeAgentGitspaceCreationCompleted GitspaceEventType = "agent_gitspace_creation_completed" + GitspaceEventTypeAgentGitspaceCreationFailed GitspaceEventType = "agent_gitspace_creation_failed" + + // Gitspace state events. + GitspaceEventTypeAgentGitspaceStateReportRunning GitspaceEventType = "agent_gitspace_state_report_running" + GitspaceEventTypeAgentGitspaceStateReportError GitspaceEventType = "agent_gitspace_state_report_error" + GitspaceEventTypeAgentGitspaceStateReportStopped GitspaceEventType = "agent_gitspace_state_report_stopped" + GitspaceEventTypeAgentGitspaceStateReportUnknown GitspaceEventType = "agent_gitspace_state_report_unknown" +) + +func (e GitspaceEventType) GetValue() string { + return eventsMessageMap[e] +} + +// TODO: Move eventsMessageMapping() to controller. + +func eventsMessageMapping() map[GitspaceEventType]string { + var gitspaceConfigsMap = make(map[GitspaceEventType]string) + + gitspaceConfigsMap[GitspaceEventTypeGitspaceActionStart] = "Starting Gitspace..." + gitspaceConfigsMap[GitspaceEventTypeGitspaceActionStartCompleted] = "Started Gitspace" + gitspaceConfigsMap[GitspaceEventTypeGitspaceActionStartFailed] = "Starting Gitspace Failed" + + gitspaceConfigsMap[GitspaceEventTypeGitspaceActionStop] = "Stopping Gitspace" + gitspaceConfigsMap[GitspaceEventTypeGitspaceActionStopCompleted] = "Stopped Gitspace" + gitspaceConfigsMap[GitspaceEventTypeGitspaceActionStopFailed] = "Stopping Gitspace Failed" + + gitspaceConfigsMap[GitspaceEventTypeInfraProvisioningStart] = "Provisioning Infrastructure..." + gitspaceConfigsMap[GitspaceEventTypeInfraProvisioningCompleted] = "Provisioning Infrastructure Completed" + gitspaceConfigsMap[GitspaceEventTypeInfraProvisioningFailed] = "Provisioning Infrastructure Failed" + + gitspaceConfigsMap[GitspaceEventTypeInfraUnprovisioningStart] = "Unprovisioning Infrastructure..." + gitspaceConfigsMap[GitspaceEventTypeInfraUnprovisioningCompleted] = "Unprovisioning Infrastructure Completed" + gitspaceConfigsMap[GitspaceEventTypeInfraUnprovisioningFailed] = "Unprovisioning Infrastructure Failed" + + gitspaceConfigsMap[GitspaceEventTypeAgentConnectStart] = "Connecting to the gitspace agent..." + gitspaceConfigsMap[GitspaceEventTypeAgentConnectCompleted] = "Connected to the gitspace agent" + gitspaceConfigsMap[GitspaceEventTypeAgentConnectFailed] = "Failed connecting to the gitspace agent" + + gitspaceConfigsMap[GitspaceEventTypeAgentGitspaceCreationStart] = "Setting up the gitspace..." + gitspaceConfigsMap[GitspaceEventTypeAgentGitspaceCreationCompleted] = "Successfully setup the gitspace" + gitspaceConfigsMap[GitspaceEventTypeAgentGitspaceCreationFailed] = "Failed to setup the gitspace" + + gitspaceConfigsMap[GitspaceEventTypeAgentGitspaceStateReportRunning] = "Gitspace is running" + gitspaceConfigsMap[GitspaceEventTypeAgentGitspaceStateReportStopped] = "Gitspace is stopped" + gitspaceConfigsMap[GitspaceEventTypeAgentGitspaceStateReportUnknown] = "Gitspace is in unknown state" + gitspaceConfigsMap[GitspaceEventTypeAgentGitspaceStateReportError] = "Gitspace has an error" + + return gitspaceConfigsMap +} diff --git a/types/gitspace_event.go b/types/gitspace_event.go new file mode 100644 index 000000000..b6e1c78fb --- /dev/null +++ b/types/gitspace_event.go @@ -0,0 +1,37 @@ +// Copyright 2023 Harness, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package types + +import "github.com/harness/gitness/types/enum" + +type GitspaceEvent struct { + ID int64 `json:"-"` + Event enum.GitspaceEventType `json:"event,omitempty"` + EntityID int64 `json:"-"` + EntityIdentifier string `json:"entity_identifier,omitempty"` + EntityType enum.GitspaceEntityType `json:"entity_type,omitempty"` + Created int64 `json:"timestamp,omitempty"` +} + +type GitspaceEventResponse struct { + GitspaceEvent + EventTime string `json:"event_time,omitempty"` + Message string `json:"message,omitempty"` +} + +type GitspaceEventFilter struct { + EntityID int64 + EntityType enum.GitspaceEntityType +}