Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-pages.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrzegorz Bizon <grzesiek.bizon@gmail.com>2020-02-12 14:47:36 +0300
committerGrzegorz Bizon <grzesiek.bizon@gmail.com>2020-02-12 14:47:36 +0300
commitefc9707333679aecf36b38f6f53dd0a0e52698eb (patch)
treee9d8df60ac0672b50f78aa050a0d50ef33dedafb
parente3901d4a4e33ce530e4fd85cc2d7af52e5fec7a6 (diff)
Make it possible to fabricate a serverless serving
-rw-r--r--internal/serving/serverless/function.go8
-rw-r--r--internal/serving/serverless/function_test.go6
-rw-r--r--internal/serving/serverless/serverless.go29
-rw-r--r--internal/serving/serverless/serverless_test.go24
-rw-r--r--internal/source/gitlab/api/lookup_path.go10
-rw-r--r--internal/source/gitlab/factory/lookup.go22
-rw-r--r--internal/source/gitlab/factory/serving.go34
-rw-r--r--internal/source/gitlab/gitlab.go22
8 files changed, 118 insertions, 37 deletions
diff --git a/internal/serving/serverless/function.go b/internal/serving/serverless/function.go
index 20d4ec2c..c5d3d179 100644
--- a/internal/serving/serverless/function.go
+++ b/internal/serving/serverless/function.go
@@ -5,14 +5,14 @@ import "strings"
// Function represents a Knative service that is going to be invoked by the
// proxied request
type Function struct {
- Name string // Name is a function name, it includes a "service name" component too
- Namespace string // Namespace is a kubernetes namespace this function has been deployed to
- BaseDomain string // BaseDomain is a cluster base domain, used to route requests to apropriate service
+ Name string // Name is a function name, it includes a "service name" component too
+ Domain string // Domain is a cluster base domain, used to route requests to apropriate service
+ Namespace string // Namespace is a kubernetes namespace this function has been deployed to
}
// Host returns a function address that we are going to expose in the `Host:`
// header to make it possible to route a proxied request to appropriate service
// in a Knative cluster
func (f Function) Host() string {
- return strings.Join([]string{f.Name, f.Namespace, f.BaseDomain}, ".")
+ return strings.Join([]string{f.Name, f.Namespace, f.Domain}, ".")
}
diff --git a/internal/serving/serverless/function_test.go b/internal/serving/serverless/function_test.go
index 65d84eb7..39f86025 100644
--- a/internal/serving/serverless/function_test.go
+++ b/internal/serving/serverless/function_test.go
@@ -8,9 +8,9 @@ import (
func TestFunctionHost(t *testing.T) {
function := Function{
- Name: "my-func",
- Namespace: "my-namespace-123",
- BaseDomain: "knative.example.com",
+ Name: "my-func",
+ Domain: "knative.example.com",
+ Namespace: "my-namespace-123",
}
require.Equal(t, "my-func.my-namespace-123.knative.example.com", function.Host())
diff --git a/internal/serving/serverless/serverless.go b/internal/serving/serverless/serverless.go
index a8d090da..3c360054 100644
--- a/internal/serving/serverless/serverless.go
+++ b/internal/serving/serverless/serverless.go
@@ -1,10 +1,12 @@
package serverless
import (
+ "errors"
"net/http/httputil"
"gitlab.com/gitlab-org/gitlab-pages/internal/httperrors"
"gitlab.com/gitlab-org/gitlab-pages/internal/serving"
+ "gitlab.com/gitlab-org/gitlab-pages/internal/source/gitlab/api"
)
// Serverless is a servering used to proxy requests between a client and
@@ -13,6 +15,33 @@ type Serverless struct {
proxy *httputil.ReverseProxy
}
+// NewFromAPISource returns a serverless serving instance built from GitLab API
+// response
+func NewFromAPISource(config api.Serverless) (serving.Serving, error) {
+ function := Function(config.Function)
+
+ if len(function.Name) == 0 {
+ return nil, errors.New("incomplete serverless serving config")
+ }
+
+ certs, err := NewClusterCerts(
+ config.Cluster.CertificateCert,
+ config.Cluster.CertificateKey,
+ )
+ if err != nil {
+ return nil, err
+ }
+
+ cluster := Cluster{
+ Name: config.Cluster.Hostname,
+ Address: config.Cluster.Address,
+ Port: config.Cluster.Port,
+ Certs: certs,
+ }
+
+ return New(function, cluster), nil
+}
+
// New returns a new serving instance
func New(function Function, cluster Cluster) serving.Serving {
proxy := httputil.ReverseProxy{
diff --git a/internal/serving/serverless/serverless_test.go b/internal/serving/serverless/serverless_test.go
index c330cbda..2dd933cc 100644
--- a/internal/serving/serverless/serverless_test.go
+++ b/internal/serving/serverless/serverless_test.go
@@ -40,9 +40,9 @@ func TestServeFileHTTP(t *testing.T) {
withTestCluster(t, fixture.Certificate, fixture.Key, func(mux *http.ServeMux, server *url.URL, certs *Certs) {
serverless := New(
Function{
- Name: "my-func",
- Namespace: "my-namespace-123",
- BaseDomain: "knative.example.com",
+ Name: "my-func",
+ Namespace: "my-namespace-123",
+ Domain: "knative.example.com",
},
Cluster{
Name: "knative.gitlab-example.com",
@@ -76,9 +76,9 @@ func TestServeFileHTTP(t *testing.T) {
withTestCluster(t, fixture.Certificate, fixture.Key, func(mux *http.ServeMux, server *url.URL, certs *Certs) {
serverless := New(
Function{
- Name: "my-func",
- Namespace: "my-namespace-123",
- BaseDomain: "knative.example.com",
+ Name: "my-func",
+ Namespace: "my-namespace-123",
+ Domain: "knative.example.com",
},
Cluster{
Name: "knative.invalid-gitlab-example.com",
@@ -111,9 +111,9 @@ func TestServeFileHTTP(t *testing.T) {
withTestCluster(t, fixture.Certificate, fixture.Key, func(mux *http.ServeMux, server *url.URL, certs *Certs) {
serverless := New(
Function{
- Name: "my-func",
- Namespace: "my-namespace-123",
- BaseDomain: "knative.example.com",
+ Name: "my-func",
+ Namespace: "my-namespace-123",
+ Domain: "knative.example.com",
},
Cluster{
Name: "knative.gitlab-example.com",
@@ -147,9 +147,9 @@ func TestServeFileHTTP(t *testing.T) {
withTestCluster(t, fixture.Certificate, fixture.Key, func(mux *http.ServeMux, server *url.URL, certs *Certs) {
serverless := New(
Function{
- Name: "my-func",
- Namespace: "my-namespace-123",
- BaseDomain: "knative.example.com",
+ Name: "my-func",
+ Namespace: "my-namespace-123",
+ Domain: "knative.example.com",
},
Cluster{
Name: "knative.gitlab-example.com",
diff --git a/internal/source/gitlab/api/lookup_path.go b/internal/source/gitlab/api/lookup_path.go
index e9c0038d..de200e37 100644
--- a/internal/source/gitlab/api/lookup_path.go
+++ b/internal/source/gitlab/api/lookup_path.go
@@ -6,16 +6,18 @@ type LookupPath struct {
AccessControl bool `json:"access_control,omitempty"`
HTTPSOnly bool `json:"https_only,omitempty"`
Prefix string `json:"prefix,omitempty"`
- Source source `json:"source,omitempty"`
+ Source Source `json:"source,omitempty"`
}
-type source struct {
+// Source describes GitLab Page serving variant
+type Source struct {
Type string `json:"type,omitempty"`
Path string `json:"path,omitempty"`
- Serverless serverless `json:"serverless,omitempty"`
+ Serverless Serverless `json:"serverless,omitempty"`
}
-type serverless struct {
+// Serverless describeg serverless serving configuration
+type Serverless struct {
Function function `json:"function,omitempty"`
Cluster cluster `json:"cluster,omitempty"`
}
diff --git a/internal/source/gitlab/factory/lookup.go b/internal/source/gitlab/factory/lookup.go
new file mode 100644
index 00000000..71bb24bc
--- /dev/null
+++ b/internal/source/gitlab/factory/lookup.go
@@ -0,0 +1,22 @@
+package factory
+
+import (
+ "strings"
+
+ "gitlab.com/gitlab-org/gitlab-pages/internal/serving"
+ "gitlab.com/gitlab-org/gitlab-pages/internal/source/gitlab/api"
+)
+
+// LookupPath fabricates a serving LookupPath based on the API LookupPath
+// `size` argument is DEPRECATED, see
+// https://gitlab.com/gitlab-org/gitlab-pages/issues/272
+func LookupPath(size int, lookup api.LookupPath) *serving.LookupPath {
+ return &serving.LookupPath{
+ Prefix: lookup.Prefix,
+ Path: strings.TrimPrefix(lookup.Source.Path, "/"),
+ IsNamespaceProject: (lookup.Prefix == "/" && size > 1),
+ IsHTTPSOnly: lookup.HTTPSOnly,
+ HasAccessControl: lookup.AccessControl,
+ ProjectID: uint64(lookup.ProjectID),
+ }
+}
diff --git a/internal/source/gitlab/factory/serving.go b/internal/source/gitlab/factory/serving.go
new file mode 100644
index 00000000..22b99bc1
--- /dev/null
+++ b/internal/source/gitlab/factory/serving.go
@@ -0,0 +1,34 @@
+package factory
+
+import (
+ "gitlab.com/gitlab-org/gitlab-pages/internal/serving"
+ "gitlab.com/gitlab-org/gitlab-pages/internal/serving/disk"
+ "gitlab.com/gitlab-org/gitlab-pages/internal/serving/serverless"
+ "gitlab.com/gitlab-org/gitlab-pages/internal/source/gitlab/api"
+)
+
+// Serving fabricates serving based on the GitLab API response
+func Serving(lookup api.LookupPath) serving.Serving {
+ source := lookup.Source
+
+ switch source.Type {
+ case "file":
+ return disk.New()
+ case "serverless":
+ serving, err := serverless.NewFromAPISource(source.Serverless)
+ if err != nil {
+ break
+ }
+
+ return serving
+ }
+
+ return DefaultServing()
+}
+
+// DefaultServing returns a serving that we will use as a default one, for
+// example to show an error, if API response does not allow us to properly
+// fabricate a serving
+func DefaultServing() serving.Serving {
+ return disk.New()
+}
diff --git a/internal/source/gitlab/gitlab.go b/internal/source/gitlab/gitlab.go
index 232239ae..67198232 100644
--- a/internal/source/gitlab/gitlab.go
+++ b/internal/source/gitlab/gitlab.go
@@ -10,10 +10,10 @@ import (
"gitlab.com/gitlab-org/gitlab-pages/internal/domain"
"gitlab.com/gitlab-org/gitlab-pages/internal/request"
"gitlab.com/gitlab-org/gitlab-pages/internal/serving"
- "gitlab.com/gitlab-org/gitlab-pages/internal/serving/disk"
"gitlab.com/gitlab-org/gitlab-pages/internal/source/gitlab/api"
"gitlab.com/gitlab-org/gitlab-pages/internal/source/gitlab/cache"
"gitlab.com/gitlab-org/gitlab-pages/internal/source/gitlab/client"
+ "gitlab.com/gitlab-org/gitlab-pages/internal/source/gitlab/factory"
)
// Gitlab source represent a new domains configuration source. We fetch all the
@@ -46,6 +46,8 @@ func (g *Gitlab) GetDomain(name string) (*domain.Domain, error) {
return nil, nil
}
+ // TODO introduce a second-level cache for domains, invalidate using etags
+ // from first-level cache
domain := domain.Domain{
Name: name,
CertificateCert: lookup.Domain.Certificate,
@@ -68,33 +70,25 @@ func (g *Gitlab) Resolve(r *http.Request) (*serving.Request, error) {
}
urlPath := path.Clean(r.URL.Path)
- lookups := len(response.Domain.LookupPaths)
+ size := len(response.Domain.LookupPaths)
for _, lookup := range response.Domain.LookupPaths {
isSubPath := strings.HasPrefix(urlPath, lookup.Prefix)
isRootPath := urlPath == path.Clean(lookup.Prefix)
if isSubPath || isRootPath {
- lookupPath := &serving.LookupPath{
- Prefix: lookup.Prefix,
- Path: strings.TrimPrefix(lookup.Source.Path, "/"),
- IsNamespaceProject: (lookup.Prefix == "/" && lookups > 1),
- IsHTTPSOnly: lookup.HTTPSOnly,
- HasAccessControl: lookup.AccessControl,
- ProjectID: uint64(lookup.ProjectID),
- }
-
subPath := ""
if isSubPath {
subPath = strings.TrimPrefix(urlPath, lookup.Prefix)
}
return &serving.Request{
- Serving: disk.New(),
- LookupPath: lookupPath,
+ Serving: factory.Serving(lookup),
+ LookupPath: factory.LookupPath(size, lookup),
SubPath: subPath}, nil
}
}
- return &serving.Request{Serving: disk.New()}, errors.New("could not match lookup path")
+ return &serving.Request{Serving: factory.DefaultServing()},
+ errors.New("could not match lookup path")
}