Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Léo-Paul Géneau
gitlab-ce
Commits
2c80a1c0
Commit
2c80a1c0
authored
6 years ago
by
Dylan Griffith
Committed by
Mike Greiling
6 years ago
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Introduce Knative Serverless Tab
parent
e80f8933
Changes
27
Show whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
866 additions
and
2 deletions
+866
-2
app/assets/javascripts/pages/projects/serverless/index.js
app/assets/javascripts/pages/projects/serverless/index.js
+5
-0
app/assets/javascripts/serverless/components/empty_state.vue
app/assets/javascripts/serverless/components/empty_state.vue
+40
-0
app/assets/javascripts/serverless/components/function_row.vue
...assets/javascripts/serverless/components/function_row.vue
+40
-0
app/assets/javascripts/serverless/components/functions.vue
app/assets/javascripts/serverless/components/functions.vue
+123
-0
app/assets/javascripts/serverless/event_hub.js
app/assets/javascripts/serverless/event_hub.js
+3
-0
app/assets/javascripts/serverless/serverless_bundle.js
app/assets/javascripts/serverless/serverless_bundle.js
+106
-0
app/assets/javascripts/serverless/services/get_functions_service.js
.../javascripts/serverless/services/get_functions_service.js
+11
-0
app/assets/javascripts/serverless/stores/serverless_store.js
app/assets/javascripts/serverless/stores/serverless_store.js
+24
-0
app/controllers/projects/serverless/functions_controller.rb
app/controllers/projects/serverless/functions_controller.rb
+37
-0
app/finders/projects/serverless/functions_finder.rb
app/finders/projects/serverless/functions_finder.rb
+31
-0
app/helpers/projects_helper.rb
app/helpers/projects_helper.rb
+2
-0
app/models/clusters/applications/knative.rb
app/models/clusters/applications/knative.rb
+34
-2
app/models/clusters/cluster.rb
app/models/clusters/cluster.rb
+10
-0
app/serializers/projects/serverless/service_entity.rb
app/serializers/projects/serverless/service_entity.rb
+33
-0
app/serializers/projects/serverless/service_serializer.rb
app/serializers/projects/serverless/service_serializer.rb
+9
-0
app/views/layouts/nav/sidebar/_project.html.haml
app/views/layouts/nav/sidebar/_project.html.haml
+6
-0
app/views/projects/serverless/functions/index.html.haml
app/views/projects/serverless/functions/index.html.haml
+15
-0
changelogs/unreleased/triggermesh-phase2-serverless-list.yml
changelogs/unreleased/triggermesh-phase2-serverless-list.yml
+5
-0
config/routes/project.rb
config/routes/project.rb
+4
-0
doc/user/project/clusters/serverless/img/install-knative.png
doc/user/project/clusters/serverless/img/install-knative.png
+0
-0
doc/user/project/clusters/serverless/img/serverless-page.png
doc/user/project/clusters/serverless/img/serverless-page.png
+0
-0
locale/gitlab.pot
locale/gitlab.pot
+39
-0
spec/controllers/projects/serverless/functions_controller_spec.rb
...trollers/projects/serverless/functions_controller_spec.rb
+72
-0
spec/features/projects/serverless/functions_spec.rb
spec/features/projects/serverless/functions_spec.rb
+49
-0
spec/finders/projects/serverless/functions_finder_spec.rb
spec/finders/projects/serverless/functions_finder_spec.rb
+60
-0
spec/models/clusters/applications/knative_spec.rb
spec/models/clusters/applications/knative_spec.rb
+42
-0
spec/support/helpers/kubernetes_helpers.rb
spec/support/helpers/kubernetes_helpers.rb
+66
-0
No files found.
app/assets/javascripts/pages/projects/serverless/index.js
0 → 100644
View file @
2c80a1c0
import
ServerlessBundle
from
'
~/serverless/serverless_bundle
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
new
ServerlessBundle
();
// eslint-disable-line no-new
});
This diff is collapsed.
Click to expand it.
app/assets/javascripts/serverless/components/empty_state.vue
0 → 100644
View file @
2c80a1c0
<
script
>
export
default
{
props
:
{
clustersPath
:
{
type
:
String
,
required
:
true
,
},
helpPath
:
{
type
:
String
,
required
:
true
,
},
},
};
</
script
>
<
template
>
<div
class=
"row empty-state js-empty-state"
>
<div
class=
"col-12"
>
<div
class=
"text-content"
>
<h4
class=
"state-title text-center"
>
{{
s__
(
'
Serverless|Getting started with serverless
'
)
}}
</h4>
<p
class=
"state-description"
>
{{
s__
(
`Serverless| In order to start using functions as a service,
you must first install Knative on your Kubernetes cluster.`
)
}}
<a
:href=
"helpPath"
>
{{
__
(
'
More information
'
)
}}
</a>
</p>
<div
class=
"text-center"
>
<a
:href=
"clustersPath"
class=
"btn btn-success"
>
{{
s__
(
'
Serverless|Install Knative
'
)
}}
</a>
</div>
</div>
</div>
</div>
</
template
>
This diff is collapsed.
Click to expand it.
app/assets/javascripts/serverless/components/function_row.vue
0 → 100644
View file @
2c80a1c0
<
script
>
import
Timeago
from
'
~/vue_shared/components/time_ago_tooltip.vue
'
;
export
default
{
components
:
{
Timeago
,
},
props
:
{
func
:
{
type
:
Object
,
required
:
true
,
},
},
computed
:
{
name
()
{
return
this
.
func
.
name
;
},
url
()
{
return
this
.
func
.
url
;
},
image
()
{
return
this
.
func
.
image
;
},
timestamp
()
{
return
this
.
func
.
created_at
;
},
},
};
</
script
>
<
template
>
<div
class=
"gl-responsive-table-row"
>
<div
class=
"table-section section-20"
>
{{
name
}}
</div>
<div
class=
"table-section section-50"
>
<a
:href=
"url"
>
{{
url
}}
</a>
</div>
<div
class=
"table-section section-20"
>
{{
image
}}
</div>
<div
class=
"table-section section-10"
><timeago
:time=
"timestamp"
/></div>
</div>
</
template
>
This diff is collapsed.
Click to expand it.
app/assets/javascripts/serverless/components/functions.vue
0 → 100644
View file @
2c80a1c0
<
script
>
import
{
GlSkeletonLoading
}
from
'
@gitlab/ui
'
;
import
FunctionRow
from
'
./function_row.vue
'
;
import
EmptyState
from
'
./empty_state.vue
'
;
export
default
{
components
:
{
FunctionRow
,
EmptyState
,
GlSkeletonLoading
,
},
props
:
{
functions
:
{
type
:
Array
,
required
:
true
,
default
:
()
=>
[],
},
installed
:
{
type
:
Boolean
,
required
:
true
,
},
clustersPath
:
{
type
:
String
,
required
:
true
,
},
helpPath
:
{
type
:
String
,
required
:
true
,
},
loadingData
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
hasFunctionData
:
{
type
:
Boolean
,
required
:
false
,
default
:
true
,
},
},
};
</
script
>
<
template
>
<section
id=
"serverless-functions"
>
<div
v-if=
"installed"
>
<div
v-if=
"hasFunctionData"
>
<div
class=
"ci-table js-services-list function-element"
>
<div
class=
"gl-responsive-table-row table-row-header"
role=
"row"
>
<div
class=
"table-section section-20"
role=
"rowheader"
>
{{
s__
(
'
Serverless|Function
'
)
}}
</div>
<div
class=
"table-section section-50"
role=
"rowheader"
>
{{
s__
(
'
Serverless|Domain
'
)
}}
</div>
<div
class=
"table-section section-20"
role=
"rowheader"
>
{{
s__
(
'
Serverless|Runtime
'
)
}}
</div>
<div
class=
"table-section section-10"
role=
"rowheader"
>
{{
s__
(
'
Serverless|Last Update
'
)
}}
</div>
</div>
<template
v-if=
"loadingData"
>
<div
v-for=
"j in 3"
:key=
"j"
class=
"gl-responsive-table-row"
>
<gl-skeleton-loading
/>
</div>
</
template
>
<
template
v-else
>
<function-row
v-for=
"f in functions"
:key=
"f.name"
:func=
"f"
/>
</
template
>
</div>
</div>
<div
v-else
class=
"empty-state js-empty-state"
>
<div
class=
"text-content"
>
<h4
class=
"state-title text-center"
>
{{ s__('Serverless|No functions available') }}
</h4>
<p
class=
"state-description"
>
{{
s__(`Serverless|There is currently no function data available from Knative.
This could be for a variety of reasons including:`)
}}
</p>
<ul>
<li>
Your repository does not have a corresponding
<code>
serverless.yml
</code>
file.
</li>
<li>
Your
<code>
gitlab-ci.yml
</code>
file is not properly configured.
</li>
<li>
The functions listed in the
<code>
serverless.yml
</code>
file don't match the namespace
of your cluster.
</li>
<li>
The deploy job has not finished.
</li>
</ul>
<p>
{{
s__(`Serverless|If you believe none of these apply, please check
back later as the function data may be in the process of becoming
available.`)
}}
</p>
<div
class=
"text-center"
>
<a
:href=
"helpPath"
class=
"btn btn-success"
>
{{ s__('Serverless|Learn more about Serverless') }}
</a>
</div>
</div>
</div>
</div>
<empty-state
v-else
:clusters-path=
"clustersPath"
:help-path=
"helpPath"
/>
</section>
</template>
<
style
>
.top-area
{
border-bottom
:
0
;
}
.function-element
{
border-bottom
:
1px
solid
#e5e5e5
;
border-bottom-color
:
rgb
(
229
,
229
,
229
);
border-bottom-style
:
solid
;
border-bottom-width
:
1px
;
}
</
style
>
This diff is collapsed.
Click to expand it.
app/assets/javascripts/serverless/event_hub.js
0 → 100644
View file @
2c80a1c0
import
Vue
from
'
vue
'
;
export
default
new
Vue
();
This diff is collapsed.
Click to expand it.
app/assets/javascripts/serverless/serverless_bundle.js
0 → 100644
View file @
2c80a1c0
import
Visibility
from
'
visibilityjs
'
;
import
Vue
from
'
vue
'
;
import
{
s__
}
from
'
../locale
'
;
import
Flash
from
'
../flash
'
;
import
Poll
from
'
../lib/utils/poll
'
;
import
ServerlessStore
from
'
./stores/serverless_store
'
;
import
GetFunctionsService
from
'
./services/get_functions_service
'
;
import
Functions
from
'
./components/functions.vue
'
;
export
default
class
Serverless
{
constructor
()
{
const
{
statusPath
,
clustersPath
,
helpPath
,
installed
}
=
document
.
querySelector
(
'
.js-serverless-functions-page
'
,
).
dataset
;
this
.
service
=
new
GetFunctionsService
(
statusPath
);
this
.
knativeInstalled
=
installed
!==
undefined
;
this
.
store
=
new
ServerlessStore
(
this
.
knativeInstalled
,
clustersPath
,
helpPath
);
this
.
initServerless
();
this
.
functionLoadCount
=
0
;
if
(
statusPath
&&
this
.
knativeInstalled
)
{
this
.
initPolling
();
}
}
initServerless
()
{
const
{
store
}
=
this
;
const
el
=
document
.
querySelector
(
'
#js-serverless-functions
'
);
this
.
functions
=
new
Vue
({
el
,
data
()
{
return
{
state
:
store
.
state
,
};
},
render
(
createElement
)
{
return
createElement
(
Functions
,
{
props
:
{
functions
:
this
.
state
.
functions
,
installed
:
this
.
state
.
installed
,
clustersPath
:
this
.
state
.
clustersPath
,
helpPath
:
this
.
state
.
helpPath
,
loadingData
:
this
.
state
.
loadingData
,
hasFunctionData
:
this
.
state
.
hasFunctionData
,
},
});
},
});
}
initPolling
()
{
this
.
poll
=
new
Poll
({
resource
:
this
.
service
,
method
:
'
fetchData
'
,
successCallback
:
data
=>
this
.
handleSuccess
(
data
),
errorCallback
:
()
=>
this
.
handleError
(),
});
if
(
!
Visibility
.
hidden
())
{
this
.
poll
.
makeRequest
();
}
else
{
this
.
service
.
fetchData
()
.
then
(
data
=>
this
.
handleSuccess
(
data
))
.
catch
(()
=>
this
.
handleError
());
}
Visibility
.
change
(()
=>
{
if
(
!
Visibility
.
hidden
()
&&
!
this
.
destroyed
)
{
this
.
poll
.
restart
();
}
else
{
this
.
poll
.
stop
();
}
});
}
handleSuccess
(
data
)
{
if
(
data
.
status
===
200
)
{
this
.
store
.
updateFunctionsFromServer
(
data
.
data
);
this
.
store
.
updateLoadingState
(
false
);
}
else
if
(
data
.
status
===
204
)
{
/* Time out after 3 attempts to retrieve data */
this
.
functionLoadCount
+=
1
;
if
(
this
.
functionLoadCount
===
3
)
{
this
.
poll
.
stop
();
this
.
store
.
toggleNoFunctionData
();
}
}
}
static
handleError
()
{
Flash
(
s__
(
'
Serverless|An error occurred while retrieving serverless components
'
));
}
destroy
()
{
this
.
destroyed
=
true
;
if
(
this
.
poll
)
{
this
.
poll
.
stop
();
}
this
.
functions
.
$destroy
();
}
}
This diff is collapsed.
Click to expand it.
app/assets/javascripts/serverless/services/get_functions_service.js
0 → 100644
View file @
2c80a1c0
import
axios
from
'
~/lib/utils/axios_utils
'
;
export
default
class
GetFunctionsService
{
constructor
(
endpoint
)
{
this
.
endpoint
=
endpoint
;
}
fetchData
()
{
return
axios
.
get
(
this
.
endpoint
);
}
}
This diff is collapsed.
Click to expand it.
app/assets/javascripts/serverless/stores/serverless_store.js
0 → 100644
View file @
2c80a1c0
export
default
class
ServerlessStore
{
constructor
(
knativeInstalled
=
false
,
clustersPath
,
helpPath
)
{
this
.
state
=
{
functions
:
[],
hasFunctionData
:
true
,
loadingData
:
true
,
installed
:
knativeInstalled
,
clustersPath
,
helpPath
,
};
}
updateFunctionsFromServer
(
functions
=
[])
{
this
.
state
.
functions
=
functions
;
}
updateLoadingState
(
loadingData
)
{
this
.
state
.
loadingData
=
loadingData
;
}
toggleNoFunctionData
()
{
this
.
state
.
hasFunctionData
=
false
;
}
}
This diff is collapsed.
Click to expand it.
app/controllers/projects/serverless/functions_controller.rb
0 → 100644
View file @
2c80a1c0
# frozen_string_literal: true
module
Projects
module
Serverless
class
FunctionsController
<
Projects
::
ApplicationController
include
ProjectUnauthorized
before_action
:authorize_read_cluster!
INDEX_PRIMING_INTERVAL
=
10_000
INDEX_POLLING_INTERVAL
=
30_000
def
index
finder
=
Projects
::
Serverless
::
FunctionsFinder
.
new
(
project
.
clusters
)
respond_to
do
|
format
|
format
.
json
do
functions
=
finder
.
execute
if
functions
.
any?
Gitlab
::
PollingInterval
.
set_header
(
response
,
interval:
INDEX_POLLING_INTERVAL
)
render
json:
Projects
::
Serverless
::
ServiceSerializer
.
new
(
current_user:
@current_user
).
represent
(
functions
)
else
Gitlab
::
PollingInterval
.
set_header
(
response
,
interval:
INDEX_PRIMING_INTERVAL
)
head
:no_content
end
end
format
.
html
do
@installed
=
finder
.
installed?
render
end
end
end
end
end
end
This diff is collapsed.
Click to expand it.
app/finders/projects/serverless/functions_finder.rb
0 → 100644
View file @
2c80a1c0
# frozen_string_literal: true
module
Projects
module
Serverless
class
FunctionsFinder
def
initialize
(
clusters
)
@clusters
=
clusters
end
def
execute
knative_services
.
flatten
.
compact
end
def
installed?
clusters_with_knative_installed
.
exists?
end
private
def
knative_services
clusters_with_knative_installed
.
preload_knative
.
map
do
|
cluster
|
cluster
.
application_knative
.
services_for
(
ns:
cluster
.
platform_kubernetes
&
.
actual_namespace
)
end
end
def
clusters_with_knative_installed
@clusters
.
with_knative_installed
end
end
end
end
This diff is collapsed.
Click to expand it.
app/helpers/projects_helper.rb
View file @
2c80a1c0
...
...
@@ -307,6 +307,7 @@ module ProjectsHelper
settings: :admin_project
,
builds: :read_build
,
clusters: :read_cluster
,
serverless: :read_cluster
,
labels: :read_label
,
issues: :read_issue
,
project_members: :read_project_member
,
...
...
@@ -545,6 +546,7 @@ module ProjectsHelper
%w[
environments
clusters
functions
user
gcp
]
...
...
This diff is collapsed.
Click to expand it.
app/models/clusters/applications/knative.rb
View file @
2c80a1c0
...
...
@@ -15,6 +15,9 @@ module Clusters
include
::
Clusters
::
Concerns
::
ApplicationVersion
include
::
Clusters
::
Concerns
::
ApplicationData
include
AfterCommitQueue
include
ReactiveCaching
self
.
reactive_cache_key
=
->
(
knative
)
{
[
knative
.
class
.
model_name
.
singular
,
knative
.
id
]
}
state_machine
:status
do
before_transition
any
=>
[
:installed
]
do
|
application
|
...
...
@@ -29,6 +32,8 @@ module Clusters
validates
:hostname
,
presence:
true
,
hostname:
true
scope
:for_cluster
,
->
(
cluster
)
{
where
(
cluster:
cluster
)
}
def
chart
'knative/knative'
end
...
...
@@ -55,12 +60,39 @@ module Clusters
ClusterWaitForIngressIpAddressWorker
.
perform_async
(
name
,
id
)
end
def
client
cluster
.
kubeclient
.
knative_client
end
def
services
with_reactive_cache
do
|
data
|
data
[
:services
]
end
end
def
calculate_reactive_cache
{
services:
read_services
}
end
def
ingress_service
cluster
.
kubeclient
.
get_service
(
'knative-ingressgateway'
,
'istio-system'
)
end
def
client
cluster
.
platform_kubernetes
.
kubeclient
.
knative_client
def
services_for
(
ns:
namespace
)
return
unless
services
return
[]
unless
ns
services
.
select
do
|
service
|
service
.
dig
(
'metadata'
,
'namespace'
)
==
ns
end
end
private
def
read_services
client
.
get_services
.
as_json
rescue
Kubeclient
::
ResourceNotFoundError
[]
end
end
end
...
...
This diff is collapsed.
Click to expand it.
app/models/clusters/cluster.rb
View file @
2c80a1c0
...
...
@@ -93,6 +93,16 @@ module Clusters
where
(
'NOT EXISTS (?)'
,
subquery
)
end
scope
:with_knative_installed
,
->
{
joins
(
:application_knative
).
merge
(
Clusters
::
Applications
::
Knative
.
installed
)
}
scope
:preload_knative
,
->
{
preload
(
:kubernetes_namespace
,
:platform_kubernetes
,
:application_knative
)
}
def
self
.
ancestor_clusters_for_clusterable
(
clusterable
,
hierarchy_order: :asc
)
hierarchy_groups
=
clusterable
.
ancestors_upto
(
hierarchy_order:
hierarchy_order
).
eager_load
(
:clusters
)
hierarchy_groups
=
hierarchy_groups
.
merge
(
current_scope
)
if
current_scope
...
...
This diff is collapsed.
Click to expand it.
app/serializers/projects/serverless/service_entity.rb
0 → 100644
View file @
2c80a1c0
# frozen_string_literal: true
module
Projects
module
Serverless
class
ServiceEntity
<
Grape
::
Entity
include
RequestAwareEntity
expose
:name
do
|
service
|
service
.
dig
(
'metadata'
,
'name'
)
end
expose
:namespace
do
|
service
|
service
.
dig
(
'metadata'
,
'namespace'
)
end
expose
:created_at
do
|
service
|
service
.
dig
(
'metadata'
,
'creationTimestamp'
)
end
expose
:url
do
|
service
|
"http://
#{
service
.
dig
(
'status'
,
'domain'
)
}
"
end
expose
:description
do
|
service
|
service
.
dig
(
'spec'
,
'runLatest'
,
'configuration'
,
'revisionTemplate'
,
'metadata'
,
'annotations'
,
'Description'
)
end
expose
:image
do
|
service
|
service
.
dig
(
'spec'
,
'runLatest'
,
'configuration'
,
'build'
,
'template'
,
'name'
)
end
end
end
end
This diff is collapsed.
Click to expand it.
app/serializers/projects/serverless/service_serializer.rb
0 → 100644
View file @
2c80a1c0
# frozen_string_literal: true
module
Projects
module
Serverless
class
ServiceSerializer
<
BaseSerializer
entity
Projects
::
Serverless
::
ServiceEntity
end
end
end
This diff is collapsed.
Click to expand it.
app/views/layouts/nav/sidebar/_project.html.haml
View file @
2c80a1c0
...
...
@@ -222,6 +222,12 @@
%span
=
_
(
'Environments'
)
-
if
project_nav_tab?
:serverless
=
nav_link
(
controller: :functions
)
do
=
link_to
project_serverless_functions_path
(
@project
),
title:
_
(
'Serverless'
)
do
%span
=
_
(
'Serverless'
)
-
if
project_nav_tab?
:clusters
-
show_cluster_hint
=
show_gke_cluster_integration_callout?
(
@project
)
=
nav_link
(
controller:
[
:clusters
,
:user
,
:gcp
])
do
...
...
This diff is collapsed.
Click to expand it.
app/views/projects/serverless/functions/index.html.haml
0 → 100644
View file @
2c80a1c0
-
@no_container
=
true
-
@content_class
=
"limit-container-width"
unless
fluid_layout
-
breadcrumb_title
'Serverless'
-
page_title
'Serverless'
-
status_path
=
project_serverless_functions_path
(
@project
,
format: :json
)
-
clusters_path
=
project_clusters_path
(
@project
)
.serverless-functions-page.js-serverless-functions-page
{
data:
{
status_path:
status_path
,
installed:
@installed
,
clusters_path:
clusters_path
,
help_path:
help_page_path
(
'user/project/clusters/serverless/index'
)
}
}
%div
{
class:
[
container_class
,
(
'limit-container-width'
unless
fluid_layout
)]
}
.js-serverless-functions-notice
.flash-container
.top-area.adjust
.serverless-functions-table
#js-serverless-functions
This diff is collapsed.
Click to expand it.
changelogs/unreleased/triggermesh-phase2-serverless-list.yml
0 → 100644
View file @
2c80a1c0
---
title
:
Introduce Knative and Serverless Components
merge_request
:
23174
author
:
Chris Baumbauer
type
:
added
This diff is collapsed.
Click to expand it.
config/routes/project.rb
View file @
2c80a1c0
...
...
@@ -245,6 +245,10 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end
end
namespace
:serverless
do
resources
:functions
,
only:
[
:index
]
end
scope
'-'
do
get
'archive/*id'
,
constraints:
{
format:
Gitlab
::
PathRegex
.
archive_formats_regex
,
id:
/.+?/
},
to:
'repositories#archive'
,
as:
'archive'
...
...
This diff is collapsed.
Click to expand it.
doc/user/project/clusters/serverless/img/install-knative.png
View replaced file @
e80f8933
View file @
2c80a1c0
100 KB
|
W:
0px
|
H:
0px
30.5 KB
|
W:
0px
|
H:
0px
2-up
Swipe
Onion skin
This diff is collapsed.
Click to expand it.
doc/user/project/clusters/serverless/img/serverless-page.png
0 → 100644
View file @
2c80a1c0
31 KB
This diff is collapsed.
Click to expand it.
locale/gitlab.pot
View file @
2c80a1c0
...
...
@@ -5815,6 +5815,45 @@ msgstr ""
msgid "Server version"
msgstr ""
msgid "Serverless"
msgstr ""
msgid "Serverless| In order to start using functions as a service, you must first install Knative on your Kubernetes cluster."
msgstr ""
msgid "Serverless|An error occurred while retrieving serverless components"
msgstr ""
msgid "Serverless|Domain"
msgstr ""
msgid "Serverless|Function"
msgstr ""
msgid "Serverless|Getting started with serverless"
msgstr ""
msgid "Serverless|If you believe none of these apply, please check back later as the function data may be in the process of becoming available."
msgstr ""
msgid "Serverless|Install Knative"
msgstr ""
msgid "Serverless|Last Update"
msgstr ""
msgid "Serverless|Learn more about Serverless"
msgstr ""
msgid "Serverless|No functions available"
msgstr ""
msgid "Serverless|Runtime"
msgstr ""
msgid "Serverless|There is currently no function data available from Knative. This could be for a variety of reasons including:"
msgstr ""
msgid "Service Templates"
msgstr ""
...
...
This diff is collapsed.
Click to expand it.
spec/controllers/projects/serverless/functions_controller_spec.rb
0 → 100644
View file @
2c80a1c0
# frozen_string_literal: true
require
'spec_helper'
describe
Projects
::
Serverless
::
FunctionsController
do
include
KubernetesHelpers
include
ReactiveCachingHelpers
let
(
:user
)
{
create
(
:user
)
}
let
(
:cluster
)
{
create
(
:cluster
,
:project
,
:provided_by_gcp
)
}
let
(
:knative
)
{
create
(
:clusters_applications_knative
,
:installed
,
cluster:
cluster
)
}
let
(
:service
)
{
cluster
.
platform_kubernetes
}
let
(
:project
)
{
cluster
.
project
}
let
(
:namespace
)
do
create
(
:cluster_kubernetes_namespace
,
cluster:
cluster
,
cluster_project:
cluster
.
cluster_project
,
project:
cluster
.
cluster_project
.
project
)
end
before
do
project
.
add_maintainer
(
user
)
sign_in
(
user
)
end
def
params
(
opts
=
{})
opts
.
reverse_merge
(
namespace_id:
project
.
namespace
.
to_param
,
project_id:
project
.
to_param
)
end
describe
'GET #index'
do
context
'empty cache'
do
it
'has no data'
do
get
:index
,
params
({
format: :json
})
expect
(
response
).
to
have_gitlab_http_status
(
204
)
end
it
'renders an html page'
do
get
:index
,
params
expect
(
response
).
to
have_gitlab_http_status
(
200
)
end
end
end
describe
'GET #index with data'
,
:use_clean_rails_memory_store_caching
do
before
do
stub_reactive_cache
(
knative
,
services:
kube_knative_services_body
(
namespace:
namespace
.
namespace
,
name:
cluster
.
project
.
name
)[
"items"
])
end
it
'has data'
do
get
:index
,
params
({
format: :json
})
expect
(
response
).
to
have_gitlab_http_status
(
200
)
expect
(
json_response
).
to
contain_exactly
(
a_hash_including
(
"name"
=>
project
.
name
,
"url"
=>
"http://
#{
project
.
name
}
.
#{
namespace
.
namespace
}
.example.com"
)
)
end
it
'has data in html'
do
get
:index
,
params
expect
(
response
).
to
have_gitlab_http_status
(
200
)
end
end
end
This diff is collapsed.
Click to expand it.
spec/features/projects/serverless/functions_spec.rb
0 → 100644
View file @
2c80a1c0
require
'spec_helper'
describe
'Functions'
,
:js
do
let
(
:project
)
{
create
(
:project
)
}
let
(
:user
)
{
create
(
:user
)
}
before
do
project
.
add_maintainer
(
user
)
gitlab_sign_in
(
user
)
end
context
'when user does not have a cluster and visits the serverless page'
do
before
do
visit
project_serverless_functions_path
(
project
)
end
it
'sees an empty state'
do
expect
(
page
).
to
have_link
(
'Install Knative'
)
expect
(
page
).
to
have_selector
(
'.empty-state'
)
end
end
context
'when the user does have a cluster and visits the serverless page'
do
let
(
:cluster
)
{
create
(
:cluster
,
:project
,
:provided_by_gcp
)
}
before
do
visit
project_serverless_functions_path
(
project
)
end
it
'sees an empty state'
do
expect
(
page
).
to
have_link
(
'Install Knative'
)
expect
(
page
).
to
have_selector
(
'.empty-state'
)
end
end
context
'when the user has a cluster and knative installed and visits the serverless page'
do
let!
(
:cluster
)
{
create
(
:cluster
,
:project
,
:provided_by_gcp
)
}
let
(
:knative
)
{
create
(
:clusters_applications_knative
,
:installed
,
cluster:
cluster
)
}
let
(
:project
)
{
knative
.
cluster
.
project
}
before
do
visit
project_serverless_functions_path
(
project
)
end
it
'sees an empty listing of serverless functions'
do
expect
(
page
).
to
have_selector
(
'.gl-responsive-table-row'
)
end
end
end
This diff is collapsed.
Click to expand it.
spec/finders/projects/serverless/functions_finder_spec.rb
0 → 100644
View file @
2c80a1c0
# frozen_string_literal: true
require
'spec_helper'
describe
Projects
::
Serverless
::
FunctionsFinder
do
include
KubernetesHelpers
include
ReactiveCachingHelpers
let
(
:user
)
{
create
(
:user
)
}
let
(
:cluster
)
{
create
(
:cluster
,
:project
,
:provided_by_gcp
)
}
let
(
:service
)
{
cluster
.
platform_kubernetes
}
let
(
:project
)
{
cluster
.
project
}
let
(
:namespace
)
do
create
(
:cluster_kubernetes_namespace
,
cluster:
cluster
,
cluster_project:
cluster
.
cluster_project
,
project:
cluster
.
cluster_project
.
project
)
end
before
do
project
.
add_maintainer
(
user
)
end
describe
'retrieve data from knative'
do
it
'does not have knative installed'
do
expect
(
described_class
.
new
(
project
.
clusters
).
execute
).
to
be_empty
end
context
'has knative installed'
do
let!
(
:knative
)
{
create
(
:clusters_applications_knative
,
:installed
,
cluster:
cluster
)
}
it
'there are no functions'
do
expect
(
described_class
.
new
(
project
.
clusters
).
execute
).
to
be_empty
end
it
'there are functions'
,
:use_clean_rails_memory_store_caching
do
stub_reactive_cache
(
knative
,
services:
kube_knative_services_body
(
namespace:
namespace
.
namespace
,
name:
cluster
.
project
.
name
)[
"items"
])
expect
(
described_class
.
new
(
project
.
clusters
).
execute
).
not_to
be_empty
end
end
end
describe
'verify if knative is installed'
do
context
'knative is not installed'
do
it
'does not have knative installed'
do
expect
(
described_class
.
new
(
project
.
clusters
).
installed?
).
to
be
false
end
end
context
'knative is installed'
do
let!
(
:knative
)
{
create
(
:clusters_applications_knative
,
:installed
,
cluster:
cluster
)
}
it
'does have knative installed'
do
expect
(
described_class
.
new
(
project
.
clusters
).
installed?
).
to
be
true
end
end
end
end
This diff is collapsed.
Click to expand it.
spec/models/clusters/applications/knative_spec.rb
View file @
2c80a1c0
require
'rails_helper'
describe
Clusters
::
Applications
::
Knative
do
include
KubernetesHelpers
include
ReactiveCachingHelpers
let
(
:knative
)
{
create
(
:clusters_applications_knative
)
}
include_examples
'cluster application core specs'
,
:clusters_applications_knative
...
...
@@ -121,4 +124,43 @@ describe Clusters::Applications::Knative do
describe
'validations'
do
it
{
is_expected
.
to
validate_presence_of
(
:hostname
)
}
end
describe
'#services'
do
let
(
:cluster
)
{
create
(
:cluster
,
:project
,
:provided_by_gcp
)
}
let
(
:service
)
{
cluster
.
platform_kubernetes
}
let
(
:knative
)
{
create
(
:clusters_applications_knative
,
cluster:
cluster
)
}
let
(
:namespace
)
do
create
(
:cluster_kubernetes_namespace
,
cluster:
cluster
,
cluster_project:
cluster
.
cluster_project
,
project:
cluster
.
cluster_project
.
project
)
end
subject
{
knative
.
services
}
before
do
stub_kubeclient_discover
(
service
.
api_url
)
stub_kubeclient_knative_services
end
it
'should have an unintialized cache'
do
is_expected
.
to
be_nil
end
context
'when using synchronous reactive cache'
do
before
do
stub_reactive_cache
(
knative
,
services:
kube_response
(
kube_knative_services_body
))
synchronous_reactive_cache
(
knative
)
end
it
'should have cached services'
do
is_expected
.
not_to
be_nil
end
it
'should match our namespace'
do
expect
(
knative
.
services_for
(
ns:
namespace
)).
not_to
be_nil
end
end
end
end
This diff is collapsed.
Click to expand it.
spec/support/helpers/kubernetes_helpers.rb
View file @
2c80a1c0
...
...
@@ -34,6 +34,17 @@ module KubernetesHelpers
WebMock
.
stub_request
(
:get
,
deployments_url
).
to_return
(
response
||
kube_deployments_response
)
end
def
stub_kubeclient_knative_services
(
**
options
)
options
[
:name
]
||=
"kubetest"
options
[
:namespace
]
||=
"default"
options
[
:domain
]
||=
"example.com"
stub_kubeclient_discover
(
service
.
api_url
)
knative_url
=
service
.
api_url
+
"/apis/serving.knative.dev/v1alpha1/services"
WebMock
.
stub_request
(
:get
,
knative_url
).
to_return
(
kube_response
(
kube_knative_services_body
(
options
)))
end
def
stub_kubeclient_get_secret
(
api_url
,
**
options
)
options
[
:metadata_name
]
||=
"default-token-1"
options
[
:namespace
]
||=
"default"
...
...
@@ -181,6 +192,13 @@ module KubernetesHelpers
}
end
def
kube_knative_services_body
(
**
options
)
{
"kind"
=>
"List"
,
"items"
=>
[
kube_service
(
options
)]
}
end
# This is a partial response, it will have many more elements in reality but
# these are the ones we care about at the moment
def
kube_pod
(
name:
"kube-pod"
,
app:
"valid-pod-label"
,
status:
"Running"
,
track:
nil
)
...
...
@@ -224,6 +242,54 @@ module KubernetesHelpers
}
end
def
kube_service
(
name:
"kubetest"
,
namespace:
"default"
,
domain:
"example.com"
)
{
"metadata"
=>
{
"creationTimestamp"
=>
"2018-11-21T06:16:33Z"
,
"name"
=>
name
,
"namespace"
=>
namespace
,
"selfLink"
=>
"/apis/serving.knative.dev/v1alpha1/namespaces/
#{
namespace
}
/services/
#{
name
}
"
},
"spec"
=>
{
"generation"
=>
2
},
"status"
=>
{
"domain"
=>
"
#{
name
}
.
#{
namespace
}
.
#{
domain
}
"
,
"domainInternal"
=>
"
#{
name
}
.
#{
namespace
}
.svc.cluster.local"
,
"latestCreatedRevisionName"
=>
"
#{
name
}
-00002"
,
"latestReadyRevisionName"
=>
"
#{
name
}
-00002"
,
"observedGeneration"
=>
2
}
}
end
def
kube_service_full
(
name:
"kubetest"
,
namespace:
"kube-ns"
,
domain:
"example.com"
)
{
"metadata"
=>
{
"creationTimestamp"
=>
"2018-11-21T06:16:33Z"
,
"name"
=>
name
,
"namespace"
=>
namespace
,
"selfLink"
=>
"/apis/serving.knative.dev/v1alpha1/namespaces/
#{
namespace
}
/services/
#{
name
}
"
,
"annotation"
=>
{
"description"
=>
"This is a test description"
}
},
"spec"
=>
{
"generation"
=>
2
,
"build"
=>
{
"template"
=>
"go-1.10.3"
}
},
"status"
=>
{
"domain"
=>
"
#{
name
}
.
#{
namespace
}
.
#{
domain
}
"
,
"domainInternal"
=>
"
#{
name
}
.
#{
namespace
}
.svc.cluster.local"
,
"latestCreatedRevisionName"
=>
"
#{
name
}
-00002"
,
"latestReadyRevisionName"
=>
"
#{
name
}
-00002"
,
"observedGeneration"
=>
2
}
}
end
def
kube_terminals
(
service
,
pod
)
pod_name
=
pod
[
'metadata'
][
'name'
]
containers
=
pod
[
'spec'
][
'containers'
]
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment