Skip to content
This repository was archived by the owner on Aug 21, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
05399ce
feat: remove the check for existing apps
zjrgov Mar 25, 2025
9b79437
refactor: ServicePush -> Push until reason to diff, clean up Prepare
zjrgov Mar 26, 2025
b1197df
chore: wip, commiting to save over weekend
zjrgov Mar 28, 2025
f91235f
feat: add ssh_proxy script
zjrgov Apr 3, 2025
50c9a95
fix: missed ServicePush -> Push renames, add integration flag back
zjrgov Apr 4, 2025
5feb406
feat: load egress config into JobConfig
zjrgov Apr 4, 2025
5b5e5dd
refactor: move the go module to the root directory
zjrgov Jun 16, 2025
1cd83f4
chore: add a local lazy config file to set test args
zjrgov Jun 18, 2025
8ac16a1
tests: use verbose flag for both makefile test options
zjrgov Jun 18, 2025
1456be4
fix: needed to point build at the folder w/ main.go
zjrgov Jun 18, 2025
98b9ed3
tests: automate go driver integration test setup/teardown
zjrgov Jun 18, 2025
c250b16
chore(cfd): update default cf api to fr-stage
zjrgov Jun 18, 2025
fe027bb
tests(cfd): extract integration setup and improve scanner iteration
zjrgov Jun 18, 2025
813d267
feat(cfd): WIP of calling SSH w/ milestone of SSH actually working…
zjrgov Jun 18, 2025
8cb0d1a
refactor(cfd): integration setup/teardown easier to use
zjrgov Jun 23, 2025
ed745ae
fix(cfd): change AppGet integration to use STARTED state for consistency
zjrgov Jun 23, 2025
0e54650
fix(cfd): prepare run cmd needed nil passed to newStage
zjrgov Jun 23, 2025
7eae1ec
feat(cfd) RunSSH to use proxy config when available
zjrgov Jun 23, 2025
a8a9ae3
feat(cfd) add route mapping functionality & integration test
zjrgov Jun 23, 2025
6878ae2
chore(cfd) add function stubs for unimplemented prepare steps
zjrgov Jun 23, 2025
17af898
chore: removing unused ssh_proxy script
zjrgov Jun 27, 2025
3331f33
fix(cfd): teardown not using cf_api_prod var for -p
zjrgov Jun 27, 2025
6b8954f
chore(cfd): more obviously fake (and consistent) egress creds in test
zjrgov Jul 10, 2025
c6ddfe8
style(cfd): staticcheck wants uppercase
zjrgov Jul 11, 2025
ccdacde
chore(cfd): add a sample vcap_application json
zjrgov Jul 11, 2025
71db282
feat(cfd): pull cf api url out of vcap_application
zjrgov Jul 11, 2025
cc91626
chore(cfd): add to-do RE #136
zjrgov Jul 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions .github/workflows/cf-driver-go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,6 @@ name: "CF Driver: Go Build & Test"

on: [pull_request]

defaults:
run:
working-directory: runner-manager/cfd

jobs:
build:
runs-on: ubuntu-latest
Expand All @@ -17,12 +13,9 @@ jobs:

- name: Set up Go
uses: actions/setup-go@v5
with:
go-version-file: runner-manager/cfd/go.mod
cache-dependency-path: runner-manager/cfd/go.sum

- name: Install dependencies
run: go get .
run: go get ./...

- name: Check formatting
run: test -z "$(gofmt -l .)"
Expand Down
21 changes: 21 additions & 0 deletions .lazy.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
return {
{
"nvim-neotest/neotest",
config = function()
---@diagnostic disable-next-line: missing-fields
require("neotest").setup({
adapters = {
require("neotest-golang")({
go_test_args = { "-v", "-race", "-count=1", "-tags=integration" },
go_list_args = { "-tags=integration" },
dap_go_opts = {
delve = {
build_flags = { "-tags=integration" },
},
},
}),
},
})
end,
},
}
6 changes: 3 additions & 3 deletions runner-manager/cfd/Makefile → Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ vet: fmt
go vet ./...

test: vet
go test ./...
go test -v ./...

integration: vet
go test -count=1 --tags=integration ./...
go test -v -count=1 --tags=integration ./...

build: vet
go build
go build ./runner-manager/cfd
2 changes: 1 addition & 1 deletion runner-manager/cfd/go.mod → go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module github.com/GSA-TTS/gitlab-runner-cloudgov/runner/cfd
module github.com/GSA-TTS/gitlab-runner-cloudgov

go 1.23.5

Expand Down
2 changes: 2 additions & 0 deletions runner-manager/cfd/go.sum → go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,7 @@ golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbht
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
11 changes: 0 additions & 11 deletions runner-manager/cfd/.vscode/launch.json

This file was deleted.

14 changes: 8 additions & 6 deletions runner-manager/cfd/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ make test

### Integration tests

We only have one integration test right now, and to get it running you'll need to do a bit of local setup.

1. You will need to first get a username & password for some space on cloud.gov that has at least one app.
1. Then you can add those credentials to `./cg/testdata/.cg_creds` in the style of the `.cg_creds.sample` file there.
1. Run the test with `make integration`, which should give you an error and, in its output, show you what the resulting JSON looks like.
1. Copy that JSON result over to the last line of your `.cg_creds` file and run `make integration` again, this time it should succeed.
Integration tests take a little effort get working.

1. Set your `cf target` to `sandbox-gsa`.
2. Run `./sh/integration_setup.sh`.
a. This will output credentials and `cf target` info to the `testdata` directories for `./cloudgov` and `./cmd/drive`.
b. It will also create a sample app in your sandbox account to be used for testing.
3. Run integration tests with `make integration`
4. Whenever you're ready, you can clean up the credentials & app made during setup with `./sh/integration_teardown.sh`.

