diff --git a/deployment/monocular/Chart.yaml b/deployment/monocular/Chart.yaml index 9b9ff2d70..1d2715664 100644 --- a/deployment/monocular/Chart.yaml +++ b/deployment/monocular/Chart.yaml @@ -1,4 +1,11 @@ apiVersion: v1 -description: Monocular is a search and discovery front end for Helm Charts Repositories. name: monocular -version: 0.2.0 +description: Monocular is a search and discovery front end for Helm Charts Repositories. +version: 0.3.0 +appVersion: 0.2.0 +home: https://github.com/helm/monocular +sources: +- https://github.com/helm/monocular +maintainers: +- name: prydonius + email: adnan@bitnami.com diff --git a/deployment/monocular/templates/ui-config.yaml b/deployment/monocular/templates/ui-config.yaml index 37702e1db..c11e06f49 100644 --- a/deployment/monocular/templates/ui-config.yaml +++ b/deployment/monocular/templates/ui-config.yaml @@ -13,6 +13,9 @@ data: overrides: { googleAnalyticsId: '{{.Values.ui.googleAnalyticsId}}', appName: '{{.Values.ui.appName}}', + {{- if .Values.ui.backendHostname }} + backendHostname: '{{ .Values.ui.backendHostname }}', + {{- end }} releasesEnabled: {{.Values.api.config.releasesEnabled}} } }; diff --git a/deployment/monocular/templates/ui-vhost.yaml b/deployment/monocular/templates/ui-vhost.yaml index 79e8e4547..b1d720c2f 100644 --- a/deployment/monocular/templates/ui-vhost.yaml +++ b/deployment/monocular/templates/ui-vhost.yaml @@ -14,8 +14,8 @@ data: } server { - listen 80; - + listen {{ .Values.ui.service.internalPort }}; + gzip on; # Angular CLI already has gzipped the assets (ng build --prod --aot) gzip_static on; diff --git a/deployment/monocular/values.yaml b/deployment/monocular/values.yaml index 9507a2f6d..7795b8f6c 100644 --- a/deployment/monocular/values.yaml +++ b/deployment/monocular/values.yaml @@ -34,11 +34,16 @@ api: #- name: my-repo-name # url: my-repository-url # source: my-repository-source + cors: + allowed_origins: + - my-api-server + allowed_headers: + - "access-control-allow-headers" + - "x-xsrf-token" # Enable Helm deployment integration releasesEnabled: false # Cache refresh interval in sec. cacheRefreshInterval: 3600 - ui: replicaCount: 2 image: @@ -60,13 +65,14 @@ ui: # ui-config populate googleAnalyticsId: UA-XXXXXX-X appName: Monocular + # backendHostname: http://monocular-api.local prerender: replicaCount: 1 image: repository: migmartri/prerender - tag: 0.1 - pullPolicy: IfNotPresent + tag: latest + pullPolicy: Always cacheEnabled: true service: name: prerender diff --git a/docs/config.example.yaml b/docs/config.example.yaml index 5938638c1..2ee1adbfd 100644 --- a/docs/config.example.yaml +++ b/docs/config.example.yaml @@ -13,6 +13,13 @@ repos: # url: my-repository-url # source: my-repository-source +cors: + allowed_origins: + - my-api-server + allowed_headers: + - "access-control-allow-headers" + - "x-xsrf-token" + # Enables Helm deployment integration # https://github.com/helm/monocular/blob/master/docs/configuration.md#enable-helm-releases-integration releasesEnabled: true diff --git a/src/api/config/cors/cors.go b/src/api/config/cors/cors.go index 45e3b858a..d2cd44d2b 100644 --- a/src/api/config/cors/cors.go +++ b/src/api/config/cors/cors.go @@ -1,21 +1,25 @@ package cors -import "os" +import ( + "io/ioutil" + "os" -// Cors configuration used during middleware setup -type Cors struct { - AllowedOrigins []string - AllowedHeaders []string + log "github.com/Sirupsen/logrus" + yaml "gopkg.in/yaml.v2" +) + +type corsYAML struct { + Cors Cors } -var currentEnv = func() string { - return os.Getenv("ENVIRONMENT") +// Cors configuration used during middleware setup +type Cors struct { + AllowedOrigins []string `yaml:"allowed_origins"` + AllowedHeaders []string `yaml:"allowed_headers"` } -// Config returns the CORS configuration for the environment -// TODO, read the configuration from the overrides config file argument -func Config(configFile string) (Cors, error) { - env := currentEnv() +func defaultCors() (Cors, error) { + env := os.Getenv("ENVIRONMENT") if env == "development" { return Cors{ AllowedOrigins: []string{"*"}, @@ -27,3 +31,36 @@ func Config(configFile string) (Cors, error) { AllowedHeaders: []string{"access-control-allow-headers", "x-xsrf-token"}, }, nil } + +// Config returns the CORS configuration for the environment +func Config(configFile string) (Cors, error) { + _, err := os.Stat(configFile) + if os.IsNotExist(err) { + log.Info("Loading default repositories") + return defaultCors() + } + + log.Info("Loading repositories from config file") + cors, err := loadCorsFromFile(configFile) + if err != nil { + return Cors{}, err + } + + if len(cors.AllowedOrigins) == 0 && len(cors.AllowedHeaders) == 0 { + return defaultCors() + } + + return cors, nil +} + +func loadCorsFromFile(filePath string) (Cors, error) { + var yamlStruct corsYAML + bytes, err := ioutil.ReadFile(filePath) + if err != nil { + return Cors{}, err + } + if err := yaml.Unmarshal(bytes, &yamlStruct); err != nil { + return Cors{}, err + } + return yamlStruct.Cors, nil +} diff --git a/src/api/config/cors/cors_test.go b/src/api/config/cors/cors_test.go index 5b2e9d9d0..2f9876d1d 100644 --- a/src/api/config/cors/cors_test.go +++ b/src/api/config/cors/cors_test.go @@ -1,30 +1,63 @@ package cors import ( + "os" + "path/filepath" "testing" "github.com/arschles/assert" ) -func TestConfig(t *testing.T) { - var headers = []string{"access-control-allow-headers", "x-xsrf-token"} - var origin = []string{"my-api-server"} +var configFileOk = filepath.Join("..", "testdata", "config.yaml") +var configFileNotOk = filepath.Join("..", "testdata", "bogus_config.yaml") +var configFileNoCors = filepath.Join("..", "testdata", "nocors_config.yaml") +var defaultExpectedCors = Cors{ + AllowedOrigins: []string{"my-api-server"}, + AllowedHeaders: []string{"access-control-allow-headers", "x-xsrf-token"}, +} + +func TestConfigFileDoesNotExist(t *testing.T) { config, err := Config("no-file") assert.NoErr(t, err) - assert.Equal(t, config.AllowedHeaders, headers, "Allowed headers") - assert.Equal(t, config.AllowedOrigins, origin, "Default origin") + assert.Equal(t, config.AllowedHeaders, defaultExpectedCors.AllowedHeaders, "Allowed headers") + assert.Equal(t, config.AllowedOrigins, defaultExpectedCors.AllowedOrigins, "Default origin") } // In development environment, CORS has a permissive configuration -func TestConfigDevelopment(t *testing.T) { - origCurrentEnv := currentEnv - currentEnv = func() string { - return "development" - } - defer func() { currentEnv = origCurrentEnv }() +func TestConfigFileDoesNotExistDevelopment(t *testing.T) { + os.Setenv("ENVIRONMENT", "development") + defer func() { os.Unsetenv("ENVIRONMENT") }() var origin = []string{"*"} config, err := Config("no-file") assert.NoErr(t, err) assert.Equal(t, len(config.AllowedHeaders), 0, "Allowed headers") assert.Equal(t, config.AllowedOrigins, origin, "Default origin") } + +func TestConfigFileWithoutCors(t *testing.T) { + cors, err := Config(configFileNoCors) + assert.NoErr(t, err) + assert.Equal(t, cors, defaultExpectedCors, "It returns the default CORS") +} + +func TestConfigFromFile(t *testing.T) { + expected := Cors{ + AllowedOrigins: []string{"http://mymonocular"}, + AllowedHeaders: []string{"access-control-allow-headers", "x-xsrf-token"}, + } + cors, err := Config(configFileOk) + assert.NoErr(t, err) + assert.Equal(t, cors, expected, "It uses the cors from the config file") +} + +// Return err +func TestConfigFromFileInvalid(t *testing.T) { + _, err := Config(configFileNotOk) + assert.ExistsErr(t, err, "File exist but it is not valid") +} + +func TestLoadCorsFromFileDoesNotExist(t *testing.T) { + cors, err := loadCorsFromFile("does not exist") + assert.ExistsErr(t, err, "Can not load the file") + assert.Equal(t, cors, Cors{}, "Returns no cors") +} diff --git a/src/api/config/testdata/bogus_config.yaml b/src/api/config/testdata/bogus_config.yaml index e46a68fe2..cef8da931 100644 --- a/src/api/config/testdata/bogus_config.yaml +++ b/src/api/config/testdata/bogus_config.yaml @@ -1,3 +1,5 @@ repos: - foo - bar +cors: + - foobar diff --git a/src/api/config/testdata/config.yaml b/src/api/config/testdata/config.yaml index c2b3abd1b..92cf1672e 100644 --- a/src/api/config/testdata/config.yaml +++ b/src/api/config/testdata/config.yaml @@ -4,5 +4,11 @@ repos: source: http://github.com/my-repo - name: repoName2 url: http://myrepobucket2 +cors: + allowed_origins: + - "http://mymonocular" + allowed_headers: + - "access-control-allow-headers" + - "x-xsrf-token" releasesEnabled: true -cacheRefreshInterval: 3600 \ No newline at end of file +cacheRefreshInterval: 3600 diff --git a/src/api/config/testdata/nocors_config.yaml b/src/api/config/testdata/nocors_config.yaml new file mode 100644 index 000000000..62f0702de --- /dev/null +++ b/src/api/config/testdata/nocors_config.yaml @@ -0,0 +1 @@ +otheroption: foo