Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
74a89b1221
commit
427c549b63
33 changed files with 263 additions and 265 deletions
|
@ -222,9 +222,6 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
|
||||||
elasticStackInstalled() {
|
elasticStackInstalled() {
|
||||||
return this.applications.elastic_stack.status === APPLICATION_STATUS.INSTALLED;
|
return this.applications.elastic_stack.status === APPLICATION_STATUS.INSTALLED;
|
||||||
},
|
},
|
||||||
elasticStackKibanaHostname() {
|
|
||||||
return this.applications.elastic_stack.kibana_hostname;
|
|
||||||
},
|
|
||||||
knative() {
|
knative() {
|
||||||
return this.applications.knative;
|
return this.applications.knative;
|
||||||
},
|
},
|
||||||
|
@ -681,9 +678,6 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
|
||||||
:uninstall-successful="applications.elastic_stack.uninstallSuccessful"
|
:uninstall-successful="applications.elastic_stack.uninstallSuccessful"
|
||||||
:uninstall-failed="applications.elastic_stack.uninstallFailed"
|
:uninstall-failed="applications.elastic_stack.uninstallFailed"
|
||||||
:disabled="!helmInstalled"
|
:disabled="!helmInstalled"
|
||||||
:install-application-request-params="{
|
|
||||||
kibana_hostname: applications.elastic_stack.kibana_hostname,
|
|
||||||
}"
|
|
||||||
title-link="https://github.com/helm/charts/tree/master/stable/elastic-stack"
|
title-link="https://github.com/helm/charts/tree/master/stable/elastic-stack"
|
||||||
>
|
>
|
||||||
<div slot="description">
|
<div slot="description">
|
||||||
|
@ -694,40 +688,6 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<template v-if="ingressExternalEndpoint">
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="elastic-stack-kibana-hostname">{{
|
|
||||||
s__('ClusterIntegration|Kibana Hostname')
|
|
||||||
}}</label>
|
|
||||||
|
|
||||||
<div class="input-group">
|
|
||||||
<input
|
|
||||||
v-model="applications.elastic_stack.kibana_hostname"
|
|
||||||
:readonly="elasticStackInstalled"
|
|
||||||
type="text"
|
|
||||||
class="form-control js-hostname"
|
|
||||||
/>
|
|
||||||
<span class="input-group-btn">
|
|
||||||
<clipboard-button
|
|
||||||
:text="elasticStackKibanaHostname"
|
|
||||||
:title="s__('ClusterIntegration|Copy Kibana Hostname')"
|
|
||||||
class="js-clipboard-btn"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p v-if="ingressInstalled" class="form-text text-muted">
|
|
||||||
{{
|
|
||||||
s__(`ClusterIntegration|Replace this with your own hostname if you want.
|
|
||||||
If you do so, point hostname to Ingress IP Address from above.`)
|
|
||||||
}}
|
|
||||||
<a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer">
|
|
||||||
{{ __('More information') }}
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</div>
|
</div>
|
||||||
</application-row>
|
</application-row>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,7 +5,6 @@ import {
|
||||||
JUPYTER,
|
JUPYTER,
|
||||||
KNATIVE,
|
KNATIVE,
|
||||||
CERT_MANAGER,
|
CERT_MANAGER,
|
||||||
ELASTIC_STACK,
|
|
||||||
CROSSPLANE,
|
CROSSPLANE,
|
||||||
RUNNER,
|
RUNNER,
|
||||||
APPLICATION_INSTALLED_STATUSES,
|
APPLICATION_INSTALLED_STATUSES,
|
||||||
|
@ -97,7 +96,6 @@ export default class ClusterStore {
|
||||||
elastic_stack: {
|
elastic_stack: {
|
||||||
...applicationInitialState,
|
...applicationInitialState,
|
||||||
title: s__('ClusterIntegration|Elastic Stack'),
|
title: s__('ClusterIntegration|Elastic Stack'),
|
||||||
kibana_hostname: null,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
environments: [],
|
environments: [],
|
||||||
|
@ -236,12 +234,6 @@ export default class ClusterStore {
|
||||||
} else if (appId === RUNNER) {
|
} else if (appId === RUNNER) {
|
||||||
this.state.applications.runner.version = version;
|
this.state.applications.runner.version = version;
|
||||||
this.state.applications.runner.updateAvailable = updateAvailable;
|
this.state.applications.runner.updateAvailable = updateAvailable;
|
||||||
} else if (appId === ELASTIC_STACK) {
|
|
||||||
this.state.applications.elastic_stack.kibana_hostname = this.updateHostnameIfUnset(
|
|
||||||
this.state.applications.elastic_stack.kibana_hostname,
|
|
||||||
serverAppEntry.kibana_hostname,
|
|
||||||
'kibana',
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,12 @@ export default {
|
||||||
<div role="rowheader" class="table-mobile-header">{{ s__('DeployKeys|Deploy key') }}</div>
|
<div role="rowheader" class="table-mobile-header">{{ s__('DeployKeys|Deploy key') }}</div>
|
||||||
<div class="table-mobile-content qa-key">
|
<div class="table-mobile-content qa-key">
|
||||||
<strong class="title qa-key-title"> {{ deployKey.title }} </strong>
|
<strong class="title qa-key-title"> {{ deployKey.title }} </strong>
|
||||||
<div class="fingerprint qa-key-fingerprint">{{ deployKey.fingerprint }}</div>
|
<div class="fingerprint qa-key-fingerprint">
|
||||||
|
{{ __('MD5') }}:{{ deployKey.fingerprint }}
|
||||||
|
</div>
|
||||||
|
<div class="fingerprint qa-key-fingerprint">
|
||||||
|
{{ __('SHA256') }}:{{ deployKey.fingerprint_sha256 }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="table-section section-30 section-wrap">
|
<div class="table-section section-30 section-wrap">
|
||||||
|
|
|
@ -47,7 +47,7 @@ class Clusters::ApplicationsController < Clusters::BaseController
|
||||||
end
|
end
|
||||||
|
|
||||||
def cluster_application_params
|
def cluster_application_params
|
||||||
params.permit(:application, :hostname, :kibana_hostname, :email, :stack, :modsecurity_enabled)
|
params.permit(:application, :hostname, :email, :stack, :modsecurity_enabled)
|
||||||
end
|
end
|
||||||
|
|
||||||
def cluster_application_destroy_params
|
def cluster_application_destroy_params
|
||||||
|
|
|
@ -15,24 +15,15 @@ module Clusters
|
||||||
include ::Clusters::Concerns::ApplicationData
|
include ::Clusters::Concerns::ApplicationData
|
||||||
include ::Gitlab::Utils::StrongMemoize
|
include ::Gitlab::Utils::StrongMemoize
|
||||||
|
|
||||||
|
include IgnorableColumns
|
||||||
|
ignore_column :kibana_hostname, remove_with: '12.8', remove_after: '2020-01-22'
|
||||||
|
|
||||||
default_value_for :version, VERSION
|
default_value_for :version, VERSION
|
||||||
|
|
||||||
def set_initial_status
|
|
||||||
return unless not_installable?
|
|
||||||
return unless cluster&.application_ingress_available?
|
|
||||||
|
|
||||||
ingress = cluster.application_ingress
|
|
||||||
self.status = status_states[:installable] if ingress.external_ip_or_hostname?
|
|
||||||
end
|
|
||||||
|
|
||||||
def chart
|
def chart
|
||||||
'stable/elastic-stack'
|
'stable/elastic-stack'
|
||||||
end
|
end
|
||||||
|
|
||||||
def values
|
|
||||||
content_values.to_yaml
|
|
||||||
end
|
|
||||||
|
|
||||||
def install_command
|
def install_command
|
||||||
Gitlab::Kubernetes::Helm::InstallCommand.new(
|
Gitlab::Kubernetes::Helm::InstallCommand.new(
|
||||||
name: 'elastic-stack',
|
name: 'elastic-stack',
|
||||||
|
@ -78,24 +69,6 @@ module Clusters
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def specification
|
|
||||||
{
|
|
||||||
"kibana" => {
|
|
||||||
"ingress" => {
|
|
||||||
"hosts" => [kibana_hostname],
|
|
||||||
"tls" => [{
|
|
||||||
"hosts" => [kibana_hostname],
|
|
||||||
"secretName" => "kibana-cert"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def content_values
|
|
||||||
YAML.load_file(chart_values_file).deep_merge!(specification)
|
|
||||||
end
|
|
||||||
|
|
||||||
def post_delete_script
|
def post_delete_script
|
||||||
[
|
[
|
||||||
Gitlab::Kubernetes::KubectlCmd.delete("pvc", "--selector", "release=elastic-stack")
|
Gitlab::Kubernetes::KubectlCmd.delete("pvc", "--selector", "release=elastic-stack")
|
||||||
|
|
|
@ -42,7 +42,7 @@ module Clusters
|
||||||
end
|
end
|
||||||
|
|
||||||
def allowed_to_uninstall?
|
def allowed_to_uninstall?
|
||||||
external_ip_or_hostname? && application_jupyter_nil_or_installable? && application_elastic_stack_nil_or_installable?
|
external_ip_or_hostname? && application_jupyter_nil_or_installable?
|
||||||
end
|
end
|
||||||
|
|
||||||
def install_command
|
def install_command
|
||||||
|
@ -155,10 +155,6 @@ module Clusters
|
||||||
def application_jupyter_nil_or_installable?
|
def application_jupyter_nil_or_installable?
|
||||||
cluster.application_jupyter.nil? || cluster.application_jupyter&.installable?
|
cluster.application_jupyter.nil? || cluster.application_jupyter&.installable?
|
||||||
end
|
end
|
||||||
|
|
||||||
def application_elastic_stack_nil_or_installable?
|
|
||||||
cluster.application_elastic_stack.nil? || cluster.application_elastic_stack&.installable?
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,7 +8,6 @@ class ClusterApplicationEntity < Grape::Entity
|
||||||
expose :external_ip, if: -> (e, _) { e.respond_to?(:external_ip) }
|
expose :external_ip, if: -> (e, _) { e.respond_to?(:external_ip) }
|
||||||
expose :external_hostname, if: -> (e, _) { e.respond_to?(:external_hostname) }
|
expose :external_hostname, if: -> (e, _) { e.respond_to?(:external_hostname) }
|
||||||
expose :hostname, if: -> (e, _) { e.respond_to?(:hostname) }
|
expose :hostname, if: -> (e, _) { e.respond_to?(:hostname) }
|
||||||
expose :kibana_hostname, if: -> (e, _) { e.respond_to?(:kibana_hostname) }
|
|
||||||
expose :email, if: -> (e, _) { e.respond_to?(:email) }
|
expose :email, if: -> (e, _) { e.respond_to?(:email) }
|
||||||
expose :stack, if: -> (e, _) { e.respond_to?(:stack) }
|
expose :stack, if: -> (e, _) { e.respond_to?(:stack) }
|
||||||
expose :modsecurity_enabled, if: -> (e, _) { e.respond_to?(:modsecurity_enabled) }
|
expose :modsecurity_enabled, if: -> (e, _) { e.respond_to?(:modsecurity_enabled) }
|
||||||
|
|
|
@ -5,6 +5,7 @@ class DeployKeyEntity < Grape::Entity
|
||||||
expose :user_id
|
expose :user_id
|
||||||
expose :title
|
expose :title
|
||||||
expose :fingerprint
|
expose :fingerprint
|
||||||
|
expose :fingerprint_sha256
|
||||||
expose :destroyed_when_orphaned?, as: :destroyed_when_orphaned
|
expose :destroyed_when_orphaned?, as: :destroyed_when_orphaned
|
||||||
expose :almost_orphaned?, as: :almost_orphaned
|
expose :almost_orphaned?, as: :almost_orphaned
|
||||||
expose :created_at
|
expose :created_at
|
||||||
|
|
|
@ -19,10 +19,6 @@ module Clusters
|
||||||
application.hostname = params[:hostname]
|
application.hostname = params[:hostname]
|
||||||
end
|
end
|
||||||
|
|
||||||
if application.has_attribute?(:kibana_hostname)
|
|
||||||
application.kibana_hostname = params[:kibana_hostname]
|
|
||||||
end
|
|
||||||
|
|
||||||
if application.has_attribute?(:email)
|
if application.has_attribute?(:email)
|
||||||
application.email = params[:email]
|
application.email = params[:email]
|
||||||
end
|
end
|
||||||
|
|
5
changelogs/unreleased/feat-ssh-sha256-other-key.yml
Normal file
5
changelogs/unreleased/feat-ssh-sha256-other-key.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Display SHA fingerprint for Deploy Keys and extend api to query those
|
||||||
|
merge_request: 22665
|
||||||
|
author: Roger Meier <r.meier@siemens.com>
|
||||||
|
type: added
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Add informational message about page limits to environments dashboard
|
||||||
|
merge_request: 22489
|
||||||
|
author:
|
||||||
|
type: added
|
|
@ -128,3 +128,65 @@ Example response:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Deploy Keys are bound to the creating user, so if you query with a deploy key
|
||||||
|
fingerprint you get additional information about the projects using that key:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
curl --header "PRIVATE-TOKEN: <your_access_token>" 'https://gitlab.example.com/api/v4/keys?fingerprint=SHA256%3AnUhzNyftwADy8AH3wFY31tAKs7HufskYTte2aXo%2FlCg
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"title": "Sample key 1",
|
||||||
|
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt1016k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=",
|
||||||
|
"created_at": "2019-11-14T15:11:13.222Z",
|
||||||
|
"user": {
|
||||||
|
"id": 1,
|
||||||
|
"name": "Administrator",
|
||||||
|
"username": "root",
|
||||||
|
"state": "active",
|
||||||
|
"avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon",
|
||||||
|
"web_url": "http://0.0.0.0:3000/root",
|
||||||
|
"created_at": "2019-11-14T15:09:34.831Z",
|
||||||
|
"bio": null,
|
||||||
|
"location": null,
|
||||||
|
"public_email": "",
|
||||||
|
"skype": "",
|
||||||
|
"linkedin": "",
|
||||||
|
"twitter": "",
|
||||||
|
"website_url": "",
|
||||||
|
"organization": null,
|
||||||
|
"last_sign_in_at": "2019-11-16T22:41:26.663Z",
|
||||||
|
"confirmed_at": "2019-11-14T15:09:34.575Z",
|
||||||
|
"last_activity_on": "2019-11-20",
|
||||||
|
"email": "admin@example.com",
|
||||||
|
"theme_id": 1,
|
||||||
|
"color_scheme_id": 1,
|
||||||
|
"projects_limit": 100000,
|
||||||
|
"current_sign_in_at": "2019-11-19T14:42:18.078Z",
|
||||||
|
"identities": [
|
||||||
|
],
|
||||||
|
"can_create_group": true,
|
||||||
|
"can_create_project": true,
|
||||||
|
"two_factor_enabled": false,
|
||||||
|
"external": false,
|
||||||
|
"private_profile": false,
|
||||||
|
"shared_runners_minutes_limit": null,
|
||||||
|
"extra_shared_runners_minutes_limit": null
|
||||||
|
},
|
||||||
|
"deploy_keys_projects": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"deploy_key_id": 1,
|
||||||
|
"project_id": 1,
|
||||||
|
"created_at": "2020-01-09T07:32:52.453Z",
|
||||||
|
"updated_at": "2020-01-09T07:32:52.453Z",
|
||||||
|
"can_push": false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
|
@ -15,7 +15,9 @@ should be leveraged:
|
||||||
- Feature flags should remain in the codebase for as short period as possible
|
- Feature flags should remain in the codebase for as short period as possible
|
||||||
to reduce the need for feature flag accounting.
|
to reduce the need for feature flag accounting.
|
||||||
- The person operating with feature flags is responsible for clearly communicating
|
- The person operating with feature flags is responsible for clearly communicating
|
||||||
the status of a feature behind the feature flag with responsible stakeholders.
|
the status of a feature behind the feature flag with responsible stakeholders. The
|
||||||
|
issue description should be updated with the feature flag name and whether it is
|
||||||
|
defaulted on or off as soon it is evident that a feature flag is needed.
|
||||||
- Merge requests that make changes hidden behind a feature flag, or remove an
|
- Merge requests that make changes hidden behind a feature flag, or remove an
|
||||||
existing feature flag because a feature is deemed stable must have the
|
existing feature flag because a feature is deemed stable must have the
|
||||||
~"feature flag" label assigned.
|
~"feature flag" label assigned.
|
||||||
|
|
|
@ -41,6 +41,7 @@ The following applications can be installed:
|
||||||
- [JupyterHub](#jupyterhub)
|
- [JupyterHub](#jupyterhub)
|
||||||
- [Knative](#knative)
|
- [Knative](#knative)
|
||||||
- [Crossplane](#crossplane)
|
- [Crossplane](#crossplane)
|
||||||
|
- [Elastic Stack](#elastic-stack)
|
||||||
|
|
||||||
With the exception of Knative, the applications will be installed in a dedicated
|
With the exception of Knative, the applications will be installed in a dedicated
|
||||||
namespace called `gitlab-managed-apps`.
|
namespace called `gitlab-managed-apps`.
|
||||||
|
@ -431,6 +432,38 @@ administrator to run following command within a Rails console:
|
||||||
Feature.enable(:enable_cluster_application_crossplane)
|
Feature.enable(:enable_cluster_application_crossplane)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Elastic Stack
|
||||||
|
|
||||||
|
> Introduced in GitLab 12.7 for project- and group-level clusters.
|
||||||
|
|
||||||
|
[Elastic Stack](https://www.elastic.co/products/elastic-stack) is a complete end-to-end
|
||||||
|
log analysis solution which helps in deep searching, analyzing and visualizing the logs
|
||||||
|
generated from different machines.
|
||||||
|
|
||||||
|
GitLab is able to gather logs from pods in your cluster automatically.
|
||||||
|
Filebeat will run as a DaemonSet on each node in your cluster, and it will ship container logs to Elasticsearch for querying.
|
||||||
|
GitLab will then connect to Elasticsearch for logs instead of the Kubernetes API,
|
||||||
|
and you will have access to more advanced querying capabilities.
|
||||||
|
|
||||||
|
This is a preliminary release of Elastic Stack as a GitLab-managed application. By default,
|
||||||
|
the ability to install it is disabled.
|
||||||
|
|
||||||
|
To allow installation of Elastic Stack as a GitLab-managed application, ask a GitLab
|
||||||
|
administrator to run following command within a Rails console:
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
Feature.enable(:enable_cluster_application_elastic_stack)
|
||||||
|
```
|
||||||
|
|
||||||
|
Once the feature flag is set, to enable log shipping, install Elastic Stack into the cluster with the
|
||||||
|
**Install** button.
|
||||||
|
|
||||||
|
NOTE: **Note:**
|
||||||
|
The [`stable/elastic-stack`](https://github.com/helm/charts/tree/master/stable/elastic-stack)
|
||||||
|
chart is used to install this application with a
|
||||||
|
[`values.yaml`](https://gitlab.com/gitlab-org/gitlab/blob/master/vendor/elastic_stack/values.yaml)
|
||||||
|
file.
|
||||||
|
|
||||||
## Install using GitLab CI (alpha)
|
## Install using GitLab CI (alpha)
|
||||||
|
|
||||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/20822) in GitLab 12.6.
|
> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/20822) in GitLab 12.6.
|
||||||
|
@ -639,6 +672,7 @@ The applications below can be uninstalled.
|
||||||
| Knative | 12.1+ | The associated IP will be deleted and cannot be restored. |
|
| Knative | 12.1+ | The associated IP will be deleted and cannot be restored. |
|
||||||
| Prometheus | 11.11+ | All data will be deleted and cannot be restored. |
|
| Prometheus | 11.11+ | All data will be deleted and cannot be restored. |
|
||||||
| Crossplane | 12.5+ | All data will be deleted and cannot be restored. |
|
| Crossplane | 12.5+ | All data will be deleted and cannot be restored. |
|
||||||
|
| Elastic Stack | 12.7+ | All data will be deleted and cannot be restored. |
|
||||||
| Sentry | 12.6+ | The PostgreSQL persistent volume will remain and should be manually removed for complete uninstall. |
|
| Sentry | 12.6+ | The PostgreSQL persistent volume will remain and should be manually removed for complete uninstall. |
|
||||||
|
|
||||||
To uninstall an application:
|
To uninstall an application:
|
||||||
|
|
|
@ -41,9 +41,37 @@ Logs can be displayed by clicking on a specific pod from [Deploy Boards](../depl
|
||||||
1. On the **Environments** page, you should see the status of the environment's pods with [Deploy Boards](../deploy_boards.md).
|
1. On the **Environments** page, you should see the status of the environment's pods with [Deploy Boards](../deploy_boards.md).
|
||||||
1. When mousing over the list of pods, a tooltip will appear with the exact pod name and status.
|
1. When mousing over the list of pods, a tooltip will appear with the exact pod name and status.
|
||||||
![Deploy Boards pod list](img/pod_logs_deploy_board.png)
|
![Deploy Boards pod list](img/pod_logs_deploy_board.png)
|
||||||
1. Click on the desired pod to bring up the logs view, which will contain the last 500 lines for that pod.
|
1. Click on the desired pod to bring up the logs view.
|
||||||
You may switch between the following in this view:
|
|
||||||
- Pods.
|
|
||||||
- [From GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/issues/5769), environments.
|
|
||||||
|
|
||||||
Support for pods with multiple containers is coming [in a future release](https://gitlab.com/gitlab-org/gitlab/issues/6502).
|
### Logs view
|
||||||
|
|
||||||
|
The logs view will contain the last 500 lines for a pod, and has control to filter via:
|
||||||
|
|
||||||
|
- Pods.
|
||||||
|
- [From GitLab 12.4](https://gitlab.com/gitlab-org/gitlab/issues/5769), environments.
|
||||||
|
- [From GitLab 12.7](https://gitlab.com/gitlab-org/gitlab/merge_requests/21656), [full text search](#full-text-search).
|
||||||
|
|
||||||
|
Support for pods with multiple containers is coming [in a future release](https://gitlab.com/gitlab-org/gitlab/issues/13404).
|
||||||
|
|
||||||
|
Support for historical data is coming [in a future release](https://gitlab.com/gitlab-org/gitlab/issues/196191).
|
||||||
|
|
||||||
|
### Full text search
|
||||||
|
|
||||||
|
> [Introduced](https://gitlab.com/gitlab-org/gitlab/merge_requests/21656) in GitLab 12.7.
|
||||||
|
|
||||||
|
When you enable [Elastic Stack](../../clusters/applications.md#elastic-stack) on your cluster,
|
||||||
|
you can search the content of your logs via a search bar.
|
||||||
|
|
||||||
|
The search is passed on to Elasticsearch using the [simple_query_string](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-simple-query-string-query.html)
|
||||||
|
Elasticsearch function, which supports the following operators:
|
||||||
|
|
||||||
|
```
|
||||||
|
+ signifies AND operation
|
||||||
|
| signifies OR operation
|
||||||
|
- negates a single token
|
||||||
|
" wraps a number of tokens to signify a phrase for searching
|
||||||
|
* at the end of a term signifies a prefix query
|
||||||
|
( and ) signify precedence
|
||||||
|
~N after a word signifies edit distance (fuzziness)
|
||||||
|
~N after a phrase signifies slop amount
|
||||||
|
```
|
||||||
|
|
|
@ -924,6 +924,10 @@ module API
|
||||||
expose :user, using: Entities::UserPublic
|
expose :user, using: Entities::UserPublic
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class DeployKeyWithUser < SSHKeyWithUser
|
||||||
|
expose :deploy_keys_projects
|
||||||
|
end
|
||||||
|
|
||||||
class DeployKeysProject < Grape::Entity
|
class DeployKeysProject < Grape::Entity
|
||||||
expose :deploy_key, merge: true, using: Entities::SSHKey
|
expose :deploy_key, merge: true, using: Entities::SSHKey
|
||||||
expose :can_push
|
expose :can_push
|
||||||
|
|
|
@ -26,12 +26,15 @@ module API
|
||||||
get do
|
get do
|
||||||
authenticated_with_can_read_all_resources!
|
authenticated_with_can_read_all_resources!
|
||||||
|
|
||||||
finder_params = params.merge(key_type: 'ssh')
|
key = KeysFinder.new(current_user, params).execute
|
||||||
|
|
||||||
key = KeysFinder.new(current_user, finder_params).execute
|
|
||||||
|
|
||||||
not_found!('Key') unless key
|
not_found!('Key') unless key
|
||||||
present key, with: Entities::SSHKeyWithUser, current_user: current_user
|
|
||||||
|
if key.type == "DeployKey"
|
||||||
|
present key, with: Entities::DeployKeyWithUser, current_user: current_user
|
||||||
|
else
|
||||||
|
present key, with: Entities::SSHKeyWithUser, current_user: current_user
|
||||||
|
end
|
||||||
rescue KeysFinder::InvalidFingerprint
|
rescue KeysFinder::InvalidFingerprint
|
||||||
render_api_error!('Failed to return the key', 400)
|
render_api_error!('Failed to return the key', 400)
|
||||||
end
|
end
|
||||||
|
|
|
@ -3824,9 +3824,6 @@ msgstr ""
|
||||||
msgid "ClusterIntegration|Copy Jupyter Hostname"
|
msgid "ClusterIntegration|Copy Jupyter Hostname"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "ClusterIntegration|Copy Kibana Hostname"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "ClusterIntegration|Copy Knative Endpoint"
|
msgid "ClusterIntegration|Copy Knative Endpoint"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -4043,9 +4040,6 @@ msgstr ""
|
||||||
msgid "ClusterIntegration|Key pair name"
|
msgid "ClusterIntegration|Key pair name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "ClusterIntegration|Kibana Hostname"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "ClusterIntegration|Knative"
|
msgid "ClusterIntegration|Knative"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -6927,12 +6921,18 @@ msgstr ""
|
||||||
msgid "EnvironmentsDashboard|More actions"
|
msgid "EnvironmentsDashboard|More actions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "EnvironmentsDashboard|Read more."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "EnvironmentsDashboard|Remove"
|
msgid "EnvironmentsDashboard|Remove"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "EnvironmentsDashboard|The environments dashboard provides a summary of each project's environments' status, including pipeline and alert statuses."
|
msgid "EnvironmentsDashboard|The environments dashboard provides a summary of each project's environments' status, including pipeline and alert statuses."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "EnvironmentsDashboard|This dashboard displays a maximum of 7 projects and 3 environments per project. %{readMoreLink}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Environments|An error occurred while canceling the auto stop, please try again"
|
msgid "Environments|An error occurred while canceling the auto stop, please try again"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,9 @@ module QA
|
||||||
before do
|
before do
|
||||||
Flow::Login.sign_in
|
Flow::Login.sign_in
|
||||||
|
|
||||||
issue = Resource::Issue.fabricate_via_api! do |issue|
|
Resource::Issue.fabricate_via_api! do |issue|
|
||||||
issue.title = 'issue title'
|
issue.title = 'issue title'
|
||||||
end
|
end.visit!
|
||||||
|
|
||||||
issue.visit!
|
|
||||||
|
|
||||||
Page::Project::Issue::Show.perform do |show|
|
Page::Project::Issue::Show.perform do |show|
|
||||||
show.select_all_activities_filter
|
show.select_all_activities_filter
|
||||||
|
|
|
@ -6,10 +6,9 @@ module QA
|
||||||
before do
|
before do
|
||||||
Flow::Login.sign_in
|
Flow::Login.sign_in
|
||||||
|
|
||||||
issue = Resource::Issue.fabricate_via_api! do |issue|
|
Resource::Issue.fabricate_via_api! do |issue|
|
||||||
issue.title = 'issue title'
|
issue.title = 'issue title'
|
||||||
end
|
end.visit!
|
||||||
issue.visit!
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'user comments on an issue and edits the comment' do
|
it 'user comments on an issue and edits the comment' do
|
||||||
|
|
|
@ -12,12 +12,8 @@ module QA
|
||||||
resource.name = 'project-to-test-mention'
|
resource.name = 'project-to-test-mention'
|
||||||
resource.visibility = 'private'
|
resource.visibility = 'private'
|
||||||
end
|
end
|
||||||
project.visit!
|
|
||||||
|
|
||||||
Page::Project::Show.perform(&:go_to_members_settings)
|
project.add_member(@user)
|
||||||
Page::Project::Settings::Members.perform do |members|
|
|
||||||
members.add_member(@user.username)
|
|
||||||
end
|
|
||||||
|
|
||||||
Resource::Issue.fabricate_via_api! do |issue|
|
Resource::Issue.fabricate_via_api! do |issue|
|
||||||
issue.title = 'issue to test mention'
|
issue.title = 'issue to test mention'
|
||||||
|
|
|
@ -181,11 +181,8 @@ shared_examples "installing applications on a cluster" do
|
||||||
context 'when user installs Elastic Stack' do
|
context 'when user installs Elastic Stack' do
|
||||||
before do
|
before do
|
||||||
allow(ClusterInstallAppWorker).to receive(:perform_async)
|
allow(ClusterInstallAppWorker).to receive(:perform_async)
|
||||||
allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_in)
|
|
||||||
allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_async)
|
|
||||||
|
|
||||||
create(:clusters_applications_helm, :installed, cluster: cluster)
|
create(:clusters_applications_helm, :installed, cluster: cluster)
|
||||||
create(:clusters_applications_ingress, :installed, external_ip: '127.0.0.1', cluster: cluster)
|
|
||||||
|
|
||||||
page.within('.js-cluster-application-row-elastic_stack') do
|
page.within('.js-cluster-application-row-elastic_stack') do
|
||||||
click_button 'Install'
|
click_button 'Install'
|
||||||
|
|
|
@ -73,7 +73,15 @@ describe KeysFinder do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with valid fingerprints' do
|
context 'with valid fingerprints' do
|
||||||
context 'with valid MD5 params' do
|
let!(:deploy_key) do
|
||||||
|
create(:deploy_key,
|
||||||
|
user: user,
|
||||||
|
key: 'ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt1017k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=',
|
||||||
|
fingerprint: '8a:4a:12:92:0b:50:47:02:d4:5a:8e:a9:44:4e:08:b4',
|
||||||
|
fingerprint_sha256: '4DPHOVNh53i9dHb5PpY2vjfyf5qniTx1/pBFPoZLDdk')
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'personal key with valid MD5 params' do
|
||||||
context 'with an existent fingerprint' do
|
context 'with an existent fingerprint' do
|
||||||
before do
|
before do
|
||||||
params[:fingerprint] = 'ba:81:59:68:d7:6c:cd:02:02:bf:6a:9b:55:4e:af:d1'
|
params[:fingerprint] = 'ba:81:59:68:d7:6c:cd:02:02:bf:6a:9b:55:4e:af:d1'
|
||||||
|
@ -85,6 +93,17 @@ describe KeysFinder do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'deploy key with an existent fingerprint' do
|
||||||
|
before do
|
||||||
|
params[:fingerprint] = '8a:4a:12:92:0b:50:47:02:d4:5a:8e:a9:44:4e:08:b4'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns the key' do
|
||||||
|
expect(subject).to eq(deploy_key)
|
||||||
|
expect(subject.user).to eq(user)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'with a non-existent fingerprint' do
|
context 'with a non-existent fingerprint' do
|
||||||
before do
|
before do
|
||||||
params[:fingerprint] = 'bb:81:59:68:d7:6c:cd:02:02:bf:6a:9b:55:4e:af:d2'
|
params[:fingerprint] = 'bb:81:59:68:d7:6c:cd:02:02:bf:6a:9b:55:4e:af:d2'
|
||||||
|
@ -96,7 +115,7 @@ describe KeysFinder do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with valid SHA256 params' do
|
context 'personal key with valid SHA256 params' do
|
||||||
context 'with an existent fingerprint' do
|
context 'with an existent fingerprint' do
|
||||||
before do
|
before do
|
||||||
params[:fingerprint] = 'SHA256:nUhzNyftwADy8AH3wFY31tAKs7HufskYTte2aXo/lCg'
|
params[:fingerprint] = 'SHA256:nUhzNyftwADy8AH3wFY31tAKs7HufskYTte2aXo/lCg'
|
||||||
|
@ -108,6 +127,17 @@ describe KeysFinder do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'deploy key with an existent fingerprint' do
|
||||||
|
before do
|
||||||
|
params[:fingerprint] = 'SHA256:4DPHOVNh53i9dHb5PpY2vjfyf5qniTx1/pBFPoZLDdk'
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns key' do
|
||||||
|
expect(subject).to eq(deploy_key)
|
||||||
|
expect(subject.user).to eq(user)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'with a non-existent fingerprint' do
|
context 'with a non-existent fingerprint' do
|
||||||
before do
|
before do
|
||||||
params[:fingerprint] = 'SHA256:xTjuFqftwADy8AH3wFY31tAKs7HufskYTte2aXi/mNp'
|
params[:fingerprint] = 'SHA256:xTjuFqftwADy8AH3wFY31tAKs7HufskYTte2aXi/mNp'
|
||||||
|
|
|
@ -35,7 +35,6 @@
|
||||||
"external_ip": { "type": ["string", "null"] },
|
"external_ip": { "type": ["string", "null"] },
|
||||||
"external_hostname": { "type": ["string", "null"] },
|
"external_hostname": { "type": ["string", "null"] },
|
||||||
"hostname": { "type": ["string", "null"] },
|
"hostname": { "type": ["string", "null"] },
|
||||||
"kibana_hostname": { "type": ["string", "null"] },
|
|
||||||
"email": { "type": ["string", "null"] },
|
"email": { "type": ["string", "null"] },
|
||||||
"stack": { "type": ["string", "null"] },
|
"stack": { "type": ["string", "null"] },
|
||||||
"modsecurity_enabled": { "type": ["boolean", "null"] },
|
"modsecurity_enabled": { "type": ["boolean", "null"] },
|
||||||
|
|
|
@ -199,7 +199,7 @@ describe('Applications', () => {
|
||||||
prometheus: { title: 'Prometheus' },
|
prometheus: { title: 'Prometheus' },
|
||||||
jupyter: { title: 'JupyterHub', hostname: '' },
|
jupyter: { title: 'JupyterHub', hostname: '' },
|
||||||
knative: { title: 'Knative', hostname: '' },
|
knative: { title: 'Knative', hostname: '' },
|
||||||
elastic_stack: { title: 'Elastic Stack', kibana_hostname: '' },
|
elastic_stack: { title: 'Elastic Stack' },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -433,79 +433,33 @@ describe('Applications', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Elastic Stack application', () => {
|
describe('Elastic Stack application', () => {
|
||||||
describe('with ingress installed with ip & elastic stack installable', () => {
|
describe('with elastic stack installable', () => {
|
||||||
it('renders hostname active input', () => {
|
it('renders hostname active input', () => {
|
||||||
vm = mountComponent(Applications, {
|
vm = mountComponent(Applications, {
|
||||||
applications: {
|
applications: {
|
||||||
...APPLICATIONS_MOCK_STATE,
|
...APPLICATIONS_MOCK_STATE,
|
||||||
ingress: {
|
|
||||||
title: 'Ingress',
|
|
||||||
status: 'installed',
|
|
||||||
externalIp: '1.1.1.1',
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
vm.$el
|
vm.$el
|
||||||
.querySelector('.js-cluster-application-row-elastic_stack .js-hostname')
|
.querySelector(
|
||||||
.getAttribute('readonly'),
|
'.js-cluster-application-row-elastic_stack .js-cluster-application-install-button',
|
||||||
).toEqual(null);
|
)
|
||||||
|
.getAttribute('disabled'),
|
||||||
|
).toEqual('disabled');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('with ingress installed without external ip', () => {
|
describe('elastic stack installed', () => {
|
||||||
it('does not render hostname input', () => {
|
it('renders uninstall button', () => {
|
||||||
vm = mountComponent(Applications, {
|
vm = mountComponent(Applications, {
|
||||||
applications: {
|
applications: {
|
||||||
...APPLICATIONS_MOCK_STATE,
|
...APPLICATIONS_MOCK_STATE,
|
||||||
ingress: { title: 'Ingress', status: 'installed' },
|
elastic_stack: { title: 'Elastic Stack', status: 'installed' },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(vm.$el.querySelector('.js-cluster-application-row-elastic_stack .js-hostname')).toBe(
|
|
||||||
null,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('with ingress & elastic stack installed', () => {
|
|
||||||
it('renders readonly input', () => {
|
|
||||||
vm = mountComponent(Applications, {
|
|
||||||
applications: {
|
|
||||||
...APPLICATIONS_MOCK_STATE,
|
|
||||||
ingress: {
|
|
||||||
title: 'Ingress',
|
|
||||||
status: 'installed',
|
|
||||||
externalIp: '1.1.1.1',
|
|
||||||
modsecurity_enabled: false,
|
|
||||||
},
|
|
||||||
elastic_stack: { title: 'Elastic Stack', status: 'installed', kibana_hostname: '' },
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(
|
|
||||||
vm.$el
|
|
||||||
.querySelector('.js-cluster-application-row-elastic_stack .js-hostname')
|
|
||||||
.getAttribute('readonly'),
|
|
||||||
).toEqual('readonly');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('without ingress installed', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
vm = mountComponent(Applications, {
|
|
||||||
applications: APPLICATIONS_MOCK_STATE,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not render input', () => {
|
|
||||||
expect(vm.$el.querySelector('.js-cluster-application-row-elastic_stack .js-hostname')).toBe(
|
|
||||||
null,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('renders disabled install button', () => {
|
|
||||||
expect(
|
expect(
|
||||||
vm.$el
|
vm.$el
|
||||||
.querySelector(
|
.querySelector(
|
||||||
|
|
|
@ -157,7 +157,7 @@ const APPLICATIONS_MOCK_STATE = {
|
||||||
prometheus: { title: 'Prometheus' },
|
prometheus: { title: 'Prometheus' },
|
||||||
jupyter: { title: 'JupyterHub', status: 'installable', hostname: '' },
|
jupyter: { title: 'JupyterHub', status: 'installable', hostname: '' },
|
||||||
knative: { title: 'Knative ', status: 'installable', hostname: '' },
|
knative: { title: 'Knative ', status: 'installable', hostname: '' },
|
||||||
elastic_stack: { title: 'Elastic Stack', status: 'installable', kibana_hostname: '' },
|
elastic_stack: { title: 'Elastic Stack', status: 'installable' },
|
||||||
};
|
};
|
||||||
|
|
||||||
export { CLUSTERS_MOCK_DATA, DEFAULT_APPLICATION_STATE, APPLICATIONS_MOCK_STATE };
|
export { CLUSTERS_MOCK_DATA, DEFAULT_APPLICATION_STATE, APPLICATIONS_MOCK_STATE };
|
||||||
|
|
|
@ -167,7 +167,6 @@ describe('Clusters Store', () => {
|
||||||
installFailed: true,
|
installFailed: true,
|
||||||
statusReason: mockResponseData.applications[7].status_reason,
|
statusReason: mockResponseData.applications[7].status_reason,
|
||||||
requestReason: null,
|
requestReason: null,
|
||||||
kibana_hostname: '',
|
|
||||||
installed: false,
|
installed: false,
|
||||||
uninstallable: false,
|
uninstallable: false,
|
||||||
uninstallSuccessful: false,
|
uninstallSuccessful: false,
|
||||||
|
@ -216,16 +215,5 @@ describe('Clusters Store', () => {
|
||||||
`jupyter.${store.state.applications.ingress.externalIp}.nip.io`,
|
`jupyter.${store.state.applications.ingress.externalIp}.nip.io`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('sets default hostname for elastic stack when ingress has a ip address', () => {
|
|
||||||
const mockResponseData =
|
|
||||||
CLUSTERS_MOCK_DATA.GET['/gitlab-org/gitlab-shell/clusters/2/status.json'].data;
|
|
||||||
|
|
||||||
store.updateStateFromServer(mockResponseData);
|
|
||||||
|
|
||||||
expect(store.state.applications.elastic_stack.kibana_hostname).toEqual(
|
|
||||||
`kibana.${store.state.applications.ingress.externalIp}.nip.io`,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,6 +7,10 @@ describe UsersHelper do
|
||||||
|
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
|
|
||||||
|
def filter_ee_badges(badges)
|
||||||
|
badges.reject { |badge| badge[:text] == 'Is using seat' }
|
||||||
|
end
|
||||||
|
|
||||||
describe '#user_link' do
|
describe '#user_link' do
|
||||||
subject { helper.user_link(user) }
|
subject { helper.user_link(user) }
|
||||||
|
|
||||||
|
@ -118,7 +122,7 @@ describe UsersHelper do
|
||||||
|
|
||||||
badges = helper.user_badges_in_admin_section(blocked_user)
|
badges = helper.user_badges_in_admin_section(blocked_user)
|
||||||
|
|
||||||
expect(badges).to eq([text: "Blocked", variant: "danger"])
|
expect(filter_ee_badges(badges)).to eq([text: "Blocked", variant: "danger"])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -128,7 +132,7 @@ describe UsersHelper do
|
||||||
|
|
||||||
badges = helper.user_badges_in_admin_section(admin_user)
|
badges = helper.user_badges_in_admin_section(admin_user)
|
||||||
|
|
||||||
expect(badges).to eq([text: "Admin", variant: "success"])
|
expect(filter_ee_badges(badges)).to eq([text: "Admin", variant: "success"])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -138,7 +142,7 @@ describe UsersHelper do
|
||||||
|
|
||||||
badges = helper.user_badges_in_admin_section(external_user)
|
badges = helper.user_badges_in_admin_section(external_user)
|
||||||
|
|
||||||
expect(badges).to eq([text: "External", variant: "secondary"])
|
expect(filter_ee_badges(badges)).to eq([text: "External", variant: "secondary"])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -146,7 +150,7 @@ describe UsersHelper do
|
||||||
it 'returns the "It\'s You" badge' do
|
it 'returns the "It\'s You" badge' do
|
||||||
badges = helper.user_badges_in_admin_section(user)
|
badges = helper.user_badges_in_admin_section(user)
|
||||||
|
|
||||||
expect(badges).to eq([text: "It's you!", variant: nil])
|
expect(filter_ee_badges(badges)).to eq([text: "It's you!", variant: nil])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -170,7 +174,7 @@ describe UsersHelper do
|
||||||
|
|
||||||
badges = helper.user_badges_in_admin_section(user)
|
badges = helper.user_badges_in_admin_section(user)
|
||||||
|
|
||||||
expect(badges).to be_empty
|
expect(filter_ee_badges(badges)).to be_empty
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,45 +10,8 @@ describe Clusters::Applications::ElasticStack do
|
||||||
include_examples 'cluster application version specs', :clusters_applications_elastic_stack
|
include_examples 'cluster application version specs', :clusters_applications_elastic_stack
|
||||||
include_examples 'cluster application helm specs', :clusters_applications_elastic_stack
|
include_examples 'cluster application helm specs', :clusters_applications_elastic_stack
|
||||||
|
|
||||||
describe '#can_uninstall?' do
|
|
||||||
let(:ingress) { create(:clusters_applications_ingress, :installed, external_hostname: 'localhost.localdomain') }
|
|
||||||
let(:elastic_stack) { create(:clusters_applications_elastic_stack, cluster: ingress.cluster) }
|
|
||||||
|
|
||||||
subject { elastic_stack.can_uninstall? }
|
|
||||||
|
|
||||||
it { is_expected.to be_truthy }
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#set_initial_status' do
|
|
||||||
before do
|
|
||||||
elastic_stack.set_initial_status
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when ingress is not installed' do
|
|
||||||
let(:cluster) { create(:cluster, :provided_by_gcp) }
|
|
||||||
let(:elastic_stack) { create(:clusters_applications_elastic_stack, cluster: cluster) }
|
|
||||||
|
|
||||||
it { expect(elastic_stack).to be_not_installable }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when ingress is installed and external_ip is assigned' do
|
|
||||||
let(:ingress) { create(:clusters_applications_ingress, :installed, external_ip: '127.0.0.1') }
|
|
||||||
let(:elastic_stack) { create(:clusters_applications_elastic_stack, cluster: ingress.cluster) }
|
|
||||||
|
|
||||||
it { expect(elastic_stack).to be_installable }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when ingress is installed and external_hostname is assigned' do
|
|
||||||
let(:ingress) { create(:clusters_applications_ingress, :installed, external_hostname: 'localhost.localdomain') }
|
|
||||||
let(:elastic_stack) { create(:clusters_applications_elastic_stack, cluster: ingress.cluster) }
|
|
||||||
|
|
||||||
it { expect(elastic_stack).to be_installable }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#install_command' do
|
describe '#install_command' do
|
||||||
let!(:ingress) { create(:clusters_applications_ingress, :installed, external_ip: '127.0.0.1') }
|
let!(:elastic_stack) { create(:clusters_applications_elastic_stack) }
|
||||||
let!(:elastic_stack) { create(:clusters_applications_elastic_stack, cluster: ingress.cluster) }
|
|
||||||
|
|
||||||
subject { elastic_stack.install_command }
|
subject { elastic_stack.install_command }
|
||||||
|
|
||||||
|
@ -80,8 +43,7 @@ describe Clusters::Applications::ElasticStack do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#uninstall_command' do
|
describe '#uninstall_command' do
|
||||||
let!(:ingress) { create(:clusters_applications_ingress, :installed, external_ip: '127.0.0.1') }
|
let!(:elastic_stack) { create(:clusters_applications_elastic_stack) }
|
||||||
let!(:elastic_stack) { create(:clusters_applications_elastic_stack, cluster: ingress.cluster) }
|
|
||||||
|
|
||||||
subject { elastic_stack.uninstall_command }
|
subject { elastic_stack.uninstall_command }
|
||||||
|
|
||||||
|
@ -100,19 +62,6 @@ describe Clusters::Applications::ElasticStack do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#files' do
|
|
||||||
let!(:ingress) { create(:clusters_applications_ingress, :installed, external_ip: '127.0.0.1') }
|
|
||||||
let!(:elastic_stack) { create(:clusters_applications_elastic_stack, cluster: ingress.cluster) }
|
|
||||||
|
|
||||||
let(:values) { subject[:'values.yaml'] }
|
|
||||||
|
|
||||||
subject { elastic_stack.files }
|
|
||||||
|
|
||||||
it 'includes elastic stack specific keys in the values.yaml file' do
|
|
||||||
expect(values).to include('ELASTICSEARCH_HOSTS')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#elasticsearch_client' do
|
describe '#elasticsearch_client' do
|
||||||
context 'cluster is nil' do
|
context 'cluster is nil' do
|
||||||
it 'returns nil' do
|
it 'returns nil' do
|
||||||
|
|
|
@ -106,6 +106,36 @@ describe API::Keys do
|
||||||
|
|
||||||
expect(json_response['user']['is_admin']).to be_nil
|
expect(json_response['user']['is_admin']).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when searching a DeployKey' do
|
||||||
|
let(:project) { create(:project, :repository) }
|
||||||
|
let(:project_push) { create(:project, :repository) }
|
||||||
|
let(:deploy_key) { create(:deploy_key) }
|
||||||
|
|
||||||
|
let!(:deploy_keys_project) do
|
||||||
|
create(:deploy_keys_project, project: project, deploy_key: deploy_key)
|
||||||
|
end
|
||||||
|
|
||||||
|
let!(:deploy_keys_project_push) do
|
||||||
|
create(:deploy_keys_project, project: project_push, deploy_key: deploy_key, can_push: true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'returns user and projects if SSH sha256 fingerprint for DeployKey found' do
|
||||||
|
user.keys << deploy_key
|
||||||
|
|
||||||
|
get api("/keys?fingerprint=#{URI.encode_www_form_component("SHA256:" + deploy_key.fingerprint_sha256)}", admin)
|
||||||
|
|
||||||
|
expect(response).to have_gitlab_http_status(200)
|
||||||
|
expect(json_response['title']).to eq(deploy_key.title)
|
||||||
|
expect(json_response['user']['id']).to eq(user.id)
|
||||||
|
|
||||||
|
expect(json_response['deploy_keys_projects'].count).to eq(2)
|
||||||
|
expect(json_response['deploy_keys_projects'][0]['project_id']).to eq(deploy_keys_project.project.id)
|
||||||
|
expect(json_response['deploy_keys_projects'][0]['can_push']).to eq(deploy_keys_project.can_push)
|
||||||
|
expect(json_response['deploy_keys_projects'][1]['project_id']).to eq(deploy_keys_project_push.project.id)
|
||||||
|
expect(json_response['deploy_keys_projects'][1]['can_push']).to eq(deploy_keys_project_push.can_push)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,6 +24,7 @@ describe DeployKeyEntity do
|
||||||
user_id: deploy_key.user_id,
|
user_id: deploy_key.user_id,
|
||||||
title: deploy_key.title,
|
title: deploy_key.title,
|
||||||
fingerprint: deploy_key.fingerprint,
|
fingerprint: deploy_key.fingerprint,
|
||||||
|
fingerprint_sha256: deploy_key.fingerprint_sha256,
|
||||||
destroyed_when_orphaned: true,
|
destroyed_when_orphaned: true,
|
||||||
almost_orphaned: false,
|
almost_orphaned: false,
|
||||||
created_at: deploy_key.created_at,
|
created_at: deploy_key.created_at,
|
||||||
|
|
|
@ -163,8 +163,7 @@ describe Clusters::Applications::CreateService do
|
||||||
context 'elastic stack application' do
|
context 'elastic stack application' do
|
||||||
let(:params) do
|
let(:params) do
|
||||||
{
|
{
|
||||||
application: 'elastic_stack',
|
application: 'elastic_stack'
|
||||||
kibana_hostname: 'example.com'
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -182,10 +181,6 @@ describe Clusters::Applications::CreateService do
|
||||||
cluster.reload
|
cluster.reload
|
||||||
end.to change(cluster, :application_elastic_stack)
|
end.to change(cluster, :application_elastic_stack)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'sets the kibana_hostname' do
|
|
||||||
expect(subject.kibana_hostname).to eq('example.com')
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
9
vendor/elastic_stack/values.yaml
vendored
9
vendor/elastic_stack/values.yaml
vendored
|
@ -11,14 +11,7 @@ elasticsearch:
|
||||||
replicas: 1
|
replicas: 1
|
||||||
|
|
||||||
kibana:
|
kibana:
|
||||||
enabled: true
|
enabled: false
|
||||||
env:
|
|
||||||
ELASTICSEARCH_HOSTS: http://elastic-stack-elasticsearch-client:9200
|
|
||||||
ingress:
|
|
||||||
enabled: true
|
|
||||||
annotations:
|
|
||||||
kubernetes.io/ingress.class: "nginx"
|
|
||||||
kubernetes.io/tls-acme: "true"
|
|
||||||
|
|
||||||
logstash:
|
logstash:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
|
Loading…
Reference in a new issue