## Builds

Expand Down
34 changes: 33 additions & 1 deletion runner-manager/cfd/cloudgov/cf_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func castApp(app *resource.App) *App {
if app == nil || app.GUID == "" {
return nil
}
return &(App{Name: app.Name, GUID: app.GUID, State: app.State})
return &(App{Name: app.Name, GUID: app.GUID, State: app.State, SpaceGUID: app.Relationships.Space.Data.GUID})
}

func castApps(apps []*resource.App) []*App {
Expand Down Expand Up @@ -104,3 +104,35 @@ func (cf *CFClientAPI) appsList() ([]*App, error) {
}
return castApps(apps), nil
}

func (cf *CFClientAPI) sshCode() (string, error) {
ctx := context.Background()
return cf.conn().SSHCode(ctx)
}

func (cf *CFClientAPI) mapRoute(
ctx context.Context,
app *App,
domain string, space string, host string, path string, port int,
) error {
opts := resource.NewRouteCreateWithHost(domain, space, host, path, port)

route, err := cf.conn().Routes.Create(ctx, opts)
if err != nil {
return err
}

_, err = cf.conn().Routes.InsertDestinations(
ctx,
route.GUID,
[]*resource.RouteDestinationInsertOrReplace{{
App: resource.RouteDestinationApp{GUID: &app.GUID},
}},
)
return err
}

// addNetworkPolicy implements ClientAPI.
func (cf *CFClientAPI) addNetworkPolicy(app *App, dest string, space string, port string) error {
panic("unimplemented")
}
65 changes: 25 additions & 40 deletions runner-manager/cfd/cloudgov/cloudgov.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,18 @@
package cloudgov

import (
"errors"
"fmt"
import "context"

"github.com/cloudfoundry/go-cfclient/v3/resource"
)

// Stuff we'll need to implement, for ref
//
// mapRoute()
//
// addNetworkPolicy()
// removeNetworkPolicy()
type ClientAPI interface {
connect(url string, creds *Creds) error

appGet(id string) (*App, error)
appPush(m *AppManifest) (*App, error)
appDelete(id string) error
appsList() (apps []*App, err error)

sshCode() (string, error)
mapRoute(ctx context.Context, app *App, domain string, space string, host string, path string, port int) error
addNetworkPolicy(app *App, dest string, space string, port string) error
}

type CredsGetter interface {
Expand All @@ -46,8 +39,10 @@ func (e CloudGovClientError) Error() string {
return e.msg
}

// TODO: we should pull this out of VCAP_APPLICATION
const apiRootURLDefault = "https://api.fr.cloud.gov"
const (
apiRootURLDefault = "https://api.fr-stage.cloud.gov"
Comment thread
zjrgov marked this conversation as resolved.
internalDomainGUID = "8a5d6a8c-cfc1-4fc4-afc9-aa563ff9df5e"
)

func New(i ClientAPI, o *Opts) (*Client, error) {
if o == nil {
Expand Down Expand Up @@ -83,9 +78,10 @@ func (c *Client) Connect() (*Client, error) {
}

type App struct {
Name string
GUID string
State string
Name string
GUID string
State string
SpaceGUID string
}

func (c *Client) AppGet(id string) (*App, error) {
Expand All @@ -102,34 +98,15 @@ func (c *Client) AppsList() ([]*App, error) {

// TODO: this abstraction might belong in /cmd,
// unless it can be further generalized to all pushes
func (c *Client) ServicePush(manifest *AppManifest) (*App, error) {
func (c *Client) Push(manifest *AppManifest) (*App, error) {
containerID := manifest.Name

if containerID == "" {
return nil, CloudGovClientError{"ServicePush: AppManifest.Name must be defined"}
return nil, CloudGovClientError{"Push: AppManifest.Name must be defined"}
}

if manifest.OrgName == "" || manifest.SpaceName == "" {
return nil, CloudGovClientError{"ServicePush: AppManifest must have Org and Space names"}
}

// check for an old instance of the service, delete if found
Comment thread
zjrgov marked this conversation as resolved.
app, err := c.AppGet(containerID)
if err != nil {
var cferr resource.CloudFoundryError
if errors.As(err, &cferr) {
err = nil
if cferr.Code != 10010 {
return nil, fmt.Errorf("unexpected cferr checking for existing app: %w", cferr)
}
} else {
return nil, fmt.Errorf("error checking for existing service (%v): %w", containerID, err)
}
}
if app != nil {
if err := c.AppDelete(containerID); err != nil {
return nil, fmt.Errorf("error deleting existing service (%v): %w", containerID, err)
}
return nil, CloudGovClientError{"Push: AppManifest must have Org and Space names"}
}

return c.appPush(manifest)
Expand All @@ -144,7 +121,7 @@ func (c *Client) ServicesPush(manifests []*AppManifest) ([]*App, error) {
apps := make([]*App, len(manifests))

for i, s := range manifests {
app, err := c.ServicePush(s)
app, err := c.Push(s)
if err != nil {
return nil, err
}
Expand All @@ -153,3 +130,11 @@ func (c *Client) ServicesPush(manifests []*AppManifest) ([]*App, error) {

return apps, nil
}

func (c *Client) SSHCode() (string, error) {
return c.sshCode()
}

func (c *Client) MapServiceRoute(app *App) error {
return c.mapRoute(context.Background(), app, internalDomainGUID, app.SpaceGUID, app.Name, "", 0)
}
Loading