Merge pull request #1628 from soulseen/fix/image_search
remove schema if required and add check SSL
This commit is contained in:
@@ -21,6 +21,7 @@ package registries
|
||||
import (
|
||||
"github.com/emicklei/go-restful"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"kubesphere.io/kubesphere/pkg/models/registries"
|
||||
"kubesphere.io/kubesphere/pkg/server/errors"
|
||||
@@ -68,6 +69,25 @@ func RegistryImageBlob(request *restful.Request, response *restful.Response) {
|
||||
return
|
||||
}
|
||||
|
||||
// default use ssl
|
||||
checkSSl := func(serverAddress string) bool {
|
||||
if strings.HasPrefix(serverAddress, "http://") {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if strings.HasPrefix(imageName, "http") {
|
||||
dockerurl, err := registries.ParseDockerURL(imageName)
|
||||
if err != nil {
|
||||
log.Errorf("%+v", err)
|
||||
errors.ParseSvcErr(restful.NewError(http.StatusBadRequest, err.Error()), response)
|
||||
return
|
||||
}
|
||||
imageName = dockerurl.StringWithoutScheme()
|
||||
}
|
||||
|
||||
// parse image
|
||||
image, err := registries.ParseImage(imageName)
|
||||
if err != nil {
|
||||
@@ -76,8 +96,10 @@ func RegistryImageBlob(request *restful.Request, response *restful.Response) {
|
||||
return
|
||||
}
|
||||
|
||||
useSSL := checkSSl(entry.ServerAddress)
|
||||
|
||||
// Create the registry client.
|
||||
r, err := registries.CreateRegistryClient(entry.Username, entry.Password, image.Domain)
|
||||
r, err := registries.CreateRegistryClient(entry.Username, entry.Password, image.Domain, useSSL)
|
||||
if err != nil {
|
||||
log.Errorf("%+v", err)
|
||||
response.WriteAsJson(®istries.ImageDetails{Status: registries.StatusFailed, Message: err.Error()})
|
||||
|
||||
@@ -2,9 +2,11 @@ package registries
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/docker/distribution/reference"
|
||||
digest "github.com/opencontainers/go-digest"
|
||||
"github.com/opencontainers/go-digest"
|
||||
log "k8s.io/klog"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Image holds information about an image.
|
||||
@@ -30,9 +32,28 @@ func (i *Image) Reference() string {
|
||||
return i.Tag
|
||||
}
|
||||
|
||||
type DockerURL struct {
|
||||
*url.URL
|
||||
}
|
||||
|
||||
func (u *DockerURL) StringWithoutScheme() string {
|
||||
u.Scheme = ""
|
||||
s := u.String()
|
||||
return strings.Trim(s, "//")
|
||||
}
|
||||
|
||||
func ParseDockerURL(rawurl string) (*DockerURL, error) {
|
||||
url, err := url.Parse(rawurl)
|
||||
if err != nil {
|
||||
log.Errorf("%+v", err)
|
||||
return nil, err
|
||||
}
|
||||
return &DockerURL{URL: url}, nil
|
||||
}
|
||||
|
||||
// ParseImage returns an Image struct with all the values filled in for a given image.
|
||||
// example : localhost:5000/nginx:latest, nginx:perl etc.
|
||||
func ParseImage(image string) (Image, error) {
|
||||
func ParseImage(image string) (i Image, err error) {
|
||||
// Parse the image name and tag.
|
||||
named, err := reference.ParseNormalizedNamed(image)
|
||||
if err != nil {
|
||||
@@ -41,7 +62,7 @@ func ParseImage(image string) (Image, error) {
|
||||
// Add the latest lag if they did not provide one.
|
||||
named = reference.TagNameOnly(named)
|
||||
|
||||
i := Image{
|
||||
i = Image{
|
||||
named: named,
|
||||
Domain: reference.Domain(named),
|
||||
Path: reference.Path(named),
|
||||
|
||||
73
pkg/models/registries/image_test.go
Normal file
73
pkg/models/registries/image_test.go
Normal file
@@ -0,0 +1,73 @@
|
||||
package registries
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestParseImage(t *testing.T) {
|
||||
type testImage struct {
|
||||
inputImageName string
|
||||
ExImage Image
|
||||
}
|
||||
|
||||
testImages := []testImage{
|
||||
{inputImageName: "dockerhub.qingcloud.com/kubesphere/test:v1", ExImage: Image{Domain: "dockerhub.qingcloud.com", Tag: "v1", Path: "kubesphere/test"}},
|
||||
{inputImageName: "harbor.devops.kubesphere.local:30280/library/tomcat:latest", ExImage: Image{Domain: "harbor.devops.kubesphere.local:30280", Tag: "latest", Path: "library/tomcat"}},
|
||||
{inputImageName: "zhuxiaoyang/nginx:v1", ExImage: Image{Domain: "docker.io", Tag: "v1", Path: "zhuxiaoyang/nginx"}},
|
||||
{inputImageName: "nginx", ExImage: Image{Domain: "docker.io", Tag: "latest", Path: "library/nginx"}},
|
||||
{inputImageName: "nginx:latest", ExImage: Image{Domain: "docker.io", Tag: "latest", Path: "library/nginx"}},
|
||||
{inputImageName: "kubesphere/ks-account:v2.1.0", ExImage: Image{Domain: "docker.io", Tag: "v2.1.0", Path: "kubesphere/ks-account"}},
|
||||
{inputImageName: "http://docker.io/nginx:latest", ExImage: Image{}},
|
||||
{inputImageName: "https://harbor.devops.kubesphere.local:30280/library/tomcat:latest", ExImage: Image{}},
|
||||
{inputImageName: "docker.io/nginx:latest:latest", ExImage: Image{}},
|
||||
{inputImageName: "nginx:8000:latest", ExImage: Image{}},
|
||||
}
|
||||
|
||||
for _, image := range testImages {
|
||||
res, err := ParseImage(image.inputImageName)
|
||||
if err != nil {
|
||||
if res != image.ExImage {
|
||||
t.Fatalf("Get err %s", err)
|
||||
}
|
||||
}
|
||||
if res.Domain != image.ExImage.Domain {
|
||||
t.Fatalf("Doamin got %v, expected %v", res.Domain, image.ExImage.Domain)
|
||||
}
|
||||
|
||||
if res.Tag != image.ExImage.Tag {
|
||||
t.Fatalf("Tag got %v, expected %v", res.Tag, image.ExImage.Tag)
|
||||
}
|
||||
|
||||
if res.Path != image.ExImage.Path {
|
||||
t.Fatalf("Path got %v, expected %v", res.Path, image.ExImage.Path)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestStringWithoutScheme(t *testing.T) {
|
||||
type testRawUrl struct {
|
||||
Rawurl string
|
||||
ExUrl string
|
||||
}
|
||||
testRawurls := []testRawUrl{
|
||||
{"http://dockerhub.qingcloud.com/kubesphere/nginx:v1", "dockerhub.qingcloud.com/kubesphere/nginx:v1"},
|
||||
{"https://dockerhub.qingcloud.com/kubesphere/nginx:v1", "dockerhub.qingcloud.com/kubesphere/nginx:v1"},
|
||||
{"http://harbor.devops.kubesphere.local:30280/library/tomcat:latest", "harbor.devops.kubesphere.local:30280/library/tomcat:latest"},
|
||||
{"https://harbor.devops.kubesphere.local:30280/library/tomcat:latest", "harbor.devops.kubesphere.local:30280/library/tomcat:latest"},
|
||||
}
|
||||
|
||||
for _, rawurl := range testRawurls {
|
||||
dockerurl, err := ParseDockerURL(rawurl.Rawurl)
|
||||
if err != nil {
|
||||
t.Fatalf("Get err %s", err)
|
||||
}
|
||||
|
||||
imageName := dockerurl.StringWithoutScheme()
|
||||
|
||||
if imageName != rawurl.ExUrl {
|
||||
t.Fatalf("imagename got %v, expected %v", imageName, rawurl.ExUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
func TestDigestFromDockerHub(t *testing.T) {
|
||||
|
||||
testImage := Image{Domain: "docker.io", Path: "library/alpine", Tag: "latest"}
|
||||
r, err := CreateRegistryClient("", "", "docker.io")
|
||||
r, err := CreateRegistryClient("", "", "docker.io", true)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not get client: %s", err)
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ type authService struct {
|
||||
Scope []string
|
||||
}
|
||||
|
||||
func CreateRegistryClient(username, password, domain string) (*Registry, error) {
|
||||
func CreateRegistryClient(username, password, domain string, useSSL bool) (*Registry, error) {
|
||||
authDomain := domain
|
||||
auth, err := GetAuthConfig(username, password, authDomain)
|
||||
if err != nil {
|
||||
@@ -75,6 +75,7 @@ func CreateRegistryClient(username, password, domain string) (*Registry, error)
|
||||
// Create the registry client.
|
||||
return New(auth, RegistryOpt{
|
||||
Domain: domain,
|
||||
UseSSL: useSSL,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
const DockerHub = "docker.io"
|
||||
|
||||
func TestCreateRegistryClient(t *testing.T) {
|
||||
type imageInfo struct {
|
||||
Username string
|
||||
@@ -11,17 +13,19 @@ func TestCreateRegistryClient(t *testing.T) {
|
||||
Domain string
|
||||
ExDomain string
|
||||
ExUrl string
|
||||
UseSSL bool
|
||||
}
|
||||
|
||||
testImages := []imageInfo{
|
||||
{Domain: "kubesphere.io", ExDomain: "kubesphere.io", ExUrl: "http://kubesphere.io"},
|
||||
{Domain: "127.0.0.1:5000", ExDomain: "127.0.0.1:5000", ExUrl: "http://127.0.0.1:5000"},
|
||||
{Username: "Username", Password: "Password", Domain: "docker.io", ExDomain: "registry-1.docker.io", ExUrl: "https://registry-1.docker.io"},
|
||||
{Domain: "harbor.devops.kubesphere.local:30280", ExDomain: "harbor.devops.kubesphere.local:30280", ExUrl: "http://harbor.devops.kubesphere.local:30280"},
|
||||
{Domain: "kubesphere.io", ExDomain: "kubesphere.io", ExUrl: "https://kubesphere.io", UseSSL: true},
|
||||
{Domain: "127.0.0.1:5000", ExDomain: "127.0.0.1:5000", ExUrl: "http://127.0.0.1:5000", UseSSL: false},
|
||||
{Username: "Username", Password: "Password", Domain: DockerHub, ExDomain: "registry-1.docker.io", ExUrl: "https://registry-1.docker.io", UseSSL: true},
|
||||
{Domain: "harbor.devops.kubesphere.local:30280", ExDomain: "harbor.devops.kubesphere.local:30280", ExUrl: "http://harbor.devops.kubesphere.local:30280", UseSSL: false},
|
||||
{Domain: "dockerhub.qingcloud.com/zxytest/s2i-jj:jj", ExDomain: "dockerhub.qingcloud.com", ExUrl: "https://dockerhub.qingcloud.com/zxytest/s2i-jj:jj", UseSSL: true},
|
||||
}
|
||||
|
||||
for _, testImage := range testImages {
|
||||
reg, err := CreateRegistryClient(testImage.Username, testImage.Password, testImage.Domain)
|
||||
reg, err := CreateRegistryClient(testImage.Username, testImage.Password, testImage.Domain, testImage.UseSSL)
|
||||
if err != nil {
|
||||
t.Fatalf("Get err %s", err)
|
||||
}
|
||||
@@ -36,8 +40,8 @@ func TestCreateRegistryClient(t *testing.T) {
|
||||
|
||||
}
|
||||
|
||||
testImage := Image{Domain: "docker.io", Path: "library/alpine", Tag: "latest"}
|
||||
r, err := CreateRegistryClient("", "", "docker.io")
|
||||
testImage := Image{Domain: DockerHub, Path: "library/alpine", Tag: "latest"}
|
||||
r, err := CreateRegistryClient("", "", DockerHub, true)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not get client: %s", err)
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ func (asm authServiceMock) equalTo(v *authService) bool {
|
||||
|
||||
func TestToken(t *testing.T) {
|
||||
testImage := Image{Domain: "docker.io", Path: "library/alpine", Tag: "latest"}
|
||||
r, err := CreateRegistryClient("", "", "docker.io")
|
||||
r, err := CreateRegistryClient("", "", "docker.io", true)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not get registry client: %s", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user