diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 79f1da77..3369dd6a 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -2,10 +2,7 @@ name: Integration Tests on: push: branches: - - main - pull_request: - branches: - - main + - test-e2e-wip jobs: garm-cli-test: @@ -93,6 +90,15 @@ jobs: public = true protocol = "simplestreams" skip_verify = false + [[github]] + name = "mihaelabalutoiu" + description = "github token of user ionutbalutoiu" + oauth2_token = "${{ secrets.AUTH2_TOKEN_SECRETS }}" + + [[github]] + name = "mihaelabalutoiu" + description = "github token of user mihaelabalutoiu-clone" + oauth2_token = "${{ secrets.AUTH2_TOKEN_SECRETS }}" EOF sudo mv config.toml /etc/garm/config.toml sudo chown -R garm:garm /etc/garm /var/log/garm @@ -120,53 +126,26 @@ jobs: wait_open_port 127.0.0.1 9997 - - name: Test GARM API with garm-cli tool + - name: Test GARM API shell: bash run: | set -e set -x set -o pipefail - GARM_URL="http://127.0.0.1:9997" - ADMIN_USERNAME='admin' - ADMIN_PASWORD='Ma*jirksiCr9esrT8DGQPrfx*XKnBVZo' - - garm-cli init --debug \ - --name="local_garm" \ - --url $GARM_URL \ - --email root@localhost \ - --username $ADMIN_USERNAME \ - --password $ADMIN_PASWORD - - garm-cli profile add --debug \ - --name="local_garm_2" \ - --url $GARM_URL \ - --username $ADMIN_USERNAME \ - --password $ADMIN_PASWORD - - garm-cli profile login --debug \ - --username $ADMIN_USERNAME \ - --password $ADMIN_PASWORD - - garm-cli metrics-token --debug create - - garm-cli provider --debug list - - garm-cli profile --debug list - - garm-cli runner --debug list --all - - garm-cli credentials --debug list - - garm-cli job --debug list - - garm-cli org --debug list - - garm-cli repo --debug list + export GARM_URL="http://127.0.0.1:9997" + export GARM_USERNAME='admin' + export GARM_PASWORD='Ma*jirksiCr9esrT8DGQPrfx*XKnBVZo' + export GARM_FULLNAME='test-fullname' + export GARM_EMAIL='test@example.com' + export GARM_NAME='local_garm' + export CREDENTIALS_NAME='mihaelabalutoiu' - garm-cli enterprise --debug list + export REPO_WEBHOOK_SECRET=${{ secrets.REPO_WEBHOOK_SECRET }} + export ORG_WEBHOOK_SECRET=${{ secrets.ORG_WEBHOOK_SECRET }} - garm-cli pool --debug list --all + go run integration/e2e.go + - name: Show GARM logs run: | diff --git a/integration/e2e.go b/integration/e2e.go new file mode 100644 index 00000000..f457ff6b --- /dev/null +++ b/integration/e2e.go @@ -0,0 +1,1339 @@ +package main + +import ( + "encoding/json" + "fmt" + "log" + "net/url" + "os" + "time" + + commonParams "github.com/cloudbase/garm-provider-common/params" + client "github.com/cloudbase/garm/client" + clientCredentials "github.com/cloudbase/garm/client/credentials" + clientEnterprises "github.com/cloudbase/garm/client/enterprises" + clientFirstRun "github.com/cloudbase/garm/client/first_run" + clientInstances "github.com/cloudbase/garm/client/instances" + clientJobs "github.com/cloudbase/garm/client/jobs" + clientLogin "github.com/cloudbase/garm/client/login" + clientMetricsToken "github.com/cloudbase/garm/client/metrics_token" + clientOrganizations "github.com/cloudbase/garm/client/organizations" + clientPools "github.com/cloudbase/garm/client/pools" + clientProviders "github.com/cloudbase/garm/client/providers" + clientRepositories "github.com/cloudbase/garm/client/repositories" + "github.com/cloudbase/garm/cmd/garm-cli/config" + "github.com/cloudbase/garm/params" + "github.com/go-openapi/runtime" + openapiRuntimeClient "github.com/go-openapi/runtime/client" +) + +const ( + orgName = "test-garm-org" + repoName = "test-garm-repo" + enterpriseName = "cloudbase-solutions" +) + +var ( + cli *client.GarmAPI + cfg config.Config + authToken runtime.ClientAuthInfoWriter + + credentialsName = os.Getenv("CREDENTIALS_NAME") + + repoID string + repoPoolID string + repoInstanceName string + repoWebhookSecret = os.Getenv("REPO_WEBHOOK_SECRET") + + orgID string + orgPoolID string + orgInstanceName string + orgWebhookSecret = os.Getenv("ORG_WEBHOOK_SECRET") + + enterpriseID string + enterprisePoolID string + enterpriseInstanceName string + enterpriseWebhookSecret = os.Getenv("ENTERPRISE_WEBHOOK_SECRET") + + username = os.Getenv("GARM_USERNAME") + password = os.Getenv("GARM_PASSWORD") + fullName = os.Getenv("GARM_FULLNAME") + email = os.Getenv("GARM_EMAIL") + name = os.Getenv("GARM_NAME") + baseURL = os.Getenv("GARM_BASE_URL") + + poolID string +) + +// //////////////// // +// helper functions // +// /////////////////// +func handleError(err error) { + if err != nil { + log.Fatalf("error encountered: %v", err) + } +} + +func printResponse(resp interface{}) { + b, err := json.MarshalIndent(resp, "", " ") + handleError(err) + log.Println(string(b)) +} + +// /////////// +// Garm Init / +// /////////// +func firstRun(apiCli *client.GarmAPI, newUser params.NewUserParams) (params.User, error) { + firstRunResponse, err := apiCli.FirstRun.FirstRun( + clientFirstRun.NewFirstRunParams().WithBody(newUser), + authToken) + if err != nil { + return params.User{}, err + } + return firstRunResponse.Payload, nil +} + +func login(apiCli *client.GarmAPI, params params.PasswordLoginParams) (string, error) { + loginResponse, err := apiCli.Login.Login( + clientLogin.NewLoginParams().WithBody(params), + authToken) + if err != nil { + return "", err + } + return loginResponse.Payload.Token, nil +} + +// //////////////////////////// +// Credentials and Providers // +// //////////////////////////// +func listCredentials(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter) (params.Credentials, error) { + listCredentialsResponse, err := apiCli.Credentials.ListCredentials( + clientCredentials.NewListCredentialsParams(), + apiAuthToken) + if err != nil { + return nil, err + } + return listCredentialsResponse.Payload, nil +} + +func listProviders(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter) (params.Providers, error) { + listProvidersResponse, err := apiCli.Providers.ListProviders( + clientProviders.NewListProvidersParams(), + apiAuthToken) + if err != nil { + return nil, err + } + return listProvidersResponse.Payload, nil +} + +// //////// +// Jobs // +// //////// +func listJobs(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter) (params.Jobs, error) { + listJobsResponse, err := apiCli.Jobs.ListJobs( + clientJobs.NewListJobsParams(), + apiAuthToken) + if err != nil { + return nil, err + } + return listJobsResponse.Payload, nil +} + +// ////////////////// +// / Metrics Token // +// ////////////////// +func getMetricsToken(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter) (string, error) { + getMetricsTokenResponse, err := apiCli.MetricsToken.GetMetricsToken( + clientMetricsToken.NewGetMetricsTokenParams(), + apiAuthToken) + if err != nil { + return "", err + } + return getMetricsTokenResponse.Payload.Token, nil +} + +// /////////////// +// Repositories // +// /////////////// +func createRepo(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoParams params.CreateRepoParams) (*params.Repository, error) { + createRepoResponse, err := apiCli.Repositories.CreateRepo( + clientRepositories.NewCreateRepoParams().WithBody(repoParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &createRepoResponse.Payload, nil +} + +func listRepos(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter) (params.Repositories, error) { + listReposResponse, err := apiCli.Repositories.ListRepos( + clientRepositories.NewListReposParams(), + apiAuthToken) + if err != nil { + return nil, err + } + return listReposResponse.Payload, nil +} + +func updateRepo(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoID string, repoParams params.UpdateEntityParams) (*params.Repository, error) { + updateRepoResponse, err := apiCli.Repositories.UpdateRepo( + clientRepositories.NewUpdateRepoParams().WithRepoID(repoID).WithBody(repoParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &updateRepoResponse.Payload, nil +} + +func getRepo(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoID string) (*params.Repository, error) { + getRepoResponse, err := apiCli.Repositories.GetRepo( + clientRepositories.NewGetRepoParams().WithRepoID(repoID), + apiAuthToken) + if err != nil { + return nil, err + } + return &getRepoResponse.Payload, nil +} + +func createRepoPool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoID string, poolParams params.CreatePoolParams) (*params.Pool, error) { + createRepoPoolResponse, err := apiCli.Repositories.CreateRepoPool( + clientRepositories.NewCreateRepoPoolParams().WithRepoID(repoID).WithBody(poolParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &createRepoPoolResponse.Payload, nil +} + +func listRepoPools(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoID string) (params.Pools, error) { + listRepoPoolsResponse, err := apiCli.Repositories.ListRepoPools( + clientRepositories.NewListRepoPoolsParams().WithRepoID(repoID), + apiAuthToken) + if err != nil { + return nil, err + } + return listRepoPoolsResponse.Payload, nil +} + +func getRepoPool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoID, poolID string) (*params.Pool, error) { + getRepoPoolResponse, err := apiCli.Repositories.GetRepoPool( + clientRepositories.NewGetRepoPoolParams().WithRepoID(repoID).WithPoolID(poolID), + apiAuthToken) + if err != nil { + return nil, err + } + return &getRepoPoolResponse.Payload, nil +} + +func updateRepoPool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoID, poolID string, poolParams params.UpdatePoolParams) (*params.Pool, error) { + updateRepoPoolResponse, err := apiCli.Repositories.UpdateRepoPool( + clientRepositories.NewUpdateRepoPoolParams().WithRepoID(repoID).WithPoolID(poolID).WithBody(poolParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &updateRepoPoolResponse.Payload, nil +} + +func listRepoInstances(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoID string) (params.Instances, error) { + listRepoInstancesResponse, err := apiCli.Repositories.ListRepoInstances( + clientRepositories.NewListRepoInstancesParams().WithRepoID(repoID), + apiAuthToken) + if err != nil { + return nil, err + } + return listRepoInstancesResponse.Payload, nil +} + +func deleteRepo(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoID string) error { + return apiCli.Repositories.DeleteRepo( + clientRepositories.NewDeleteRepoParams().WithRepoID(repoID), + apiAuthToken) +} + +func deleteRepoPool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, repoID, poolID string) error { + return apiCli.Repositories.DeleteRepoPool( + clientRepositories.NewDeleteRepoPoolParams().WithRepoID(repoID).WithPoolID(poolID), + apiAuthToken) +} + +// //////////////// +// Organizations // +// //////////////// +func createOrg(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgParams params.CreateOrgParams) (*params.Organization, error) { + createOrgResponse, err := apiCli.Organizations.CreateOrg( + clientOrganizations.NewCreateOrgParams().WithBody(orgParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &createOrgResponse.Payload, nil +} + +func listOrgs(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter) (params.Organizations, error) { + listOrgsResponse, err := apiCli.Organizations.ListOrgs( + clientOrganizations.NewListOrgsParams(), + apiAuthToken) + if err != nil { + return nil, err + } + return listOrgsResponse.Payload, nil +} + +func updateOrg(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgID string, orgParams params.UpdateEntityParams) (*params.Organization, error) { + updateOrgResponse, err := apiCli.Organizations.UpdateOrg( + clientOrganizations.NewUpdateOrgParams().WithOrgID(orgID).WithBody(orgParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &updateOrgResponse.Payload, nil +} + +func getOrg(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgID string) (*params.Organization, error) { + getOrgResponse, err := apiCli.Organizations.GetOrg( + clientOrganizations.NewGetOrgParams().WithOrgID(orgID), + apiAuthToken) + if err != nil { + return nil, err + } + return &getOrgResponse.Payload, nil +} + +func createOrgPool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgID string, poolParams params.CreatePoolParams) (*params.Pool, error) { + createOrgPoolResponse, err := apiCli.Organizations.CreateOrgPool( + clientOrganizations.NewCreateOrgPoolParams().WithOrgID(orgID).WithBody(poolParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &createOrgPoolResponse.Payload, nil +} + +func listOrgPools(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgID string) (params.Pools, error) { + listOrgPoolsResponse, err := apiCli.Organizations.ListOrgPools( + clientOrganizations.NewListOrgPoolsParams().WithOrgID(orgID), + apiAuthToken) + if err != nil { + return nil, err + } + return listOrgPoolsResponse.Payload, nil +} + +func getOrgPool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgID, poolID string) (*params.Pool, error) { + getOrgPoolResponse, err := apiCli.Organizations.GetOrgPool( + clientOrganizations.NewGetOrgPoolParams().WithOrgID(orgID).WithPoolID(poolID), + apiAuthToken) + if err != nil { + return nil, err + } + return &getOrgPoolResponse.Payload, nil +} + +func updateOrgPool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgID, poolID string, poolParams params.UpdatePoolParams) (*params.Pool, error) { + updateOrgPoolResponse, err := apiCli.Organizations.UpdateOrgPool( + clientOrganizations.NewUpdateOrgPoolParams().WithOrgID(orgID).WithPoolID(poolID).WithBody(poolParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &updateOrgPoolResponse.Payload, nil +} + +func listOrgInstances(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgID string) (params.Instances, error) { + listOrgInstancesResponse, err := apiCli.Organizations.ListOrgInstances( + clientOrganizations.NewListOrgInstancesParams().WithOrgID(orgID), + apiAuthToken) + if err != nil { + return nil, err + } + return listOrgInstancesResponse.Payload, nil +} + +func deleteOrg(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgID string) error { + return apiCli.Organizations.DeleteOrg( + clientOrganizations.NewDeleteOrgParams().WithOrgID(orgID), + apiAuthToken) +} + +func deleteOrgPool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, orgID, poolID string) error { + return apiCli.Organizations.DeleteOrgPool( + clientOrganizations.NewDeleteOrgPoolParams().WithOrgID(orgID).WithPoolID(poolID), + apiAuthToken) +} + +// //////////// +// Instances // +// //////////// +func listInstances(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter) (params.Instances, error) { + listInstancesResponse, err := apiCli.Instances.ListInstances( + clientInstances.NewListInstancesParams(), + apiAuthToken) + if err != nil { + return nil, err + } + return listInstancesResponse.Payload, nil +} + +func getInstance(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, instanceID string) (*params.Instance, error) { + getInstancesResponse, err := apiCli.Instances.GetInstance( + clientInstances.NewGetInstanceParams().WithInstanceName(instanceID), + apiAuthToken) + if err != nil { + return nil, err + } + return &getInstancesResponse.Payload, nil +} + +func deleteInstance(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, instanceID string) error { + return apiCli.Instances.DeleteInstance( + clientInstances.NewDeleteInstanceParams().WithInstanceName(instanceID), + apiAuthToken) +} + +// //////// +// Pools // +// //////// +func listPools(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter) (params.Pools, error) { + listPoolsResponse, err := apiCli.Pools.ListPools( + clientPools.NewListPoolsParams(), + apiAuthToken) + if err != nil { + return nil, err + } + return listPoolsResponse.Payload, nil +} + +func getPool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, poolID string) (*params.Pool, error) { + getPoolResponse, err := apiCli.Pools.GetPool( + clientPools.NewGetPoolParams().WithPoolID(poolID), + apiAuthToken) + if err != nil { + return nil, err + } + return &getPoolResponse.Payload, nil +} + +func updatePool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, poolID string, poolParams params.UpdatePoolParams) (*params.Pool, error) { + updatePoolResponse, err := apiCli.Pools.UpdatePool( + clientPools.NewUpdatePoolParams().WithPoolID(poolID).WithBody(poolParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &updatePoolResponse.Payload, nil +} + +func listPoolInstances(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, poolID string) (params.Instances, error) { + listPoolInstancesResponse, err := apiCli.Instances.ListPoolInstances( + clientInstances.NewListPoolInstancesParams().WithPoolID(poolID), + apiAuthToken) + if err != nil { + return nil, err + } + return listPoolInstancesResponse.Payload, nil +} + +func deletePool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, poolID string) error { + return apiCli.Pools.DeletePool( + clientPools.NewDeletePoolParams().WithPoolID(poolID), + apiAuthToken) +} + +// /////////////// +// Enterprises // +// /////////////// +func createEnterprise(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, enterpriseParams params.CreateEnterpriseParams) (*params.Enterprise, error) { + createEnterpriseResponse, err := apiCli.Enterprises.CreateEnterprise( + clientEnterprises.NewCreateEnterpriseParams().WithBody(enterpriseParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &createEnterpriseResponse.Payload, nil +} + +func listEnterprises(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter) (params.Enterprises, error) { + listEnterprisesResponse, err := apiCli.Enterprises.ListEnterprises( + clientEnterprises.NewListEnterprisesParams(), + apiAuthToken) + if err != nil { + return nil, err + } + return listEnterprisesResponse.Payload, nil +} + +func updateEnterprise(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, enterpriseID string, enterpriseParams params.UpdateEntityParams) (*params.Enterprise, error) { + updateEnterpriseResponse, err := apiCli.Enterprises.UpdateEnterprise( + clientEnterprises.NewUpdateEnterpriseParams().WithEnterpriseID(enterpriseID).WithBody(enterpriseParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &updateEnterpriseResponse.Payload, nil +} + +func getEnterprise(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, enterpriseID string) (*params.Enterprise, error) { + getEnterpriseResponse, err := apiCli.Enterprises.GetEnterprise( + clientEnterprises.NewGetEnterpriseParams().WithEnterpriseID(enterpriseID), + apiAuthToken) + if err != nil { + return nil, err + } + return &getEnterpriseResponse.Payload, nil +} + +func createEnterprisePool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, enterpriseID string, poolParams params.CreatePoolParams) (*params.Pool, error) { + createEnterprisePoolResponse, err := apiCli.Enterprises.CreateEnterprisePool( + clientEnterprises.NewCreateEnterprisePoolParams().WithEnterpriseID(enterpriseID).WithBody(poolParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &createEnterprisePoolResponse.Payload, nil +} + +func listEnterprisesPools(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, enterpriseID string) (params.Pools, error) { + listEnterprisesPoolsResponse, err := apiCli.Enterprises.ListEnterprisePools( + clientEnterprises.NewListEnterprisePoolsParams().WithEnterpriseID(enterpriseID), + apiAuthToken) + if err != nil { + return nil, err + } + return listEnterprisesPoolsResponse.Payload, nil +} + +func getEnterprisePool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, enterpriseID, poolID string) (*params.Pool, error) { + getEnterprisePoolResponse, err := apiCli.Enterprises.GetEnterprisePool( + clientEnterprises.NewGetEnterprisePoolParams().WithEnterpriseID(enterpriseID).WithPoolID(poolID), + apiAuthToken) + if err != nil { + return nil, err + } + return &getEnterprisePoolResponse.Payload, nil +} + +func updateEnterprisePool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, enterpriseID, poolID string, poolParams params.UpdatePoolParams) (*params.Pool, error) { + updateEnterprisePoolResponse, err := apiCli.Enterprises.UpdateEnterprisePool( + clientEnterprises.NewUpdateEnterprisePoolParams().WithEnterpriseID(enterpriseID).WithPoolID(poolID).WithBody(poolParams), + apiAuthToken) + if err != nil { + return nil, err + } + return &updateEnterprisePoolResponse.Payload, nil +} + +func listEnterpriseInstances(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, enterpriseID string) (params.Instances, error) { + listEnterpriseInstancesResponse, err := apiCli.Enterprises.ListEnterpriseInstances( + clientEnterprises.NewListEnterpriseInstancesParams().WithEnterpriseID(enterpriseID), + apiAuthToken) + if err != nil { + return nil, err + } + return listEnterpriseInstancesResponse.Payload, nil +} + +func deleteEnterprise(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, enterpriseID string) error { + return apiCli.Enterprises.DeleteEnterprise( + clientEnterprises.NewDeleteEnterpriseParams().WithEnterpriseID(enterpriseID), + apiAuthToken) +} + +func deleteEnterprisePool(apiCli *client.GarmAPI, apiAuthToken runtime.ClientAuthInfoWriter, enterpriseID, poolID string) error { + return apiCli.Enterprises.DeleteEnterprisePool( + clientEnterprises.NewDeleteEnterprisePoolParams().WithEnterpriseID(enterpriseID).WithPoolID(poolID), + apiAuthToken) +} + +// ///////////////// +// Main functions // +// ///////////////// +// +// ///////////// +// Garm Init // +// ///////////// +func Login() { + log.Println(">>> Login") + loginParams := params.PasswordLoginParams{ + Username: username, + Password: password, + } + token, err := login(cli, loginParams) + handleError(err) + printResponse(token) + authToken = openapiRuntimeClient.BearerToken(token) + cfg.Managers = []config.Manager{ + { + Name: name, + BaseURL: baseURL, + Token: token, + }, + } + cfg.ActiveManager = name + err = cfg.SaveConfig() + handleError(err) +} + +func FirstRun() { + existingCfg, err := config.LoadConfig() + handleError(err) + if existingCfg != nil { + if existingCfg.HasManager(name) { + log.Println(">>> Already initialized") + return + } + } + + log.Println(">>> First run") + newUser := params.NewUserParams{ + Username: username, + Password: password, + FullName: fullName, + Email: email, + } + user, err := firstRun(cli, newUser) + handleError(err) + printResponse(user) +} + +// //////////////////////////// +// Credentials and Providers // +// //////////////////////////// +func ListCredentials() { + log.Println(">>> List credentials") + credentials, err := listCredentials(cli, authToken) + handleError(err) + printResponse(credentials) +} + +func ListProviders() { + log.Println(">>> List providers") + providers, err := listProviders(cli, authToken) + handleError(err) + printResponse(providers) +} + +// //////// +// Jobs // +// //////// +func ListJobs() { + log.Println(">>> List jobs") + jobs, err := listJobs(cli, authToken) + handleError(err) + printResponse(jobs) +} + +// ////////////////// +// / Metrics Token // +// ////////////////// +func GetMetricsToken() { + log.Println(">>> Get metrics token") + token, err := getMetricsToken(cli, authToken) + handleError(err) + printResponse(token) +} + +// /////////////// +// Repositories // +// /////////////// +func CreateRepo() { + repos, err := listRepos(cli, authToken) + handleError(err) + if len(repos) > 0 { + log.Println(">>> Repo already exists, skipping create") + repoID = repos[0].ID + return + } + log.Println(">>> Create repo") + createParams := params.CreateRepoParams{ + Owner: orgName, + Name: repoName, + CredentialsName: credentialsName, + WebhookSecret: repoWebhookSecret, + } + repo, err := createRepo(cli, authToken, createParams) + handleError(err) + printResponse(repo) + repoID = repo.ID +} + +func ListRepos() { + log.Println(">>> List repos") + repos, err := listRepos(cli, authToken) + handleError(err) + printResponse(repos) +} + +func UpdateRepo() { + log.Println(">>> Update repo") + updateParams := params.UpdateEntityParams{ + CredentialsName: fmt.Sprintf("%s-clone", credentialsName), + } + repo, err := updateRepo(cli, authToken, repoID, updateParams) + handleError(err) + printResponse(repo) +} + +func GetRepo() { + log.Println(">>> Get repo") + repo, err := getRepo(cli, authToken, repoID) + handleError(err) + printResponse(repo) +} + +func CreateRepoPool() { + pools, err := listRepoPools(cli, authToken, repoID) + handleError(err) + if len(pools) > 0 { + log.Println(">>> Repo pool already exists, skipping create") + repoPoolID = pools[0].ID + return + } + log.Println(">>> Create repo pool") + poolParams := params.CreatePoolParams{ + MaxRunners: 2, + MinIdleRunners: 0, + Flavor: "garm", + Image: "ubuntu:22.04", + OSType: commonParams.Linux, + OSArch: commonParams.Amd64, + ProviderName: "lxd_local", + Tags: []string{"ubuntu", "simple-runner"}, + Enabled: true, + } + repo, err := createRepoPool(cli, authToken, repoID, poolParams) + handleError(err) + printResponse(repo) + repoPoolID = repo.ID +} + +func ListRepoPools() { + log.Println(">>> List repo pools") + pools, err := listRepoPools(cli, authToken, repoID) + handleError(err) + printResponse(pools) +} + +func GetRepoPool() { + log.Println(">>> Get repo pool") + pool, err := getRepoPool(cli, authToken, repoID, repoPoolID) + handleError(err) + printResponse(pool) +} + +func UpdateRepoPool() { + log.Println(">>> Update repo pool") + var maxRunners uint = 5 + var idleRunners uint = 1 + poolParams := params.UpdatePoolParams{ + MinIdleRunners: &idleRunners, + MaxRunners: &maxRunners, + } + pool, err := updateRepoPool(cli, authToken, repoID, repoPoolID, poolParams) + handleError(err) + printResponse(pool) +} + +func DisableRepoPool() { + enabled := false + _, err := updateRepoPool(cli, authToken, repoID, repoPoolID, params.UpdatePoolParams{Enabled: &enabled}) + handleError(err) + log.Printf("repo pool %s disabled", repoPoolID) +} + +func WaitRepoPoolNoInstances() { + for { + log.Println(">>> Wait until repo pool has no instances") + pool, err := getRepoPool(cli, authToken, repoID, repoPoolID) + handleError(err) + if len(pool.Instances) == 0 { + break + } + time.Sleep(5 * time.Second) + } +} + +func WaitRepoInstance() { + log.Println(">>> Wait until repo instance is in running state") + for { + instances, err := listRepoInstances(cli, authToken, repoID) + handleError(err) + if len(instances) > 0 { + instance := instances[0] + log.Printf("instance %s status: %s", instance.Name, instance.Status) + if instance.Status == commonParams.InstanceRunning && instance.RunnerStatus == params.RunnerIdle { + repoInstanceName = instance.Name + break + } + } + time.Sleep(5 * time.Second) + } +} + +func ListRepoInstances() { + log.Println(">>> List repo instances") + instances, err := listRepoInstances(cli, authToken, repoID) + handleError(err) + printResponse(instances) +} + +func DeleteRepo() { + log.Println(">>> Delete repo") + err := deleteRepo(cli, authToken, repoID) + handleError(err) + log.Printf("repo %s deleted", repoID) +} + +func DeleteRepoPool() { + log.Println(">>> Delete repo pool") + err := deleteRepoPool(cli, authToken, repoID, repoPoolID) + handleError(err) + log.Printf("repo pool %s deleted", repoPoolID) +} + +// //////////////// +// Organizations // +// //////////////// +func CreateOrg() { + orgs, err := listOrgs(cli, authToken) + handleError(err) + if len(orgs) > 0 { + log.Println(">>> Org already exists, skipping create") + orgID = orgs[0].ID + return + } + log.Println(">>> Create org") + orgParams := params.CreateOrgParams{ + Name: orgName, + CredentialsName: credentialsName, + WebhookSecret: orgWebhookSecret, + } + org, err := createOrg(cli, authToken, orgParams) + handleError(err) + printResponse(org) + orgID = org.ID +} + +func ListOrgs() { + log.Println(">>> List orgs") + orgs, err := listOrgs(cli, authToken) + handleError(err) + printResponse(orgs) +} + +func UpdateOrg() { + log.Println(">>> Update org") + updateParams := params.UpdateEntityParams{ + CredentialsName: fmt.Sprintf("%s-clone", credentialsName), + } + org, err := updateOrg(cli, authToken, orgID, updateParams) + handleError(err) + printResponse(org) +} + +func GetOrg() { + log.Println(">>> Get org") + org, err := getOrg(cli, authToken, orgID) + handleError(err) + printResponse(org) +} + +func CreateOrgPool() { + pools, err := listOrgPools(cli, authToken, orgID) + handleError(err) + if len(pools) > 0 { + log.Println(">>> Org pool already exists, skipping create") + orgPoolID = pools[0].ID + return + } + log.Println(">>> Create org pool") + poolParams := params.CreatePoolParams{ + MaxRunners: 2, + MinIdleRunners: 0, + Flavor: "garm", + Image: "ubuntu:22.04", + OSType: commonParams.Linux, + OSArch: commonParams.Amd64, + ProviderName: "lxd_local", + Tags: []string{"ubuntu", "simple-runner"}, + Enabled: true, + } + org, err := createOrgPool(cli, authToken, orgID, poolParams) + handleError(err) + printResponse(org) + orgPoolID = org.ID +} + +func ListOrgPools() { + log.Println(">>> List org pools") + pools, err := listOrgPools(cli, authToken, orgID) + handleError(err) + printResponse(pools) +} + +func GetOrgPool() { + log.Println(">>> Get org pool") + pool, err := getOrgPool(cli, authToken, orgID, orgPoolID) + handleError(err) + printResponse(pool) +} + +func UpdateOrgPool() { + log.Println(">>> Update org pool") + var maxRunners uint = 5 + var idleRunners uint = 1 + poolParams := params.UpdatePoolParams{ + MinIdleRunners: &idleRunners, + MaxRunners: &maxRunners, + } + pool, err := updateOrgPool(cli, authToken, orgID, orgPoolID, poolParams) + handleError(err) + printResponse(pool) +} + +func DisableOrgPool() { + enabled := false + _, err := updateOrgPool(cli, authToken, orgID, orgPoolID, params.UpdatePoolParams{Enabled: &enabled}) + handleError(err) + log.Printf("org pool %s disabled", orgPoolID) +} + +func WaitOrgPoolNoInstances() { + for { + log.Println(">>> Wait until org pool has no instances") + pool, err := getOrgPool(cli, authToken, orgID, orgPoolID) + handleError(err) + if len(pool.Instances) == 0 { + break + } + time.Sleep(5 * time.Second) + } +} + +func WaitOrgInstance() { + log.Println(">>> Wait until org instance is in running state") + for { + instances, err := listOrgInstances(cli, authToken, orgID) + handleError(err) + if len(instances) > 0 { + instance := instances[0] + log.Printf("instance %s status: %s", instance.Name, instance.Status) + if instance.Status == commonParams.InstanceRunning && instance.RunnerStatus == params.RunnerIdle { + orgInstanceName = instance.Name + break + } + } + time.Sleep(5 * time.Second) + } +} + +func ListOrgInstances() { + log.Println(">>> List org instances") + instances, err := listOrgInstances(cli, authToken, orgID) + handleError(err) + printResponse(instances) +} + +func DeleteOrg() { + log.Println(">>> Delete org") + err := deleteOrg(cli, authToken, orgID) + handleError(err) + log.Printf("org %s deleted", orgID) +} + +func DeleteOrgPool() { + log.Println(">>> Delete org pool") + err := deleteOrgPool(cli, authToken, orgID, orgPoolID) + handleError(err) + log.Printf("org pool %s deleted", orgPoolID) +} + +// //////////// +// Instances // +// //////////// +func ListInstances() { + log.Println(">>> List instances") + instances, err := listInstances(cli, authToken) + handleError(err) + printResponse(instances) +} + +func GetInstance() { + log.Println(">>> Get instance") + instance, err := getInstance(cli, authToken, orgInstanceName) + handleError(err) + printResponse(instance) +} + +func DeleteInstance(name string) { + err := deleteInstance(cli, authToken, name) + for { + log.Printf(">>> Wait until instance %s is deleted", name) + instances, err := listInstances(cli, authToken) + handleError(err) + for _, instance := range instances { + if instance.Name == name { + time.Sleep(5 * time.Second) + continue + } + } + break + } + handleError(err) + log.Printf("instance %s deleted", name) +} + +// //////// +// Pools // +// //////// +func CreatePool() { + pools, err := listPools(cli, authToken) + handleError(err) + for _, pool := range pools { + if pool.Image == "ubuntu:20.04" { + // this is the extra pool to be deleted, later, via [DELETE] pools dedicated API. + poolID = pool.ID + return + } + } + log.Println(">>> Create pool") + poolParams := params.CreatePoolParams{ + MaxRunners: 2, + MinIdleRunners: 0, + Flavor: "garm", + Image: "ubuntu:20.04", + OSType: commonParams.Linux, + OSArch: commonParams.Amd64, + ProviderName: "lxd_local", + Tags: []string{"ubuntu", "simple-runner"}, + Enabled: true, + } + pool, err := createRepoPool(cli, authToken, repoID, poolParams) + handleError(err) + printResponse(pool) + poolID = pool.ID +} + +func ListPools() { + log.Println(">>> List pools") + pools, err := listPools(cli, authToken) + handleError(err) + printResponse(pools) +} + +func UpdatePool() { + log.Println(">>> Update pool") + var maxRunners uint = 5 + var idleRunners uint = 0 + poolParams := params.UpdatePoolParams{ + MinIdleRunners: &idleRunners, + MaxRunners: &maxRunners, + } + pool, err := updatePool(cli, authToken, poolID, poolParams) + handleError(err) + printResponse(pool) +} + +func GetPool() { + log.Println(">>> Get pool") + pool, err := getPool(cli, authToken, poolID) + handleError(err) + printResponse(pool) +} + +func DeletePool() { + log.Println(">>> Delete pool") + err := deletePool(cli, authToken, poolID) + handleError(err) + log.Printf("pool %s deleted", poolID) +} + +func ListPoolInstances() { + log.Println(">>> List pool instances") + instances, err := listPoolInstances(cli, authToken, repoPoolID) + handleError(err) + printResponse(instances) +} + +// /////////////// +// Enterprises // +// /////////////// +func CreateEnterprise() { + enterprises, err := listEnterprises(cli, authToken) + handleError(err) + if len(enterprises) > 0 { + log.Println(">>> Enterprise already exists, skipping create") + enterpriseID = enterprises[0].ID + return + } + log.Println(">>> Create enterprise") + createParams := params.CreateEnterpriseParams{ + Name: enterpriseName, + CredentialsName: credentialsName, + WebhookSecret: enterpriseWebhookSecret, + } + enterprise, err := createEnterprise(cli, authToken, createParams) + handleError(err) + printResponse(enterprise) + enterpriseID = enterprise.ID +} + +func ListEnterprises() { + log.Println(">>> List enterprises") + enterprises, err := listEnterprises(cli, authToken) + handleError(err) + printResponse(enterprises) +} + +func UpdateEnterprise() { + log.Println(">>> Update enterprise") + updateParams := params.UpdateEntityParams{ + CredentialsName: fmt.Sprintf("%s-clone", credentialsName), + } + enterprise, err := updateEnterprise(cli, authToken, enterpriseID, updateParams) + handleError(err) + printResponse(enterprise) +} + +func GetEnterprise() { + log.Println(">>> Get enterprise") + enterprise, err := getEnterprise(cli, authToken, enterpriseID) + handleError(err) + printResponse(enterprise) +} + +func CreateEnterprisePool() { + pools, err := listEnterprisesPools(cli, authToken, enterpriseID) + handleError(err) + if len(pools) > 0 { + log.Println(">>> Enterprise pool already exists, skipping create") + enterprisePoolID = pools[0].ID + return + } + log.Println(">>> Create enterprise pool") + poolParams := params.CreatePoolParams{ + MaxRunners: 2, + MinIdleRunners: 0, + Flavor: "garm", + Image: "ubuntu:22.04", + OSType: commonParams.Linux, + OSArch: commonParams.Amd64, + ProviderName: "lxd_local", + Tags: []string{"ubuntu", "simple-runner"}, + Enabled: true, + } + enterprise, err := createEnterprisePool(cli, authToken, enterpriseID, poolParams) + handleError(err) + printResponse(enterprise) + enterprisePoolID = enterprise.ID +} + +func ListEnterprisePools() { + log.Println(">>> List enterprise pools") + pools, err := listEnterprisesPools(cli, authToken, enterpriseID) + handleError(err) + printResponse(pools) +} + +func GetEnterprisePool() { + log.Println(">>> Get enterprise pool") + pool, err := getEnterprisePool(cli, authToken, enterpriseID, enterprisePoolID) + handleError(err) + printResponse(pool) +} + +func UpdateEnterprisePool() { + log.Println(">>> Update enterprise pool") + var maxRunners uint = 5 + var idleRunners uint = 1 + poolParams := params.UpdatePoolParams{ + MinIdleRunners: &idleRunners, + MaxRunners: &maxRunners, + } + pool, err := updateEnterprisePool(cli, authToken, enterpriseID, enterprisePoolID, poolParams) + handleError(err) + printResponse(pool) +} + +func DisableEnterprisePool() { + enabled := false + _, err := updateEnterprisePool(cli, authToken, enterpriseID, enterprisePoolID, params.UpdatePoolParams{Enabled: &enabled}) + handleError(err) + log.Printf("enterprise pool %s disabled", enterprisePoolID) +} + +func WaitEnterprisePoolNoInstances() { + for { + log.Println(">>> Wait until enterprise pool has no instances") + pool, err := getEnterprisePool(cli, authToken, enterpriseID, enterprisePoolID) + handleError(err) + if len(pool.Instances) == 0 { + break + } + time.Sleep(5 * time.Second) + } +} + +func WaitEnterpriseInstance() { + log.Println(">>> Wait until enterprise instance is in running state") + for { + instances, err := listEnterpriseInstances(cli, authToken, enterpriseID) + handleError(err) + if len(instances) > 0 { + instance := instances[0] + log.Printf("instance %s status: %s", instance.Name, instance.Status) + if instance.Status == commonParams.InstanceRunning && instance.RunnerStatus == params.RunnerIdle { + enterpriseInstanceName := instance.Name + log.Printf("enterprise instance %s is running", enterpriseInstanceName) + break + } + } + time.Sleep(5 * time.Second) + } +} + +func ListEnterpriseInstances() { + log.Println(">>> List enterprise instances") + instances, err := listEnterpriseInstances(cli, authToken, enterpriseID) + handleError(err) + printResponse(instances) +} + +func DeleteEnterprise() { + log.Println(">>> Delete enterprise") + err := deleteEnterprise(cli, authToken, enterpriseID) + handleError(err) + log.Printf("enterprise %s deleted", enterpriseID) +} + +func DeleteEnterprisePool() { + log.Println(">>> Delete enterprise pool") + err := deleteEnterprisePool(cli, authToken, enterpriseID, enterprisePoolID) + handleError(err) + log.Printf("enterprise pool %s deleted", enterprisePoolID) +} + +func main() { + ////////////////// + // initialize cli / + ////////////////// + garmUrl, err := url.Parse(baseURL) + handleError(err) + apiPath, err := url.JoinPath(garmUrl.Path, client.DefaultBasePath) + handleError(err) + transportCfg := client.DefaultTransportConfig(). + WithHost(garmUrl.Host). + WithBasePath(apiPath). + WithSchemes([]string{garmUrl.Scheme}) + cli = client.NewHTTPClientWithConfig(nil, transportCfg) + + ////////////////// + // garm init // + ////////////////// + FirstRun() + Login() + + // //////////////////////////// + // credentials and providers // + // //////////////////////////// + ListCredentials() + ListProviders() + + ////////// + // jobs // + ////////// + ListJobs() + + //////////////////// + /// metrics token // + //////////////////// + GetMetricsToken() + + ////////////////// + // repositories // + ////////////////// + CreateRepo() + ListRepos() + UpdateRepo() + GetRepo() + + CreateRepoPool() + ListRepoPools() + GetRepoPool() + UpdateRepoPool() + + ////////////////// + // organizations // + ////////////////// + CreateOrg() + ListOrgs() + UpdateOrg() + GetOrg() + + CreateOrgPool() + ListOrgPools() + GetOrgPool() + UpdateOrgPool() + + /////////////// + // instances // + /////////////// + WaitRepoInstance() + ListRepoInstances() + + WaitOrgInstance() + ListOrgInstances() + + ListInstances() + GetInstance() + + /////////////// + // pools // + /////////////// + CreatePool() + ListPools() + UpdatePool() + GetPool() + ListPoolInstances() + + /////////////// + // enterprise / + /////////////// + // CreateEnterprise() + // ListEnterprises() + // UpdateEnterprise() + // GetEnterprise() + + // CreateEnterprisePool() + // ListEnterprisePools() + // GetEnterprisePool() + // UpdateEnterprisePool() + + // WaitEnterpriseInstance() + // ListEnterpriseInstances() + + // DisableEnterprisePool() + // DeleteInstance(enterpriseInstanceName) + // WaitEnterprisePoolNoInstances() + // DeleteEnterprisePool() + // DeleteEnterprise() + + ///////////// + // Cleanup // + ///////////// + DisableRepoPool() + DisableOrgPool() + + DeleteInstance(repoInstanceName) + DeleteInstance(orgInstanceName) + + WaitRepoPoolNoInstances() + WaitOrgPoolNoInstances() + + DeleteRepoPool() + DeleteOrgPool() + DeletePool() + + DeleteRepo() + DeleteOrg() +}