From 0f8eb568e230cae7dadd6468e905948bb9f05c22 Mon Sep 17 00:00:00 2001 From: Dhruv Dhruv Date: Fri, 16 Aug 2024 08:31:05 +0000 Subject: [PATCH] feat: [CDE-241]: Adding protocol to the gitspace port returned by the IDE and corresponding changes. Fixing gitspace instance's reference instead of value in the orchestrator. (#2521) * feat: [CDE-241]: Addressing review comment. * feat: [CDE-241]: Addressing review comment. * feat: [CDE-241]: Adding protocol to the gitspace port returned by the IDE and corresponding changes. Fixing gitspace instance's reference instead of value in the orchestrator. --- app/gitspace/infrastructure/find.go | 2 +- app/gitspace/infrastructure/provision.go | 12 +++---- app/gitspace/infrastructure/provisioner.go | 4 +-- .../orchestrator/container/embedded_docker.go | 1 - app/gitspace/orchestrator/ide/ide.go | 3 +- app/gitspace/orchestrator/ide/vscode.go | 8 +++-- app/gitspace/orchestrator/ide/vscodeweb.go | 8 +++-- .../orchestrator/orchestrator_impl.go | 35 ++++++++++--------- infraprovider/docker_provider.go | 6 ++-- infraprovider/infra_provider.go | 11 ++++-- types/enum/communication_protocol.go | 28 +++++++++++++++ types/gitspace_port.go | 22 ++++++++++++ 12 files changed, 103 insertions(+), 37 deletions(-) create mode 100644 types/enum/communication_protocol.go create mode 100644 types/gitspace_port.go diff --git a/app/gitspace/infrastructure/find.go b/app/gitspace/infrastructure/find.go index c21967c2e..87e257be8 100644 --- a/app/gitspace/infrastructure/find.go +++ b/app/gitspace/infrastructure/find.go @@ -27,7 +27,7 @@ func (i infraProvisioner) Find( ctx context.Context, infraProviderResource types.InfraProviderResource, gitspaceConfig types.GitspaceConfig, - requiredGitspacePorts []int, + requiredGitspacePorts []types.GitspacePort, ) (*types.Infrastructure, error) { infraProviderEntity, err := i.getConfigFromResource(ctx, infraProviderResource) if err != nil { diff --git a/app/gitspace/infrastructure/provision.go b/app/gitspace/infrastructure/provision.go index f577459a9..abd8bbb63 100644 --- a/app/gitspace/infrastructure/provision.go +++ b/app/gitspace/infrastructure/provision.go @@ -31,7 +31,7 @@ func (i infraProvisioner) TriggerProvision( ctx context.Context, infraProviderResource types.InfraProviderResource, gitspaceConfig types.GitspaceConfig, - requiredPorts []int, + requiredGitspacePorts []types.GitspacePort, ) error { infraProviderEntity, err := i.getConfigFromResource(ctx, infraProviderResource) if err != nil { @@ -45,10 +45,10 @@ func (i infraProvisioner) TriggerProvision( if infraProvider.ProvisioningType() == enum.InfraProvisioningTypeNew { return i.triggerProvisionForNewProvisioning( - ctx, infraProviderResource, infraProvider, infraProviderEntity.Type, gitspaceConfig, requiredPorts) + ctx, infraProviderResource, infraProvider, infraProviderEntity.Type, gitspaceConfig, requiredGitspacePorts) } return i.triggerProvisionForExistingProvisioning( - ctx, infraProviderResource, infraProvider, gitspaceConfig, requiredPorts) + ctx, infraProviderResource, infraProvider, gitspaceConfig, requiredGitspacePorts) } func (i infraProvisioner) triggerProvisionForNewProvisioning( @@ -57,7 +57,7 @@ func (i infraProvisioner) triggerProvisionForNewProvisioning( infraProvider infraprovider.InfraProvider, infraProviderType enum.InfraProviderType, gitspaceConfig types.GitspaceConfig, - requiredGitspacePorts []int, + requiredGitspacePorts []types.GitspacePort, ) error { infraProvisionedLatest, _ := i.infraProvisionedStore.FindLatestByGitspaceInstanceID( ctx, gitspaceConfig.SpaceID, gitspaceConfig.GitspaceInstance.ID) @@ -140,7 +140,7 @@ func (i infraProvisioner) triggerProvisionForExistingProvisioning( infraProviderResource types.InfraProviderResource, infraProvider infraprovider.InfraProvider, gitspaceConfig types.GitspaceConfig, - requiredPorts []int, + requiredGitspacePorts []types.GitspacePort, ) error { allParams, err := i.getAllParamsFromDB(ctx, infraProviderResource, infraProvider) if err != nil { @@ -159,7 +159,7 @@ func (i infraProvisioner) triggerProvisionForExistingProvisioning( gitspaceConfig.Identifier, gitspaceConfig.GitspaceInstance.Identifier, 0, // NOTE: Agent port is not required for provisioning type Existing. - requiredPorts, + requiredGitspacePorts, allParams, ) if err != nil { diff --git a/app/gitspace/infrastructure/provisioner.go b/app/gitspace/infrastructure/provisioner.go index 0053c9461..461f3b32a 100644 --- a/app/gitspace/infrastructure/provisioner.go +++ b/app/gitspace/infrastructure/provisioner.go @@ -29,7 +29,7 @@ type InfraProvisioner interface { ctx context.Context, infraProviderResource types.InfraProviderResource, gitspaceConfig types.GitspaceConfig, - requiredGitspacePorts []int, + requiredGitspacePorts []types.GitspacePort, ) error // ResumeProvision stores the provisioned infra details in the db depending on the provisioning type. @@ -73,6 +73,6 @@ type InfraProvisioner interface { ctx context.Context, infraProviderResource types.InfraProviderResource, gitspaceConfig types.GitspaceConfig, - requiredGitspacePorts []int, + requiredGitspacePorts []types.GitspacePort, ) (*types.Infrastructure, error) } diff --git a/app/gitspace/orchestrator/container/embedded_docker.go b/app/gitspace/orchestrator/container/embedded_docker.go index be5030f0b..7751018ad 100644 --- a/app/gitspace/orchestrator/container/embedded_docker.go +++ b/app/gitspace/orchestrator/container/embedded_docker.go @@ -90,7 +90,6 @@ func (e *EmbeddedDockerOrchestrator) CreateAndStartGitspace( gitspaceConfig.GitspaceInstance.AccessKey != nil { accessKey = *gitspaceConfig.GitspaceInstance.AccessKey } else { - log.Error().Msgf("no access key is configured: %s", gitspaceConfig.Identifier) return nil, fmt.Errorf("no access key is configured: %s", gitspaceConfig.Identifier) } diff --git a/app/gitspace/orchestrator/ide/ide.go b/app/gitspace/orchestrator/ide/ide.go index 09960d944..0e4b7fa35 100644 --- a/app/gitspace/orchestrator/ide/ide.go +++ b/app/gitspace/orchestrator/ide/ide.go @@ -18,6 +18,7 @@ import ( "context" "github.com/harness/gitness/app/gitspace/orchestrator/devcontainer" + "github.com/harness/gitness/types" "github.com/harness/gitness/types/enum" ) @@ -30,7 +31,7 @@ type IDE interface { Run(ctx context.Context, exec *devcontainer.Exec) ([]byte, error) // Port provides the port which will be used by this IDE. - Port() int + Port() *types.GitspacePort // Type provides the IDE type to which the service belongs. Type() enum.IDEType diff --git a/app/gitspace/orchestrator/ide/vscode.go b/app/gitspace/orchestrator/ide/vscode.go index d1f100318..5d80e928c 100644 --- a/app/gitspace/orchestrator/ide/vscode.go +++ b/app/gitspace/orchestrator/ide/vscode.go @@ -21,6 +21,7 @@ import ( "github.com/harness/gitness/app/gitspace/orchestrator/devcontainer" "github.com/harness/gitness/app/gitspace/orchestrator/template" + "github.com/harness/gitness/types" "github.com/harness/gitness/types/enum" ) @@ -92,8 +93,11 @@ func (v *VSCode) Run(ctx context.Context, exec *devcontainer.Exec) ([]byte, erro } // Port returns the port on which the ssh-server is listening. -func (v *VSCode) Port() int { - return v.config.Port +func (v *VSCode) Port() *types.GitspacePort { + return &types.GitspacePort{ + Port: v.config.Port, + Protocol: enum.CommunicationProtocolSSH, + } } func (v *VSCode) Type() enum.IDEType { diff --git a/app/gitspace/orchestrator/ide/vscodeweb.go b/app/gitspace/orchestrator/ide/vscodeweb.go index b913c5815..caf31af97 100644 --- a/app/gitspace/orchestrator/ide/vscodeweb.go +++ b/app/gitspace/orchestrator/ide/vscodeweb.go @@ -27,6 +27,7 @@ import ( "github.com/harness/gitness/app/gitspace/orchestrator/devcontainer" "github.com/harness/gitness/app/gitspace/orchestrator/template" + "github.com/harness/gitness/types" "github.com/harness/gitness/types/enum" "github.com/docker/docker/api/types/container" @@ -115,8 +116,11 @@ func (v *VSCodeWeb) Run(ctx context.Context, exec *devcontainer.Exec) ([]byte, e } // PortAndProtocol returns the port on which the code-server is listening. -func (v *VSCodeWeb) Port() int { - return v.config.Port +func (v *VSCodeWeb) Port() *types.GitspacePort { + return &types.GitspacePort{ + Port: v.config.Port, + Protocol: enum.CommunicationProtocolHTTP, + } } func (v *VSCodeWeb) Type() enum.IDEType { diff --git a/app/gitspace/orchestrator/orchestrator_impl.go b/app/gitspace/orchestrator/orchestrator_impl.go index 92a342b93..4e638e52d 100644 --- a/app/gitspace/orchestrator/orchestrator_impl.go +++ b/app/gitspace/orchestrator/orchestrator_impl.go @@ -290,18 +290,18 @@ func (o orchestrator) ResumeStartGitspace( gitspaceConfig types.GitspaceConfig, provisionedInfra types.Infrastructure, ) (types.GitspaceInstance, error) { - gitspaceInstance := *gitspaceConfig.GitspaceInstance + gitspaceInstance := gitspaceConfig.GitspaceInstance gitspaceInstance.State = enum.GitspaceInstanceStateError secretResolver, err := o.getSecretResolver(gitspaceInstance.AccessType) if err != nil { log.Err(err).Msgf("could not find secret resolver for type: %s", gitspaceInstance.AccessType) - return gitspaceInstance, err + return *gitspaceInstance, err } rootSpaceID, _, err := paths.DisectRoot(gitspaceConfig.SpacePath) if err != nil { log.Err(err).Msgf("unable to find root space id from space path: %s", gitspaceConfig.SpacePath) - return gitspaceInstance, err + return *gitspaceInstance, err } resolvedSecret, err := secretResolver.Resolve(ctx, secret.ResolutionContext{ UserIdentifier: gitspaceConfig.UserID, @@ -312,13 +312,13 @@ func (o orchestrator) ResumeStartGitspace( if err != nil { log.Err(err).Msgf("could not resolve secret type: %s, ref: %s", gitspaceInstance.AccessType, *gitspaceInstance.AccessKeyRef) - return gitspaceInstance, err + return *gitspaceInstance, err } gitspaceInstance.AccessKey = &resolvedSecret.SecretValue ideSvc, err := o.getIDEService(gitspaceConfig) if err != nil { - return gitspaceInstance, err + return *gitspaceInstance, err } idePort := ideSvc.Port() @@ -327,18 +327,19 @@ func (o orchestrator) ResumeStartGitspace( if err != nil { o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraProvisioningFailed) - return gitspaceInstance, fmt.Errorf( + return *gitspaceInstance, fmt.Errorf( "cannot provision infrastructure for ID %d: %w", gitspaceConfig.InfraProviderResourceID, err) } if provisionedInfra.Status != enum.InfraStatusProvisioned { o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraProvisioningFailed) - return gitspaceInstance, fmt.Errorf( + return *gitspaceInstance, fmt.Errorf( "infra state is %v, should be %v for gitspace instance identifier %s", provisionedInfra.Status, enum.InfraStatusProvisioned, - gitspaceConfig.GitspaceInstance.Identifier) + gitspaceConfig.GitspaceInstance.Identifier, + ) } o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeInfraProvisioningCompleted) @@ -349,7 +350,7 @@ func (o orchestrator) ResumeStartGitspace( if err != nil { o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeFetchDevcontainerFailed) - return gitspaceInstance, fmt.Errorf( + return *gitspaceInstance, fmt.Errorf( "failed to fetch code repo details for gitspace config ID %w %d", err, gitspaceConfig.ID) } devcontainerConfig := scmResolvedDetails.DevcontainerConfig @@ -366,7 +367,7 @@ func (o orchestrator) ResumeStartGitspace( if err != nil { o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectFailed) - return gitspaceInstance, fmt.Errorf("couldn't call the agent health API: %w", err) + return *gitspaceInstance, fmt.Errorf("couldn't call the agent health API: %w", err) } o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentConnectCompleted) @@ -381,7 +382,7 @@ func (o orchestrator) ResumeStartGitspace( if err != nil { o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceCreationFailed) - return gitspaceInstance, fmt.Errorf("couldn't call the agent start API: %w", err) + return *gitspaceInstance, fmt.Errorf("couldn't call the agent start API: %w", err) } o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeAgentGitspaceCreationCompleted) @@ -390,10 +391,10 @@ func (o orchestrator) ResumeStartGitspace( var forwardedPort string - if provisionedInfra.GitspacePortMappings[idePort].PublishedPort == 0 { - forwardedPort = startResponse.PublishedPorts[idePort] + if provisionedInfra.GitspacePortMappings[idePort.Port].PublishedPort == 0 { + forwardedPort = startResponse.PublishedPorts[idePort.Port] } else { - forwardedPort = strconv.Itoa(provisionedInfra.GitspacePortMappings[idePort].ForwardedPort) + forwardedPort = strconv.Itoa(provisionedInfra.GitspacePortMappings[idePort.Port].ForwardedPort) } scheme := provisionedInfra.GitspaceScheme @@ -431,7 +432,7 @@ func (o orchestrator) ResumeStartGitspace( o.emitGitspaceEvent(ctx, gitspaceConfig, enum.GitspaceEventTypeGitspaceActionStartCompleted) - return gitspaceInstance, nil + return *gitspaceInstance, nil } func (o orchestrator) getSecretResolver(accessType enum.GitspaceAccessType) (secret.Resolver, error) { @@ -515,7 +516,7 @@ func (o orchestrator) ResumeDeleteGitspace( func (o orchestrator) getPortsRequiredForGitspace( gitspaceConfig types.GitspaceConfig, -) ([]int, error) { +) ([]types.GitspacePort, error) { // TODO: What if the required ports in the config have deviated from when the last instance was created? ideSvc, err := o.getIDEService(gitspaceConfig) if err != nil { @@ -523,7 +524,7 @@ func (o orchestrator) getPortsRequiredForGitspace( } idePort := ideSvc.Port() - return []int{idePort}, nil + return []types.GitspacePort{*idePort}, nil } func (o orchestrator) GetGitspaceLogs(ctx context.Context, gitspaceConfig types.GitspaceConfig) (string, error) { diff --git a/infraprovider/docker_provider.go b/infraprovider/docker_provider.go index a90094d17..4f9856123 100644 --- a/infraprovider/docker_provider.go +++ b/infraprovider/docker_provider.go @@ -57,7 +57,7 @@ func (d DockerProvider) Provision( gitspaceConfigIdentifier string, _ string, _ int, - requiredGitspacePorts []int, + requiredGitspacePorts []types.GitspacePort, inputParameters []types.InfraProviderParameter, ) error { dockerClient, err := d.dockerClientFactory.NewDockerClient(ctx, types.Infrastructure{ @@ -99,7 +99,7 @@ func (d DockerProvider) Provision( ForwardedPort: 0, } - portMappings[requiredPort] = portMapping + portMappings[requiredPort.Port] = portMapping } infrastructure.GitspacePortMappings = portMappings @@ -125,7 +125,7 @@ func (d DockerProvider) Find( gitspaceConfigIdentifier string, _ string, _ int, - _ []int, + _ []types.GitspacePort, inputParameters []types.InfraProviderParameter, ) (*types.Infrastructure, error) { dockerClient, err := d.dockerClientFactory.NewDockerClient(ctx, types.Infrastructure{ diff --git a/infraprovider/infra_provider.go b/infraprovider/infra_provider.go index 27e9f2713..93c287489 100644 --- a/infraprovider/infra_provider.go +++ b/infraprovider/infra_provider.go @@ -30,9 +30,10 @@ type InfraProvider interface { gitspaceConfigIdentifier string, gitspaceInstanceIdentifier string, agentPort int, - requiredGitspacePorts []int, + requiredGitspacePorts []types.GitspacePort, inputParameters []types.InfraProviderParameter, ) error + // Find finds infrastructure provisioned against a gitspace. Find( ctx context.Context, @@ -41,19 +42,25 @@ type InfraProvider interface { gitspaceConfigIdentifier string, gitspaceInstanceIdentifier string, agentPort int, - requiredGitspacePorts []int, + requiredGitspacePorts []types.GitspacePort, inputParameters []types.InfraProviderParameter, ) (*types.Infrastructure, error) + // Stop frees up the resources allocated against a gitspace, which can be freed. Stop(ctx context.Context, infra types.Infrastructure) error + // Deprovision removes all infrastructure provisioned against the gitspace. Deprovision(ctx context.Context, infra types.Infrastructure) error + // AvailableParams provides a schema to define the infrastructure. AvailableParams() []types.InfraProviderParameterSchema + // ValidateParams validates the supplied params before defining the infrastructure resource . ValidateParams(inputParameters []types.InfraProviderParameter) error + // TemplateParams provides a list of params which are of type template. TemplateParams() []types.InfraProviderParameterSchema + // ProvisioningType specifies whether the provider will provision new infra resources or it will reuse existing. ProvisioningType() enum.InfraProvisioningType } diff --git a/types/enum/communication_protocol.go b/types/enum/communication_protocol.go new file mode 100644 index 000000000..5a01d9169 --- /dev/null +++ b/types/enum/communication_protocol.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 CommunicationProtocol string + +func (CommunicationProtocol) Enum() []interface{} { return toInterfaceSlice(communicationProtocols) } + +var communicationProtocols = []CommunicationProtocol{ + CommunicationProtocolHTTP, CommunicationProtocolSSH, +} + +const ( + CommunicationProtocolHTTP CommunicationProtocol = "http" + CommunicationProtocolSSH CommunicationProtocol = "ssh" +) diff --git a/types/gitspace_port.go b/types/gitspace_port.go new file mode 100644 index 000000000..092356cc0 --- /dev/null +++ b/types/gitspace_port.go @@ -0,0 +1,22 @@ +// 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 GitspacePort struct { + Port int `json:"port"` + Protocol enum.CommunicationProtocol `json:"protocol"` +}