mirror of
https://github.com/goharbor/harbor.git
synced 2025-01-05 15:38:20 +01:00
add api testing for harbor including image pull and push
This commit is contained in:
parent
6f4e27ef73
commit
61eefbaf6c
97
tests/apitests/api-testing/client/docker_client.go
Normal file
97
tests/apitests/api-testing/client/docker_client.go
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import "os/exec"
|
||||||
|
import "strings"
|
||||||
|
import "errors"
|
||||||
|
import "bufio"
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
//DockerClient : Run docker commands
|
||||||
|
type DockerClient struct{}
|
||||||
|
|
||||||
|
//Status : Check if docker daemon is there
|
||||||
|
func (dc *DockerClient) Status() error {
|
||||||
|
cmdName := "docker"
|
||||||
|
args := []string{"info"}
|
||||||
|
|
||||||
|
return dc.runCommand(cmdName, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
//Pull : Pull image
|
||||||
|
func (dc *DockerClient) Pull(image string) error {
|
||||||
|
if len(strings.TrimSpace(image)) == 0 {
|
||||||
|
return errors.New("Empty image")
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdName := "docker"
|
||||||
|
args := []string{"pull", image}
|
||||||
|
|
||||||
|
return dc.runCommandWithOutput(cmdName, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
//Tag :Tag image
|
||||||
|
func (dc *DockerClient) Tag(source, target string) error {
|
||||||
|
if len(strings.TrimSpace(source)) == 0 ||
|
||||||
|
len(strings.TrimSpace(target)) == 0 {
|
||||||
|
return errors.New("Empty images")
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdName := "docker"
|
||||||
|
args := []string{"tag", source, target}
|
||||||
|
|
||||||
|
return dc.runCommandWithOutput(cmdName, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
//Push : push image
|
||||||
|
func (dc *DockerClient) Push(image string) error {
|
||||||
|
if len(strings.TrimSpace(image)) == 0 {
|
||||||
|
return errors.New("Empty image")
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdName := "docker"
|
||||||
|
args := []string{"push", image}
|
||||||
|
|
||||||
|
return dc.runCommandWithOutput(cmdName, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
//Login : Login docker
|
||||||
|
func (dc *DockerClient) Login(userName, password string, uri string) error {
|
||||||
|
if len(strings.TrimSpace(userName)) == 0 ||
|
||||||
|
len(strings.TrimSpace(password)) == 0 {
|
||||||
|
return errors.New("Invlaid credential")
|
||||||
|
}
|
||||||
|
|
||||||
|
cmdName := "docker"
|
||||||
|
args := []string{"login", "-u", userName, "-p", password, uri}
|
||||||
|
|
||||||
|
return dc.runCommandWithOutput(cmdName, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dc *DockerClient) runCommand(cmdName string, args []string) error {
|
||||||
|
return exec.Command(cmdName, args...).Run()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (dc *DockerClient) runCommandWithOutput(cmdName string, args []string) error {
|
||||||
|
cmd := exec.Command(cmdName, args...)
|
||||||
|
cmdReader, err := cmd.StdoutPipe()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
scanner := bufio.NewScanner(cmdReader)
|
||||||
|
go func() {
|
||||||
|
for scanner.Scan() {
|
||||||
|
fmt.Printf("%s out | %s\n", cmdName, scanner.Text())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if err = cmd.Start(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = cmd.Wait(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
170
tests/apitests/api-testing/client/harbor_api_client.go
Normal file
170
tests/apitests/api-testing/client/harbor_api_client.go
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/tls"
|
||||||
|
"crypto/x509"
|
||||||
|
"errors"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
httpHeaderJSON = "application/json"
|
||||||
|
httpHeaderContentType = "Content-Type"
|
||||||
|
httpHeaderAccept = "Accept"
|
||||||
|
)
|
||||||
|
|
||||||
|
//APIClientConfig : Keep config options for APIClient
|
||||||
|
type APIClientConfig struct {
|
||||||
|
Username string
|
||||||
|
Password string
|
||||||
|
CaFile string
|
||||||
|
CertFile string
|
||||||
|
KeyFile string
|
||||||
|
}
|
||||||
|
|
||||||
|
//APIClient provided the http client for trigger http requests
|
||||||
|
type APIClient struct {
|
||||||
|
//http client
|
||||||
|
client *http.Client
|
||||||
|
|
||||||
|
//Configuration
|
||||||
|
config APIClientConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
//NewAPIClient is constructor of APIClient
|
||||||
|
func NewAPIClient(config APIClientConfig) (*APIClient, error) {
|
||||||
|
//Load client cert
|
||||||
|
cert, err := tls.LoadX509KeyPair(config.CertFile, config.KeyFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//Add ca
|
||||||
|
caCert, err := ioutil.ReadFile(config.CaFile)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
caCertPool := x509.NewCertPool()
|
||||||
|
caCertPool.AppendCertsFromPEM(caCert)
|
||||||
|
|
||||||
|
tlsConfig := &tls.Config{
|
||||||
|
Certificates: []tls.Certificate{cert},
|
||||||
|
RootCAs: caCertPool,
|
||||||
|
}
|
||||||
|
|
||||||
|
tlsConfig.BuildNameToCertificate()
|
||||||
|
transport := &http.Transport{
|
||||||
|
TLSClientConfig: tlsConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &http.Client{
|
||||||
|
Transport: transport,
|
||||||
|
}
|
||||||
|
|
||||||
|
return &APIClient{
|
||||||
|
client: client,
|
||||||
|
config: config,
|
||||||
|
}, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//Get data
|
||||||
|
func (ac *APIClient) Get(url string) ([]byte, error) {
|
||||||
|
if strings.TrimSpace(url) == "" {
|
||||||
|
return nil, errors.New("empty url")
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set(httpHeaderAccept, httpHeaderJSON)
|
||||||
|
req.SetBasicAuth(ac.config.Username, ac.config.Password)
|
||||||
|
|
||||||
|
resp, err := ac.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if resp.Body != nil {
|
||||||
|
resp.Body.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return nil, errors.New(resp.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//Post data
|
||||||
|
func (ac *APIClient) Post(url string, data []byte) error {
|
||||||
|
if strings.TrimSpace(url) == "" {
|
||||||
|
return errors.New("Empty url")
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", url, strings.NewReader(string(data)))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set(httpHeaderContentType, httpHeaderJSON)
|
||||||
|
req.SetBasicAuth(ac.config.Username, ac.config.Password)
|
||||||
|
resp, err := ac.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusCreated &&
|
||||||
|
resp.StatusCode != http.StatusOK {
|
||||||
|
return errors.New(resp.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//Delete data
|
||||||
|
func (ac *APIClient) Delete(url string) error {
|
||||||
|
if strings.TrimSpace(url) == "" {
|
||||||
|
return errors.New("Empty url")
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("DELETE", url, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set(httpHeaderAccept, httpHeaderJSON)
|
||||||
|
req.SetBasicAuth(ac.config.Username, ac.config.Password)
|
||||||
|
|
||||||
|
resp, err := ac.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
return errors.New(resp.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//SwitchAccount : Switch account
|
||||||
|
func (ac *APIClient) SwitchAccount(username, password string) {
|
||||||
|
if len(strings.TrimSpace(username)) == 0 ||
|
||||||
|
len(strings.TrimSpace(password)) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ac.config.Username = username
|
||||||
|
ac.config.Password = password
|
||||||
|
}
|
17
tests/apitests/api-testing/envs/concourse_ci.go
Normal file
17
tests/apitests/api-testing/envs/concourse_ci.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package envs
|
||||||
|
|
||||||
|
//ConcourseCIEnv : Env for concourse pipeline
|
||||||
|
var ConcourseCIEnv = Environment{
|
||||||
|
Protocol: "https",
|
||||||
|
TestingProject: "concoursecitesting01",
|
||||||
|
ImageName: "busybox",
|
||||||
|
ImageTag: "latest",
|
||||||
|
CAFile: "../../../ca.crt",
|
||||||
|
KeyFile: "../../../key.crt",
|
||||||
|
CertFile: "../../../cert.crt",
|
||||||
|
Account: "cody",
|
||||||
|
Password: "Admin!23",
|
||||||
|
Admin: "admin",
|
||||||
|
AdminPass: "pksxgxmifc0cnwa5px9h",
|
||||||
|
Hostname: "10.112.122.1",
|
||||||
|
}
|
127
tests/apitests/api-testing/envs/environment.go
Normal file
127
tests/apitests/api-testing/envs/environment.go
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
package envs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/vmware/harbor/tests/apitests/api-testing/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
//Environment keeps the testing env info
|
||||||
|
type Environment struct {
|
||||||
|
Protocol string //env var: HTTP_PROTOCOL
|
||||||
|
Hostname string //env var: TESTING_ENV_HOSTNAME
|
||||||
|
Account string //env var: TESTING_ENV_ACCOUNT
|
||||||
|
Password string //env var: TESTING_ENV_PASSWORD
|
||||||
|
Admin string //env var: TESTING_ENV_ADMIN
|
||||||
|
AdminPass string //env var: TESTING_ENV_ADMIN_PASS
|
||||||
|
TestingProject string //env var: TESTING_PROJECT_NAME
|
||||||
|
ImageName string //env var: TESTING_IMAGE_NAME
|
||||||
|
ImageTag string //env var: TESTING_IMAGE_TAG
|
||||||
|
CAFile string //env var: CA_FILE_PATH
|
||||||
|
CertFile string //env var: CERT_FILE_PATH
|
||||||
|
KeyFile string //env var: KEY_FILE_PATH
|
||||||
|
|
||||||
|
//API client
|
||||||
|
HTTPClient *client.APIClient
|
||||||
|
|
||||||
|
//Docker client
|
||||||
|
DockerClient *client.DockerClient
|
||||||
|
|
||||||
|
//Initialize status
|
||||||
|
loaded bool
|
||||||
|
}
|
||||||
|
|
||||||
|
//Load test env info
|
||||||
|
func (env *Environment) Load() error {
|
||||||
|
host := os.Getenv("TESTING_ENV_HOSTNAME")
|
||||||
|
if isNotEmpty(host) {
|
||||||
|
env.Hostname = host
|
||||||
|
}
|
||||||
|
|
||||||
|
account := os.Getenv("TESTING_ENV_ACCOUNT")
|
||||||
|
if isNotEmpty(account) {
|
||||||
|
env.Account = account
|
||||||
|
}
|
||||||
|
|
||||||
|
pwd := os.Getenv("TESTING_ENV_PASSWORD")
|
||||||
|
if isNotEmpty(pwd) {
|
||||||
|
env.Password = pwd
|
||||||
|
}
|
||||||
|
|
||||||
|
admin := os.Getenv("TESTING_ENV_ADMIN")
|
||||||
|
if isNotEmpty(admin) {
|
||||||
|
env.Admin = admin
|
||||||
|
}
|
||||||
|
|
||||||
|
adminPwd := os.Getenv("TESTING_ENV_ADMIN_PASS")
|
||||||
|
if isNotEmpty(adminPwd) {
|
||||||
|
env.AdminPass = adminPwd
|
||||||
|
}
|
||||||
|
|
||||||
|
pro := os.Getenv("TESTING_PROJECT_NAME")
|
||||||
|
if isNotEmpty(pro) {
|
||||||
|
env.TestingProject = pro
|
||||||
|
}
|
||||||
|
|
||||||
|
imgName := os.Getenv("TESTING_IMAGE_NAME")
|
||||||
|
if isNotEmpty(imgName) {
|
||||||
|
env.ImageName = imgName
|
||||||
|
}
|
||||||
|
|
||||||
|
imgTag := os.Getenv("TESTING_IMAGE_TAG")
|
||||||
|
if isNotEmpty(imgTag) {
|
||||||
|
env.ImageTag = imgTag
|
||||||
|
}
|
||||||
|
|
||||||
|
protocol := os.Getenv("HTTP_PROTOCOL")
|
||||||
|
if isNotEmpty(protocol) {
|
||||||
|
env.Protocol = protocol
|
||||||
|
}
|
||||||
|
|
||||||
|
caFile := os.Getenv("CA_FILE_PATH")
|
||||||
|
if isNotEmpty(caFile) {
|
||||||
|
env.CAFile = caFile
|
||||||
|
}
|
||||||
|
|
||||||
|
keyFile := os.Getenv("KEY_FILE_PATH")
|
||||||
|
if isNotEmpty(keyFile) {
|
||||||
|
env.KeyFile = keyFile
|
||||||
|
}
|
||||||
|
|
||||||
|
certFile := os.Getenv("CERT_FILE_PATH")
|
||||||
|
if isNotEmpty(certFile) {
|
||||||
|
env.CertFile = certFile
|
||||||
|
}
|
||||||
|
|
||||||
|
if !env.loaded {
|
||||||
|
cfg := client.APIClientConfig{
|
||||||
|
Username: env.Admin,
|
||||||
|
Password: env.AdminPass,
|
||||||
|
CaFile: env.CAFile,
|
||||||
|
CertFile: env.CertFile,
|
||||||
|
KeyFile: env.KeyFile,
|
||||||
|
}
|
||||||
|
|
||||||
|
httpClient, err := client.NewAPIClient(cfg)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
env.HTTPClient = httpClient
|
||||||
|
env.DockerClient = &client.DockerClient{}
|
||||||
|
|
||||||
|
env.loaded = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//RootURI : The root URI like https://<hostname>
|
||||||
|
func (env *Environment) RootURI() string {
|
||||||
|
return fmt.Sprintf("%s://%s", env.Protocol, env.Hostname)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isNotEmpty(str string) bool {
|
||||||
|
return len(strings.TrimSpace(str)) > 0
|
||||||
|
}
|
137
tests/apitests/api-testing/lib/image.go
Normal file
137
tests/apitests/api-testing/lib/image.go
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/vmware/harbor/tests/apitests/api-testing/client"
|
||||||
|
"github.com/vmware/harbor/tests/apitests/api-testing/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
//ImageUtil : For repository and tag functions
|
||||||
|
type ImageUtil struct {
|
||||||
|
rootURI string
|
||||||
|
testingClient *client.APIClient
|
||||||
|
}
|
||||||
|
|
||||||
|
//NewImageUtil : Constructor
|
||||||
|
func NewImageUtil(rootURI string, httpClient *client.APIClient) *ImageUtil {
|
||||||
|
if len(strings.TrimSpace(rootURI)) == 0 || httpClient == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ImageUtil{
|
||||||
|
rootURI: rootURI,
|
||||||
|
testingClient: httpClient,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//DeleteRepo : Delete repo
|
||||||
|
func (iu *ImageUtil) DeleteRepo(repoName string) error {
|
||||||
|
if len(strings.TrimSpace(repoName)) == 0 {
|
||||||
|
return errors.New("Empty repo name for deleting")
|
||||||
|
}
|
||||||
|
|
||||||
|
url := fmt.Sprintf("%s%s%s", iu.rootURI, "/api/repositories/", repoName)
|
||||||
|
if err := iu.testingClient.Delete(url); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//ScanTag :Scan a tag
|
||||||
|
func (iu *ImageUtil) ScanTag(repoName string, tagName string) error {
|
||||||
|
if len(strings.TrimSpace(repoName)) == 0 {
|
||||||
|
return errors.New("Empty repo name for scanning")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(strings.TrimSpace(tagName)) == 0 {
|
||||||
|
return errors.New("Empty tag name for scanning")
|
||||||
|
}
|
||||||
|
|
||||||
|
url := fmt.Sprintf("%s%s%s%s%s%s", iu.rootURI, "/api/repositories/", repoName, "/tags/", tagName, "/scan")
|
||||||
|
if err := iu.testingClient.Post(url, nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
tk := time.NewTicker(1 * time.Second)
|
||||||
|
defer tk.Stop()
|
||||||
|
done := make(chan bool)
|
||||||
|
errchan := make(chan error)
|
||||||
|
url = fmt.Sprintf("%s%s%s%s%s", iu.rootURI, "/api/repositories/", repoName, "/tags/", tagName)
|
||||||
|
go func() {
|
||||||
|
for _ = range tk.C {
|
||||||
|
data, err := iu.testingClient.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
errchan <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var tag models.Tag
|
||||||
|
if err = json.Unmarshal(data, &tag); err != nil {
|
||||||
|
errchan <- err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if tag.ScanOverview != nil && tag.ScanOverview.Status == "finished" {
|
||||||
|
done <- true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-done:
|
||||||
|
return nil
|
||||||
|
case <-time.After(20 * time.Second):
|
||||||
|
return errors.New("Scan timeout after 30 seconds")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//GetRepos : Get repos in the project
|
||||||
|
func (iu *ImageUtil) GetRepos(projectName string) ([]models.Repository, error) {
|
||||||
|
if len(strings.TrimSpace(projectName)) == 0 {
|
||||||
|
return nil, errors.New("Empty project name for getting repos")
|
||||||
|
}
|
||||||
|
|
||||||
|
proUtil := NewProjectUtil(iu.rootURI, iu.testingClient)
|
||||||
|
pid := proUtil.GetProjectID(projectName)
|
||||||
|
if pid == -1 {
|
||||||
|
return nil, fmt.Errorf("Failed to get project ID with name %s", projectName)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := fmt.Sprintf("%s%s%d", iu.rootURI, "/api/repositories?project_id=", pid)
|
||||||
|
data, err := iu.testingClient.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var repos []models.Repository
|
||||||
|
if err = json.Unmarshal(data, &repos); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return repos, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//GetTags : Get tags
|
||||||
|
func (iu *ImageUtil) GetTags(repoName string) ([]models.Tag, error) {
|
||||||
|
if len(strings.TrimSpace(repoName)) == 0 {
|
||||||
|
return nil, errors.New("Empty repository name for getting tags")
|
||||||
|
}
|
||||||
|
|
||||||
|
url := fmt.Sprintf("%s%s%s%s", iu.rootURI, "/api/repositories/", repoName, "/tags")
|
||||||
|
tagData, err := iu.testingClient.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var tags []models.Tag
|
||||||
|
if err = json.Unmarshal(tagData, &tags); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tags, nil
|
||||||
|
}
|
169
tests/apitests/api-testing/lib/project.go
Normal file
169
tests/apitests/api-testing/lib/project.go
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/vmware/harbor/tests/apitests/api-testing/client"
|
||||||
|
"github.com/vmware/harbor/tests/apitests/api-testing/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
//ProjectUtil : Util methods for project related
|
||||||
|
type ProjectUtil struct {
|
||||||
|
rootURI string
|
||||||
|
testingClient *client.APIClient
|
||||||
|
}
|
||||||
|
|
||||||
|
//NewProjectUtil : Constructor
|
||||||
|
func NewProjectUtil(rootURI string, httpClient *client.APIClient) *ProjectUtil {
|
||||||
|
if len(strings.TrimSpace(rootURI)) == 0 || httpClient == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ProjectUtil{
|
||||||
|
rootURI: rootURI,
|
||||||
|
testingClient: httpClient,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//GetProjects : Get projects
|
||||||
|
//If name specified, then only get the specified project
|
||||||
|
func (pu *ProjectUtil) GetProjects(name string) ([]models.ExistingProject, error) {
|
||||||
|
url := pu.rootURI + "/api/projects"
|
||||||
|
if len(strings.TrimSpace(name)) > 0 {
|
||||||
|
url = url + "?name=" + name
|
||||||
|
}
|
||||||
|
data, err := pu.testingClient.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var pros []models.ExistingProject
|
||||||
|
if err = json.Unmarshal(data, &pros); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return pros, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//GetProjectID : Get the project ID
|
||||||
|
//If no project existing with the name, then return -1
|
||||||
|
func (pu *ProjectUtil) GetProjectID(projectName string) int {
|
||||||
|
pros, err := pu.GetProjects(projectName)
|
||||||
|
if err != nil {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(pros) == 0 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, pro := range pros {
|
||||||
|
if pro.Name == projectName {
|
||||||
|
return pro.ID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
//CreateProject :Create project
|
||||||
|
func (pu *ProjectUtil) CreateProject(projectName string, accessLevel bool) error {
|
||||||
|
if len(strings.TrimSpace(projectName)) == 0 {
|
||||||
|
return errors.New("Empty project name for creating")
|
||||||
|
}
|
||||||
|
|
||||||
|
p := models.Project{
|
||||||
|
Name: projectName,
|
||||||
|
Metadata: &models.Metadata{
|
||||||
|
AccessLevel: fmt.Sprintf("%v", accessLevel),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := json.Marshal(&p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
url := pu.rootURI + "/api/projects"
|
||||||
|
if err = pu.testingClient.Post(url, body); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//DeleteProject : Delete project
|
||||||
|
func (pu *ProjectUtil) DeleteProject(projectName string) error {
|
||||||
|
if len(strings.TrimSpace(projectName)) == 0 {
|
||||||
|
return errors.New("Empty project name for deleting")
|
||||||
|
}
|
||||||
|
|
||||||
|
pid := pu.GetProjectID(projectName)
|
||||||
|
if pid == -1 {
|
||||||
|
return errors.New("Failed to get project ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
url := fmt.Sprintf("%s%s%d", pu.rootURI, "/api/projects/", pid)
|
||||||
|
|
||||||
|
if err := pu.testingClient.Delete(url); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//AssignRole : Assign role to user
|
||||||
|
func (pu *ProjectUtil) AssignRole(projectName, username string) error {
|
||||||
|
if len(strings.TrimSpace(projectName)) == 0 ||
|
||||||
|
len(strings.TrimSpace(username)) == 0 {
|
||||||
|
return errors.New("Project name and username are required for assigning role")
|
||||||
|
}
|
||||||
|
|
||||||
|
pid := pu.GetProjectID(projectName)
|
||||||
|
if pid == -1 {
|
||||||
|
return fmt.Errorf("Failed to get project ID with name %s", projectName)
|
||||||
|
}
|
||||||
|
|
||||||
|
m := models.Member{
|
||||||
|
UserName: username,
|
||||||
|
Roles: []int{2},
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := json.Marshal(&m)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
url := fmt.Sprintf("%s%s%d%s", pu.rootURI, "/api/projects/", pid, "/members")
|
||||||
|
if err := pu.testingClient.Post(url, body); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//RevokeRole : RevokeRole role from user
|
||||||
|
func (pu *ProjectUtil) RevokeRole(projectName string, uid int) error {
|
||||||
|
if len(strings.TrimSpace(projectName)) == 0 {
|
||||||
|
return errors.New("Project name is required for revoking role")
|
||||||
|
}
|
||||||
|
|
||||||
|
if uid == 0 {
|
||||||
|
return errors.New("User ID is required for revoking role")
|
||||||
|
}
|
||||||
|
|
||||||
|
pid := pu.GetProjectID(projectName)
|
||||||
|
if pid == -1 {
|
||||||
|
return fmt.Errorf("Failed to get project ID with name %s", projectName)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := fmt.Sprintf("%s%s%d%s%d", pu.rootURI, "/api/projects/", pid, "/members/", uid)
|
||||||
|
if err := pu.testingClient.Delete(url); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
43
tests/apitests/api-testing/lib/report.go
Normal file
43
tests/apitests/api-testing/lib/report.go
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Report struct {
|
||||||
|
passed []string
|
||||||
|
failed []string
|
||||||
|
}
|
||||||
|
|
||||||
|
//Passed case
|
||||||
|
func (r *Report) Passed(caseName string) {
|
||||||
|
r.passed = append(r.passed, fmt.Sprintf("%s: [%s]", caseName, "PASSED"))
|
||||||
|
}
|
||||||
|
|
||||||
|
//Failed case
|
||||||
|
func (r *Report) Failed(caseName string, err error) {
|
||||||
|
r.failed = append(r.failed, fmt.Sprintf("%s: [%s] %s", caseName, "FAILED", err.Error()))
|
||||||
|
}
|
||||||
|
|
||||||
|
//Print report
|
||||||
|
func (r *Report) Print() {
|
||||||
|
passed := len(r.passed)
|
||||||
|
failed := len(r.failed)
|
||||||
|
total := passed + failed
|
||||||
|
|
||||||
|
fmt.Println("=====================================")
|
||||||
|
fmt.Printf("Overall: %d/%d passed , %d/%d failed\n", passed, total, failed, total)
|
||||||
|
fmt.Println("=====================================")
|
||||||
|
for _, res := range r.passed {
|
||||||
|
fmt.Println(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, res := range r.failed {
|
||||||
|
fmt.Println(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//IsFail : Overall result
|
||||||
|
func (r *Report) IsFail() bool {
|
||||||
|
return len(r.failed) > 0
|
||||||
|
}
|
50
tests/apitests/api-testing/lib/system.go
Normal file
50
tests/apitests/api-testing/lib/system.go
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/vmware/harbor/tests/apitests/api-testing/client"
|
||||||
|
"github.com/vmware/harbor/tests/apitests/api-testing/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
//SystemUtil : For getting system info
|
||||||
|
type SystemUtil struct {
|
||||||
|
rootURI string
|
||||||
|
hostname string
|
||||||
|
testingClient *client.APIClient
|
||||||
|
}
|
||||||
|
|
||||||
|
//NewSystemUtil : Constructor
|
||||||
|
func NewSystemUtil(rootURI, hostname string, httpClient *client.APIClient) *SystemUtil {
|
||||||
|
if len(strings.TrimSpace(rootURI)) == 0 || httpClient == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &SystemUtil{
|
||||||
|
rootURI: rootURI,
|
||||||
|
hostname: hostname,
|
||||||
|
testingClient: httpClient,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//GetSystemInfo : Get systeminfo
|
||||||
|
func (nsu *SystemUtil) GetSystemInfo() error {
|
||||||
|
url := nsu.rootURI + "/api/systeminfo"
|
||||||
|
data, err := nsu.testingClient.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var info models.SystemInfo
|
||||||
|
if err := json.Unmarshal(data, &info); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if info.RegistryURL != nsu.hostname {
|
||||||
|
return fmt.Errorf("Invalid registry url in system info: expect %s got %s ", nsu.hostname, info.RegistryURL)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
118
tests/apitests/api-testing/lib/user.go
Normal file
118
tests/apitests/api-testing/lib/user.go
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package lib
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/vmware/harbor/tests/apitests/api-testing/client"
|
||||||
|
"github.com/vmware/harbor/tests/apitests/api-testing/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
//UserUtil : For user related
|
||||||
|
type UserUtil struct {
|
||||||
|
rootURI string
|
||||||
|
testingClient *client.APIClient
|
||||||
|
}
|
||||||
|
|
||||||
|
//NewUserUtil : Constructor
|
||||||
|
func NewUserUtil(rootURI string, httpClient *client.APIClient) *UserUtil {
|
||||||
|
if len(strings.TrimSpace(rootURI)) == 0 || httpClient == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &UserUtil{
|
||||||
|
rootURI: rootURI,
|
||||||
|
testingClient: httpClient,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//CreateUser : Create user
|
||||||
|
func (uu *UserUtil) CreateUser(username, password string) error {
|
||||||
|
if len(strings.TrimSpace(username)) == 0 ||
|
||||||
|
len(strings.TrimSpace(password)) == 0 {
|
||||||
|
return errors.New("Username and password required for creating user")
|
||||||
|
}
|
||||||
|
|
||||||
|
u := models.User{
|
||||||
|
Username: username,
|
||||||
|
Password: password,
|
||||||
|
Email: username + "@vmware.com",
|
||||||
|
RealName: username + "pks",
|
||||||
|
Comment: "testing",
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := json.Marshal(&u)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
url := fmt.Sprintf("%s%s", uu.rootURI, "/api/users")
|
||||||
|
if err := uu.testingClient.Post(url, body); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//DeleteUser : Delete testing account
|
||||||
|
func (uu *UserUtil) DeleteUser(username string) error {
|
||||||
|
uid := uu.GetUserID(username)
|
||||||
|
if uid == -1 {
|
||||||
|
return fmt.Errorf("Failed to get user with name %s", username)
|
||||||
|
}
|
||||||
|
|
||||||
|
url := fmt.Sprintf("%s%s%d", uu.rootURI, "/api/users/", uid)
|
||||||
|
if err := uu.testingClient.Delete(url); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//GetUsers : Get users
|
||||||
|
//If name specified, then return that one
|
||||||
|
func (uu *UserUtil) GetUsers(name string) ([]models.ExistingUser, error) {
|
||||||
|
url := fmt.Sprintf("%s%s", uu.rootURI, "/api/users")
|
||||||
|
if len(strings.TrimSpace(name)) > 0 {
|
||||||
|
url = url + "?username=" + name
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := uu.testingClient.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var users []models.ExistingUser
|
||||||
|
if err = json.Unmarshal(data, &users); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return users, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//GetUserID : Get user ID
|
||||||
|
//If user with the username is not existing, then return -1
|
||||||
|
func (uu *UserUtil) GetUserID(username string) int {
|
||||||
|
if len(strings.TrimSpace(username)) == 0 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
users, err := uu.GetUsers(username)
|
||||||
|
if err != nil {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(users) == 0 {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, u := range users {
|
||||||
|
if u.Username == username {
|
||||||
|
return u.ID
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1
|
||||||
|
}
|
10
tests/apitests/api-testing/models/endpoint.go
Normal file
10
tests/apitests/api-testing/models/endpoint.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
//Endpoint : For /api/targets
|
||||||
|
type Endpoint struct {
|
||||||
|
Endpoint string `json:"endpoint"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Username string `json:"username"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Type int `json:"type"`
|
||||||
|
}
|
20
tests/apitests/api-testing/models/image.go
Normal file
20
tests/apitests/api-testing/models/image.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
//Repository : For /api/repositories
|
||||||
|
type Repository struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//Tag : For /api/repositories/:repo/tags
|
||||||
|
type Tag struct {
|
||||||
|
Digest string `json:"digest"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Signature map[string]interface{} `json:"signature, omitempty"`
|
||||||
|
ScanOverview *ScanOverview `json:"scan_overview, omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//ScanOverview : For scanning
|
||||||
|
type ScanOverview struct {
|
||||||
|
Status string `json:"scan_status"`
|
||||||
|
}
|
7
tests/apitests/api-testing/models/member.go
Normal file
7
tests/apitests/api-testing/models/member.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
//Member : For /api/projects/:pid/members
|
||||||
|
type Member struct {
|
||||||
|
UserName string `json:"username"`
|
||||||
|
Roles []int `json:"roles"`
|
||||||
|
}
|
18
tests/apitests/api-testing/models/project.go
Normal file
18
tests/apitests/api-testing/models/project.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
//Project : For /api/projects
|
||||||
|
type Project struct {
|
||||||
|
Name string `json:"project_name"`
|
||||||
|
Metadata *Metadata `json:"metadata, omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//Metadata : Metadata for project
|
||||||
|
type Metadata struct {
|
||||||
|
AccessLevel string `json:"public"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//ExistingProject : For /api/projects?name=***
|
||||||
|
type ExistingProject struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
ID int `json:"project_id"`
|
||||||
|
}
|
10
tests/apitests/api-testing/models/replication.go
Normal file
10
tests/apitests/api-testing/models/replication.go
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
//ReplicationPolicy : For /api/replications
|
||||||
|
type ReplicationPolicy struct {
|
||||||
|
ProjectID int `json:"project_id"`
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
type ExistingReplicationPolicy struct {
|
||||||
|
}
|
7
tests/apitests/api-testing/models/system_info.go
Normal file
7
tests/apitests/api-testing/models/system_info.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
//SystemInfo : For GET /api/systeminfo
|
||||||
|
type SystemInfo struct {
|
||||||
|
AuthMode string `json:"auth_mode"`
|
||||||
|
RegistryURL string `json:"registry_url"`
|
||||||
|
}
|
16
tests/apitests/api-testing/models/user.go
Normal file
16
tests/apitests/api-testing/models/user.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package models
|
||||||
|
|
||||||
|
//User : For /api/users
|
||||||
|
type User struct {
|
||||||
|
Username string `json:"username"`
|
||||||
|
RealName string `json:"realname"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
Comment string `json:"comment"`
|
||||||
|
}
|
||||||
|
|
||||||
|
//ExistingUser : For GET /api/users
|
||||||
|
type ExistingUser struct {
|
||||||
|
User
|
||||||
|
ID int `json:"user_id"`
|
||||||
|
}
|
11
tests/apitests/api-testing/tests/suites/suite.go
Normal file
11
tests/apitests/api-testing/tests/suites/suite.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package suites
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/vmware/harbor/tests/apitests/api-testing/envs"
|
||||||
|
"github.com/vmware/harbor/tests/apitests/api-testing/lib"
|
||||||
|
)
|
||||||
|
|
||||||
|
//Suite : Run a group of test cases
|
||||||
|
type Suite interface {
|
||||||
|
Run(onEnvironment envs.Environment) *lib.Report
|
||||||
|
}
|
22
tests/apitests/api-testing/tests/suites/suite01/run_test.go
Normal file
22
tests/apitests/api-testing/tests/suites/suite01/run_test.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package suite01
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/vmware/harbor/tests/apitests/api-testing/envs"
|
||||||
|
)
|
||||||
|
|
||||||
|
//TestRun : Start to run the case
|
||||||
|
func TestRun(t *testing.T) {
|
||||||
|
//Initialize env
|
||||||
|
if err := envs.ConcourseCIEnv.Load(); err != nil {
|
||||||
|
t.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
suite := ConcourseCiSuite01{}
|
||||||
|
report := suite.Run(&envs.ConcourseCIEnv)
|
||||||
|
report.Print()
|
||||||
|
if report.IsFail() {
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
177
tests/apitests/api-testing/tests/suites/suite01/suite.go
Normal file
177
tests/apitests/api-testing/tests/suites/suite01/suite.go
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
package suite01
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/vmware/harbor/tests/apitests/api-testing/envs"
|
||||||
|
"github.com/vmware/harbor/tests/apitests/api-testing/lib"
|
||||||
|
)
|
||||||
|
|
||||||
|
//Steps of suite01:
|
||||||
|
// s0: Get systeminfo
|
||||||
|
// s1: create project
|
||||||
|
// s2: create user "cody"
|
||||||
|
// s3: assign cody as developer
|
||||||
|
// s4: push a busybox image to project
|
||||||
|
// s5: scan image
|
||||||
|
// s6: pull image from project
|
||||||
|
// s7: remove "cody" from project member list
|
||||||
|
// s8: pull image from project [FAIL]
|
||||||
|
// s9: remove repository busybox
|
||||||
|
// s10: delete project
|
||||||
|
// s11: delete user
|
||||||
|
|
||||||
|
//ConcourseCiSuite01 : For harbor journey in concourse pipeline
|
||||||
|
type ConcourseCiSuite01 struct{}
|
||||||
|
|
||||||
|
//Run : Run a group of cases
|
||||||
|
func (ccs *ConcourseCiSuite01) Run(onEnvironment *envs.Environment) *lib.Report {
|
||||||
|
report := &lib.Report{}
|
||||||
|
|
||||||
|
//s0
|
||||||
|
sys := lib.NewSystemUtil(onEnvironment.RootURI(), onEnvironment.Hostname, onEnvironment.HTTPClient)
|
||||||
|
if err := sys.GetSystemInfo(); err != nil {
|
||||||
|
report.Failed("GetSystemInfo", err)
|
||||||
|
} else {
|
||||||
|
report.Passed("GetSystemInfo")
|
||||||
|
}
|
||||||
|
|
||||||
|
//s1
|
||||||
|
pro := lib.NewProjectUtil(onEnvironment.RootURI(), onEnvironment.HTTPClient)
|
||||||
|
if err := pro.CreateProject(onEnvironment.TestingProject, false); err != nil {
|
||||||
|
report.Failed("CreateProject", err)
|
||||||
|
} else {
|
||||||
|
report.Passed("CreateProject")
|
||||||
|
}
|
||||||
|
|
||||||
|
//s2
|
||||||
|
usr := lib.NewUserUtil(onEnvironment.RootURI(), onEnvironment.HTTPClient)
|
||||||
|
if err := usr.CreateUser(onEnvironment.Account, onEnvironment.Password); err != nil {
|
||||||
|
report.Failed("CreateUser", err)
|
||||||
|
} else {
|
||||||
|
report.Passed("CreateUser")
|
||||||
|
}
|
||||||
|
|
||||||
|
//s3
|
||||||
|
if err := pro.AssignRole(onEnvironment.TestingProject, onEnvironment.Account); err != nil {
|
||||||
|
report.Failed("AssignRole", err)
|
||||||
|
} else {
|
||||||
|
report.Passed("AssignRole")
|
||||||
|
}
|
||||||
|
|
||||||
|
//s4
|
||||||
|
if err := ccs.pushImage(onEnvironment); err != nil {
|
||||||
|
report.Failed("pushImage", err)
|
||||||
|
} else {
|
||||||
|
report.Passed("pushImage")
|
||||||
|
}
|
||||||
|
|
||||||
|
//s5
|
||||||
|
img := lib.NewImageUtil(onEnvironment.RootURI(), onEnvironment.HTTPClient)
|
||||||
|
repoName := fmt.Sprintf("%s/%s", onEnvironment.TestingProject, onEnvironment.ImageName)
|
||||||
|
if err := img.ScanTag(repoName, onEnvironment.ImageTag); err != nil {
|
||||||
|
report.Failed("ScanTag", err)
|
||||||
|
} else {
|
||||||
|
report.Passed("ScanTag")
|
||||||
|
}
|
||||||
|
|
||||||
|
//s6
|
||||||
|
if err := ccs.pullImage(onEnvironment); err != nil {
|
||||||
|
report.Failed("pullImage[1]", err)
|
||||||
|
} else {
|
||||||
|
report.Passed("pullImage[1]")
|
||||||
|
}
|
||||||
|
|
||||||
|
//s7
|
||||||
|
uid := usr.GetUserID(onEnvironment.Account)
|
||||||
|
if err := pro.RevokeRole(onEnvironment.TestingProject, uid); err != nil {
|
||||||
|
report.Failed("RevokeRole", err)
|
||||||
|
} else {
|
||||||
|
report.Passed("RevokeRole")
|
||||||
|
}
|
||||||
|
|
||||||
|
//s8
|
||||||
|
if err := ccs.pullImage(onEnvironment); err == nil {
|
||||||
|
report.Failed("pullImage[2]", err)
|
||||||
|
} else {
|
||||||
|
report.Passed("pullImage[2]")
|
||||||
|
}
|
||||||
|
|
||||||
|
//s9
|
||||||
|
if err := img.DeleteRepo(repoName); err != nil {
|
||||||
|
report.Failed("DeleteRepo", err)
|
||||||
|
} else {
|
||||||
|
report.Passed("DeleteRepo")
|
||||||
|
}
|
||||||
|
|
||||||
|
//s10
|
||||||
|
if err := pro.DeleteProject(onEnvironment.TestingProject); err != nil {
|
||||||
|
report.Failed("DeleteProject", err)
|
||||||
|
} else {
|
||||||
|
report.Passed("DeleteProject")
|
||||||
|
}
|
||||||
|
|
||||||
|
//s11
|
||||||
|
if err := usr.DeleteUser(onEnvironment.Account); err != nil {
|
||||||
|
report.Failed("DeleteUser", err)
|
||||||
|
} else {
|
||||||
|
report.Passed("DeleteUser")
|
||||||
|
}
|
||||||
|
|
||||||
|
return report
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ccs *ConcourseCiSuite01) pushImage(onEnvironment *envs.Environment) error {
|
||||||
|
docker := onEnvironment.DockerClient
|
||||||
|
if err := docker.Status(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
imagePulling := fmt.Sprintf("%s:%s", onEnvironment.ImageName, onEnvironment.ImageTag)
|
||||||
|
if err := docker.Pull(imagePulling); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := docker.Login(onEnvironment.Account, onEnvironment.Password, onEnvironment.Hostname); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
imagePushing := fmt.Sprintf("%s/%s/%s:%s",
|
||||||
|
onEnvironment.Hostname,
|
||||||
|
onEnvironment.TestingProject,
|
||||||
|
onEnvironment.ImageName,
|
||||||
|
onEnvironment.ImageTag)
|
||||||
|
|
||||||
|
if err := docker.Tag(imagePulling, imagePushing); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := docker.Push(imagePushing); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ccs *ConcourseCiSuite01) pullImage(onEnvironment *envs.Environment) error {
|
||||||
|
docker := onEnvironment.DockerClient
|
||||||
|
if err := docker.Status(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := docker.Login(onEnvironment.Account, onEnvironment.Password, onEnvironment.Hostname); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
imagePulling := fmt.Sprintf("%s/%s/%s:%s",
|
||||||
|
onEnvironment.Hostname,
|
||||||
|
onEnvironment.TestingProject,
|
||||||
|
onEnvironment.ImageName,
|
||||||
|
onEnvironment.ImageTag)
|
||||||
|
|
||||||
|
if err := docker.Pull(imagePulling); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user