Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Tekton Results integration DEMO #3860

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions base/200-clusterrole-backend.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,7 @@ rules:
- get
- list
- watch
# Dashboard needs to be able to query existing results.
- apiGroups: ["results.tekton.dev"]
resources: ["logs", "results", "records"]
verbs: ["get", "list"]
2 changes: 2 additions & 0 deletions base/300-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,5 @@ spec:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
# empty volumeMounts is needed for resultsAPI cert mount
volumeMounts: []
34 changes: 33 additions & 1 deletion cmd/dashboard/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/tektoncd/dashboard/pkg/router"
k8sclientset "k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
certutil "k8s.io/client-go/util/cert"
)

var (
Expand All @@ -38,6 +39,9 @@ var (
streamLogs = flag.Bool("stream-logs", true, "Enable log streaming instead of polling")
externalLogs = flag.String("external-logs", "", "External logs provider URL")
xFrameOptions = flag.String("x-frame-options", "DENY", "Value for the X-Frame-Options response header, set '' to omit it")
resultsApiAddr = flag.String("results-api-addr", "tekton-results-api-service.tekton-pipelines.svc.cluster.local:8080", "Address of Results API server")
enableResultsTLS = flag.Bool("enable-results-tls", false, "Enable TLS verification when connecting to Results API server")
resultsTLSCertPath = flag.String("results-tls-cert-path", "/etc/tls/tls.crt", "TLS certs to the Results API server.")
)

func main() {
Expand All @@ -63,6 +67,11 @@ func main() {
}
tenants := strings.FieldsFunc(*tenantNamespaces, splitByComma)

resultsCfg, err := resultsConfig(*enableResultsTLS, *resultsTLSCertPath)
if err != nil {
logging.Log.Errorf("Error building results config: %s", err.Error())
}

options := endpoints.Options{
InstallNamespace: installNamespace,
PipelinesNamespace: *pipelinesNamespace,
Expand All @@ -80,9 +89,10 @@ func main() {
Config: cfg,
K8sClient: k8sClient,
Options: options,
ResultsConfig: resultsCfg,
}

server, err := router.Register(resource, cfg)
server, err := router.Register(resource, cfg, resultsCfg)

if err != nil {
logging.Log.Errorf("Error creating proxy: %s", err.Error())
Expand All @@ -99,3 +109,25 @@ func main() {
logging.Log.Infof("Starting to serve on %s", l.Addr().String())
logging.Log.Fatal(server.ServeOnListener(l))
}

func resultsConfig(enableResultsTLS bool, resultsTLSCertPath string) (*rest.Config, error) {
var cfg *rest.Config
var err error

if cfg, err = rest.InClusterConfig(); err != nil {
logging.Log.Errorf("Error building kubeconfig: %s", err.Error())
return nil, err
}
if enableResultsTLS {
if _, err := certutil.NewPool(resultsTLSCertPath); err != nil {
logging.Log.Errorf("Expected to load root CA config from %s, but got err: %v", resultsTLSCertPath, err)
} else {
cfg.TLSClientConfig.CAFile = resultsTLSCertPath
}
} else {
cfg.TLSClientConfig.Insecure = true
cfg.TLSClientConfig.CAFile = ""
}
cfg.Host = "https://" + *resultsApiAddr
return cfg, nil
}
16 changes: 16 additions & 0 deletions docs/dev/results.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Tekton Dashboard - [Tekton Results](https://github.com/tektoncd/results) API support

Tekton Results aims to help users logically group CI/CD workload history and separate out long term result storage away
from the Pipeline controller. For more info information, please
see [Tekton Results](https://github.com/tektoncd/results)

Note: Dashboard for [Tekton Results](https://github.com/tektoncd/results) API support is still at early stage.

## [Tekton Results](https://github.com/tektoncd/results) supporting set-up

1. follow Tekton Results [installation instructions](https://github.com/tektoncd/results/blob/main/docs/install.md)
2. append `--enable-results` arguments to install, note that `--enable-results` override `--read-write`.

```bash
./scripts/installer install --enable-results
```
27 changes: 27 additions & 0 deletions overlays/installer/results/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright 2020-2023 The Tekton Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../read-only
patches:
- path: ../../patches/results/deployment-tls-patch.yaml
target:
group: apps
kind: Deployment
name: tekton-dashboard
namespace: tekton-pipelines
version: v1
35 changes: 35 additions & 0 deletions overlays/patches/results/deployment-tls-patch.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Copyright 2020-2021 The Tekton Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

---
- op: add
path: /spec/template/spec/volumes/-
value:
name: tls
secret:
secretName: tekton-results-tls
- op: add
path: /spec/template/spec/containers/0/volumeMounts/-
value:
name: tls
mountPath: "/etc/tls"
readOnly: true
- op: add
path: /spec/template/spec/containers/0/args/-
value:
--enable-results-tls=1
- op: add
path: /spec/template/spec/containers/0/args/-
value:
--results-tls-cert-path=/etc/tls/tls.crt
3 changes: 2 additions & 1 deletion packages/components/src/components/TaskRuns/TaskRuns.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ const TaskRuns = ({
const statusIcon = getTaskRunStatusIcon(taskRun);
const taskRunURL = getTaskRunURL({
name: taskRunName,
namespace
namespace,
taskRun
});

const taskRunsURL =
Expand Down
11 changes: 11 additions & 0 deletions packages/utils/src/utils/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,17 @@ export const paths = {
byNamespace() {
return byNamespace({ path: '/triggertemplates' });
}
},
taskRunsByResults: {
all() {
return '/results/taskruns';
},
byNamespace() {
return byNamespace({ path: '/results/taskruns' });
},
byUID() {
return byNamespace({ path: '/results/taskruns/:resultuid/:recorduid' });
}
}
};

Expand Down
7 changes: 4 additions & 3 deletions pkg/endpoints/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ func (o Options) GetTriggersNamespace() string {

// Resource is a wrapper around all necessary clients and config used for endpoints
type Resource struct {
Config *rest.Config
K8sClient k8sclientset.Interface
Options Options
Config *rest.Config
K8sClient k8sclientset.Interface
Options Options
ResultsConfig *rest.Config
}
23 changes: 17 additions & 6 deletions pkg/router/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ func makeUpgradeTransport(config *rest.Config, keepalive time.Duration) (proxy.U
}

// Register returns a HTTP handler with the Dashboard and Kubernetes APIs registered
func Register(r endpoints.Resource, cfg *rest.Config) (*Server, error) {
func Register(r endpoints.Resource, cfg *rest.Config, resultsCfg *rest.Config) (*Server, error) {
logging.Log.Info("Adding Kube API")
apiProxyPrefix := "/api/"
apisProxyPrefix := "/apis/"
Expand All @@ -134,6 +134,14 @@ func Register(r endpoints.Resource, cfg *rest.Config) (*Server, error) {
mux.Handle(apiProxyPrefix, proxyHandler)
mux.Handle(apisProxyPrefix, proxyHandler)

logging.Log.Info("Adding Results API")
resultsApiProxyPrefix := "/apis/results.tekton.dev/"
resultsProxyHandler, err := NewProxyHandler(resultsCfg, 30*time.Second)
if err != nil {
return nil, err
}
mux.Handle(resultsApiProxyPrefix, resultsProxyHandler)

logging.Log.Info("Adding Dashboard APIs")
registerWeb(r, mux)
registerPropertiesEndpoint(r, mux)
Expand All @@ -158,14 +166,17 @@ func NewProxyHandler(cfg *rest.Config, keepalive time.Duration) (http.Handler, e
responder := &responder{}
transport, err := rest.TransportFor(cfg)
if err != nil {
return nil, err
}
upgradeTransport, err := makeUpgradeTransport(cfg, keepalive)
if err != nil {
logging.Log.Error(err)
return nil, err
}
proxy := proxy.NewUpgradeAwareHandler(target, transport, false, false, responder)
proxy.UpgradeTransport = upgradeTransport
if !cfg.TLSClientConfig.Insecure {
upgradeTransport, err := makeUpgradeTransport(cfg, keepalive)
if err != nil {
return nil, err
}
proxy.UpgradeTransport = upgradeTransport
}
proxy.UseRequestLocation = true
proxy.UseLocationHost = true

Expand Down
9 changes: 8 additions & 1 deletion scripts/installer
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

# dashboard flavour
READONLY="true"
RESULTS_SUPPORT="false"

# configuration default values
DEBUG="false"
Expand Down Expand Up @@ -105,7 +106,9 @@ debug() {
compile() {
local overlay="overlays/installer"

if [ "$READONLY" == "true" ]; then
if [ "$RESULTS_SUPPORT" == "true" ]; then
overlay="$overlay/results"
elif [ "$READONLY" == "true" ]; then
overlay="$overlay/read-only"
else
overlay="$overlay/read-write"
Expand Down Expand Up @@ -409,6 +412,7 @@ help () {
echo -e "\t[--tenant-namespaces <namespaces>]\tWill limit the visibility to the specified comma-separated namespaces only"
echo -e "\t[--triggers-namespace <namespace>]\tOverride the namespace where Tekton Triggers is installed (defaults to Dashboard install namespace)"
echo -e "\t[--version <version>]\t\t\tWill download manifests for specified version or build everything using kustomize/ko"
echo -e "\t[--enable-results]\t\t\tWill build manifests that enable Tekton Results support"
}

# cleanup temporary files
Expand Down Expand Up @@ -536,6 +540,9 @@ while [[ $# -gt 0 ]]; do
'--preserve-import-paths')
KO_RESOLVE_OPTIONS="$KO_RESOLVE_OPTIONS --preserve-import-paths"
;;
'--enable-results')
RESULTS_SUPPORT="true"
;;
*)
echo "ERROR: Unknown option $1"
help
Expand Down
6 changes: 6 additions & 0 deletions src/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { get, getAPIRoot, post } from './comms';
import {
apiRoot,
getKubeAPI,
getLogAPI,
getTektonPipelinesAPIVersion,
isLogTimestampsEnabled,
tektonAPIGroup,
Expand Down Expand Up @@ -178,6 +179,11 @@ export function getPodLog({ container, name, namespace, stream }) {
return get(uri, { Accept: 'text/plain,*/*' }, { stream });
}

export function getLogByResultsAPI({ namespace, resultUID, recordUID }) {
const uri = getLogAPI({ namespace, resultUID, recordUID });
return get(uri, { Accept: 'text/plain,*/*' }, { stream: false });
}

export function importResources({
importerNamespace,
labels,
Expand Down
Loading