As we reevaluate how to best support and maintain Staging Ref in the future, we encourage development teams using this environment to highlight their use cases in the following issue: https://gitlab.com/gitlab-com/gl-infra/software-delivery/framework/software-delivery-framework-issue-tracker/-/issues/36.

Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • idrozdov/gitlab-shell
  • mmj/gitlab-shell
2 results
Show changes
Commits on Source (1006)
*.log
*.swp
.DS_Store
.GOPATH
.bundle
.bundle/
.gitlab_shell_secret
.idea
/*.log*
/bin/check
/bin/gitlab-shell
/bin/gitlab-shell-authorized-keys-check
/bin/gitlab-shell-authorized-principals-check
/bin/gitlab-sshd
/bin/*
/gl-code-quality-report.json
/go_build
/support/bin/golangci-*
/support/bin/gotestsum-*
authorized_keys.lock
config.yml
cover.out
cover.xml
custom_hooks
hooks/*.d
tags
tmp/*
vendor
.DS_Store
Loading
Loading
@@ -3,13 +3,29 @@ include:
- template: Security/SAST.gitlab-ci.yml
- template: Security/Dependency-Scanning.gitlab-ci.yml
- template: Security/Secret-Detection.gitlab-ci.yml
- project: 'gitlab-org/quality/pipeline-common'
file:
- '/ci/danger-review.yml'
stages:
- prepare
- lint
- test
- post-test
variables:
FF_USE_FASTZIP: 'true'
TRANSFER_METER_FREQUENCY: "1s"
DOCKER_VERSION: "20.10.15"
BUNDLE_FROZEN: "true"
GO_VERSION: "1.23"
GOPATH: $CI_PROJECT_DIR/.GOPATH
DEBIAN_VERSION: "bookworm"
RUBY_VERSION: "3.2.5"
BUNDLE_PATH: vendor/ruby
POLICY: pull
CI_DEBUG_SERVICES: 'true'
RUST_VERSION: "1.73"
UBI_VERSION: "8.6"
IMAGE_TAG: "rubygems-3.5-git-2.45-exiftool-12.60"
GITLAB_ADVANCED_SAST_ENABLED: 'true'
workflow:
rules: &workflow_rules
Loading
Loading
@@ -20,8 +36,15 @@ workflow:
# For tags, create a pipeline.
- if: '$CI_COMMIT_TAG'
.rules:go-changes:
rules:
- changes:
- 'go.mod'
- 'go.sum'
- '**/*.go'
default:
image: golang:1.14
image: registry.gitlab.com/gitlab-org/gitlab-build-images/debian-${DEBIAN_VERSION}-ruby-${RUBY_VERSION}-golang-${GO_VERSION}-rust-${RUST_VERSION}:${IMAGE_TAG}
tags:
- gitlab-org
Loading
Loading
@@ -33,17 +56,78 @@ default:
# See https://gitlab.com/gitlab-com/www-gitlab-com/-/issues/7019 for tag descriptions
- gitlab-org-docker
.test:
.cached-go: &cached_go
- key:
prefix: "golang-${GO_VERSION}-cache"
files:
- go.mod
- go.sum
policy: $POLICY
paths:
- .GOPATH/pkg/mod/
.cached-ruby: &cached_ruby
- key:
prefix: "ruby-${RUBY_VERSION}-cache"
files:
- Gemfile.lock
policy: $POLICY
paths:
- ${BUNDLE_PATH}
.cached-go-job:
variables:
CACHE_COMPRESSION_LEVEL: "fastest"
cache:
- *cached_go
.cached-ruby-job:
cache:
- *cached_ruby
.cached-job:
cache:
- *cached_go
- *cached_ruby
.go-matrix-job:
parallel:
matrix:
- GO_VERSION: ["1.22", "1.23"]
################################################################################
# Prepare jobs
################################################################################
bundle:install:
stage: prepare
extends: .cached-ruby-job
variables:
POLICY: pull-push
script:
- bundle install --jobs $(nproc)
modules:download:
stage: prepare
extends:
- .cached-go-job
- .go-matrix-job
variables:
POLICY: pull-push
script:
- go mod download
################################################################################
# Test jobs
################################################################################
.test-job:
needs: ['bundle:install', 'modules:download']
rules: !reference [".rules:go-changes", rules]
variables:
GITALY_CONNECTION_INFO: '{"address":"tcp://gitaly:8075", "storage":"default"}'
before_script:
# Set up the environment to run integration tests (still written in Ruby)
- apt-get update -qq && apt-get install -y ruby ruby-dev
- ruby -v
- export PATH=~/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin
- gem install --force --bindir /usr/local/bin bundler -v 2.3.6
- bundle install
# Now set up to run the Golang tests
- make build
- cp config.yml.example config.yml
- go version
Loading
Loading
@@ -51,32 +135,61 @@ default:
services:
- name: registry.gitlab.com/gitlab-org/build/cng/gitaly:master
# Disable the hooks so we don't have to stub the GitLab API
command: ["bash", "-c", "mkdir -p /home/git/repositories && rm -rf /srv/gitlab-shell/hooks/* && exec /usr/bin/env GITALY_TESTING_NO_GIT_HOOKS=1 /scripts/process-wrapper"]
command: ["bash", "-c", "mkdir -p /home/git/repositories && rm -rf /srv/gitlab-shell/hooks/* && touch /srv/gitlab-shell/.gitlab_shell_secret && exec /usr/bin/env GITALY_TESTING_NO_GIT_HOOKS=1 /scripts/process-wrapper"]
alias: gitaly
script:
- make verify test
tests:
extends: .test
image: golang:${GO_VERSION}
parallel:
matrix:
- GO_VERSION: ["1.17", "1.18", "1.19"]
extends:
- .cached-job
- .go-matrix-job
- .test-job
script:
- make verify test_fancy
after_script:
- make coverage
coverage: '/\d+.\d+%/'
artifacts:
when: always
paths:
- cover.xml
reports:
junit: cover.xml
tests_without_cgo:
extends:
- .cached-job
- .go-matrix-job
- .test-job
variables:
CGO_ENABLED: 0
script:
- make verify test_fancy
tests:fips:
image: registry.gitlab.com/gitlab-org/gitlab-build-images/ubi-${UBI_VERSION}-ruby-${RUBY_VERSION}-golang-${GO_VERSION}-rust-${RUST_VERSION}:${IMAGE_TAG}
extends:
- .cached-job
- .test-job
variables:
FIPS_MODE: 1
script:
- make test_fancy
race:
extends: .test
image: golang:1.18
extends:
- .cached-go-job
- .go-matrix-job
- .test-job
script:
- make test_golang_race
code_quality:
stage: lint
extends: .use-docker-in-docker
rules: *workflow_rules
code_navigation:
stage: post-test
image: sourcegraph/lsif-go:v1.9
allow_failure: true
script:
Loading
Loading
@@ -87,12 +200,84 @@ code_navigation:
# SAST
semgrep-sast:
stage: lint
rules: *workflow_rules
gitlab-advanced-sast:
stage: lint
rules: *workflow_rules
# Dependency Scanning
gemnasium-dependency_scanning:
stage: lint
rules: *workflow_rules
# Secret Detection
secret_detection:
stage: lint
rules: *workflow_rules
build-package-and-qa:
stage: post-test
trigger:
project: 'gitlab-org/build/omnibus-gitlab-mirror'
branch: 'master'
strategy: depend
inherit:
variables: false
variables:
GITLAB_SHELL_VERSION: $CI_MERGE_REQUEST_SOURCE_BRANCH_SHA
TOP_UPSTREAM_SOURCE_PROJECT: $CI_PROJECT_PATH
TOP_UPSTREAM_SOURCE_REF: $CI_COMMIT_REF_NAME
TOP_UPSTREAM_SOURCE_JOB: $CI_JOB_URL
ee: "true"
rules:
# For MRs that change dependencies, we want to automatically ensure builds
# aren't broken. In such cases, we don't want the QA tests to be run
# automatically, but still available for developers to manually run.
- if: '$CI_MERGE_REQUEST_IID'
changes:
- go.sum
variables:
BUILD_ON_ALL_OS: "true"
MANUAL_QA_TEST: "true"
allow_failure: false
# For other MRs, we still provide this job as a manual job for developers
# to obtain a package for testing and run QA tests.
- if: '$CI_MERGE_REQUEST_IID'
when: manual
allow_failure: true
needs: []
modules:tidy:
stage: lint
needs: ['modules:download']
script:
- go mod tidy
- git diff --exit-code go.mod go.sum
lint:
stage: lint
script:
# Write the code coverage report to gl-code-quality-report.json
# and print linting issues to stdout in the format: path/to/file:line description
# remove `--issues-exit-code 0` or set to non-zero to fail the job if linting issues are detected
- apt update && apt install -y jq
- make lint GOLANGCI_LINT_ARGS="--out-format code-climate:gl-code-quality-report-temp.json,line-number"
- cat gl-code-quality-report-temp.json | jq '[ .[] | select(.severity == "warning").severity |= "minor" ]' > gl-code-quality-report.json
- rm -f gl-code-quality-report-temp.json
artifacts:
reports:
codequality: gl-code-quality-report.json
paths:
- gl-code-quality-report.json
nilaway:
stage: lint
rules: !reference [".rules:go-changes", rules]
before_script:
- go install go.uber.org/nilaway/cmd/nilaway@latest
script:
- ${GOPATH}/bin/nilaway ./... > /tmp/out.txt 2>&1 || true
- cat /tmp/out.txt
allow_failure: true
* @ashmckenzie @igor.drozdov @patrickbajao
# https://gitlab.com/groups/gitlab-org/maintainers/gitlab-shell/-/group_members?with_inherited_permissions=exclude
* @gitlab-org/maintainers/gitlab-shell
[Documentation]
*.md @aqualls
[Documentation] @gl-docsteam
*.md
/doc/
# This file contains all available configuration options
# with their default values.
# options for analysis running
run:
# default concurrency is a available CPU number
# concurrency: 4
# timeout for analysis, e.g. 30s, 5m, default is 1m
timeout: 30m
# exit code when at least one issue was found, default is 1
issues-exit-code: 1
# include test files or not, default is true
tests: true
# list of build tags, all linters use it. Default is empty list.
# build-tags:
# - mytag
# which dirs to skip: issues from them won't be reported;
# can use regexp here: generated.*, regexp is applied on full path;
# default value is empty list, but default dirs are skipped independently
# from this option's value (see skip-dirs-use-default).
# skip-dirs:
# - src/external_libs
# - autogenerated_by_my_lib
# default is true. Enables skipping of directories:
# vendor$, third_party$, testdata$, examples$, Godeps$, builtin$
skip-dirs-use-default: true
# which files to skip: they will be analyzed, but issues from them
# won't be reported. Default value is empty list, but there is
# no need to include all autogenerated files, we confidently recognize
# autogenerated files. If it's not please let us know.
# skip-files:
# - ".*\\.my\\.go$"
# - lib/bad.go
# by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules":
# If invoked with -mod=readonly, the go command is disallowed from the implicit
# automatic updating of go.mod described above. Instead, it fails when any changes
# to go.mod are needed. This setting is most useful to check that go.mod does
# not need updates, such as in a continuous integration and testing system.
# If invoked with -mod=vendor, the go command assumes that the vendor
# directory holds the correct copies of dependencies and ignores
# the dependency descriptions in go.mod.
# modules-download-mode: readonly|release|vendor
# output configuration options
output:
# colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number"
formats:
- format: line-number
# print lines of code with issue, default is true
print-issued-lines: true
# print linter name in the end of issue text, default is true
print-linter-name: true
sort-results: true
# all available settings of specific linters
linters-settings:
errcheck:
# report about not checking of errors in type assetions: `a := b.(MyStruct)`;
# default is false: such cases aren't reported by default.
check-type-assertions: false
# report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`;
# default is false: such cases aren't reported by default.
check-blank: false
# [deprecated] comma-separated list of pairs of the form pkg:regex
# the regex is used to ignore names within pkg. (default "fmt:.*").
# see https://github.com/kisielk/errcheck#the-deprecated-method for details
# ignore: fmt:.*,io/ioutil:^Read.*
ignore: ''
# path to a file containing a list of functions to exclude from checking
# see https://github.com/kisielk/errcheck#excluding-functions for details
# exclude: /path/to/file.txt
# Disable error checking, as errorcheck detects more errors and is more configurable.
gosec:
exclude:
- "G104"
funlen:
lines: 60
statements: 40
govet:
# report about shadowed variables
enable:
- shadow
# settings per analyzer
settings:
printf: # analyzer name, run `go tool vet help` to see all analyzers
funcs: # run `go tool vet help printf` to see available settings for `printf` analyzer
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf
- (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf
# enable or disable analyzers by name
# enable:
# - atomicalign
# enable-all: false
# disable:
# - shadow
# disable-all: false
gofmt:
# simplify code: gofmt with `-s` option, true by default
simplify: true
goimports:
# put imports beginning with prefix after 3rd-party packages;
# it's a comma-separated list of prefixes
# local-prefixes: github.com/org/project
gocyclo:
# minimal code complexity to report, 30 by default (but we recommend 10-20)
min-complexity: 30
gocognit:
# minimal code complexity to report, 30 by default (but we recommend 10-20)
min-complexity: 20
maligned:
# print struct with more effective memory layout or not, false by default
suggest-new: true
dupl:
# tokens count to trigger issue, 150 by default
threshold: 100
goconst:
# minimal length of string constant, 3 by default
min-len: 3
# minimal occurrences count to trigger, 3 by default
min-occurrences: 3
depguard:
rules:
test:
files:
- $test
allow:
- $gostd
- github.com/stretchr/testify
- gitlab.com/gitlab-org/gitlab-shell
- gitlab.com/gitlab-org/labkit
- gitlab.com/gitlab-org/gitaly
- github.com/prometheus/client_golang/prometheus
- github.com/pires/go-proxyproto
- github.com/otiai10/copy
- github.com/hashicorp/go-retryablehttp
- github.com/golang-jwt/jwt
- github.com/mikesmitty/edkey
- github.com/sirupsen/logrus
- github.com/grpc-ecosystem/go-grpc-prometheus
- github.com/mattn/go-shellwords
# list-type: blacklist
# include-go-root: false
# packages:
# - github.com/sirupsen/logrus
# packages-with-error-messages:
# # specify an error message to output when a blacklisted package is used
# github.com/sirupsen/logrus: "logging is allowed only by logutils.Log"
misspell:
# Correct spellings using locale preferences for US or UK.
# Default is to use a neutral variety of English.
# Setting locale to US will correct the British spelling of 'colour' to 'color'.
locale: US
ignore-words:
- GitLab
lll:
# max line length, lines longer will be reported. Default is 120.
# '\t' is counted as 1 character by default, and can be changed with the tab-width option
line-length: 120
# tab width in spaces. Default to 1.
tab-width: 1
unused:
# treat code as a program (not a library) and report unused exported identifiers; default is false.
# XXX: if you enable this setting, unused will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find funcs usages. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
check-exported: false
unparam:
# Inspect exported functions, default is false. Set to true if no external program/library imports your code.
# XXX: if you enable this setting, unparam will report a lot of false-positives in text editors:
# if it's called for subdir of a project it can't find external interfaces. All text editor integrations
# with golangci-lint call it on a directory with the changed file.
check-exported: false
nakedret:
# make an issue if func has more lines of code than this setting and it has naked returns; default is 30
max-func-lines: 30
prealloc:
# XXX: we don't recommend using this linter before doing performance profiling.
# For most programs usage of prealloc will be a premature optimization.
# Report preallocation suggestions only on simple loops that have no returns/breaks/continues/gotos in them.
# True by default.
simple: true
range-loops: true # Report preallocation suggestions on range loops, true by default
for-loops: false # Report preallocation suggestions on for loops, false by default
gocritic:
# Which checks should be enabled; can't be combined with 'disabled-checks';
# See https://go-critic.github.io/overview#checks-overview
# To check which checks are enabled run `GL_DEBUG=gocritic golangci-lint run`
# By default list of stable checks is used.
# enabled-checks:
# - rangeValCopy
# Which checks should be disabled; can't be combined with 'enabled-checks'; default is empty
# disabled-checks:
# - regexpMust
# Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks.
# Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags".
# enabled-tags:
# - performance
settings: # settings passed to gocritic
captLocal: # must be valid enabled check name
paramsOnly: true
# rangeValCopy:
# sizeThreshold: 32
godox:
# report any comments starting with keywords, this is useful for TODO or FIXME comments that
# might be left in the code accidentally and should be resolved before merging
keywords: # default keywords are TODO, BUG, and FIXME, these can be overwritten by this setting
- TODO
- BUG
- FIXME
- NOTE
- OPTIMIZE # marks code that should be optimized before merging
- HACK # marks hack-arounds that should be removed before merging
dogsled:
# checks assignments with too many blank identifiers; default is 2
max-blank-identifiers: 2
whitespace:
multi-if: false # Enforces newlines (or comments) after every multi-line if statement
multi-func: false # Enforces newlines (or comments) after every multi-line function signature
wsl:
# If true append is only allowed to be cuddled if appending value is
# matching variables, fields or types on line above. Default is true.
strict-append: true
# Allow calls and assignments to be cuddled as long as the lines have any
# matching variables, fields or types. Default is true.
allow-assign-and-call: true
# Allow multiline assignments to be cuddled. Default is true.
allow-multiline-assign: true
# Allow declarations (var) to be cuddled.
allow-cuddle-declarations: false
# Allow trailing comments in ending of blocks
allow-trailing-comment: false
# Force newlines in end of case at this limit (0 = never).
force-case-trailing-whitespace: 0
linters:
# please, do not use `enable-all`: it's deprecated and will be removed soon.
# inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint
disable-all: true
enable:
- bodyclose
- copyloopvar
- depguard
- dogsled
- dupl
- errcheck
- funlen
- gocognit
- goconst
- gocritic
- godox
- gofmt
- goimports
- gosec
- gosimple
- govet
- ineffassign
- misspell
- nakedret
- revive
- staticcheck
- stylecheck
- testifylint
- typecheck
- unconvert
- unparam
- unused
- whitespace
# don't enable:
# - deadcode
# - gochecknoglobals
# - gochecknoinits
# - gocyclo
# - lll
# - maligned
# - prealloc
# - varcheck
issues:
# List of regexps of issue texts to exclude, empty list by default.
# But independently from this option we use default exclude patterns,
# it can be disabled by `exclude-use-default: false`. To list all
# excluded by default patterns execute `golangci-lint run --help`
# exclude:
# - abcdef
# Excluding configuration per-path, per-linter, per-text and per-source
exclude-rules:
# Exclude some linters from running on tests files.
- path: _test\.go
linters:
- gocyclo
- errcheck
- dupl
- gosec
- funlen
# Exclude known linters from partially hard-vendored code,
# which is impossible to exclude via "nolint" comments.
# - path: internal/hmac/
# text: "weak cryptographic primitive"
# linters:
# - gosec
# Exclude some staticcheck messages
# - linters:
# - staticcheck
# text: "SA9003:"
# Exclude lll issues for long lines with go:generate
- linters:
- lll
source: "^//go:generate "
# Independently from option `exclude` we use default exclude patterns,
# it can be disabled by this option. To list all
# excluded by default patterns execute `golangci-lint run --help`.
# Default value for this option is true.
exclude-use-default: false
# Maximum issues count per one linter. Set to 0 to disable. Default is 50.
max-issues-per-linter: 0
# Maximum count of issues with the same text. Set to 0 to disable. Default is 3.
max-same-issues: 0
# Show only new issues: if there are unstaged changes or untracked files,
# only those changes are analyzed, else only changes in HEAD~ are analyzed.
# It's a super-useful option for integration of golangci-lint into existing
# large codebase. It's not practical to fix all existing issues at the moment
# of integration: much better don't allow issues in new code.
# Default is false.
new: false
# Show only new issues created after git revision `REV`
# This should be passed as flag during individual CI jobs.
# new-from-rev: REV
# Show only new issues created in git patch with set file path.
# new-from-patch: path/to/patch/file
2.7.5
3.3.4
ruby 2.7.5
golang 1.18.7
ruby 3.3.5
golang 1.23.2
v14.39.0
- Revise CODEOWNERS to use entire TW team !1125
- Rename bin/check to bin/gitlab-shell-check to to avoid name clash !801
- Update golangci to 1.60.1 !1122
- Move bin/install to support/make_necessary_dirs !799
- Update dependency golang to v1.23.0 !1121
- Use go build so we can use -o !1117
- Add 'make make_necessary_dirs' alias !1119
- Add GitLab Advanced SAST to CI/CD config !1120
- Update github.com/charmbracelet/git-lfs-transfer digest to 2cab0ea !1118
- Update module golang.org/x/crypto to v0.26.0 !1115
- Update dependency golang to v1.22.6 !1116
- Update github.com/charmbracelet/git-lfs-transfer digest to c3aa24b !1113
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.11.8 !1114
- Update module golang.org/x/sync to v0.8.0 !1112
v14.38.0
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.11.7 !1110
- Add basic LFS connections metric for SSH !1107
- Update module google.golang.org/grpc to v1.65.0 !1098
- Add basic LFS connections metric for HTTP !1108
- Remove migration section as no longer supported !1106
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.11.6 !1104
- Update dependency ruby to v3.3.4 !1102
- Update Ruby to 3.3.4 !1105
- Update module golang.org/x/crypto to v0.25.0 !1100
- Update github.com/charmbracelet/git-lfs-transfer digest to bacbfdb !1101
- Restructure CI jobs !1097
- Update dependency golang to v1.22.5 !1099
v14.37.0
- Update dependency danger-review to v1.4.1 !1095
- Allow pure_ssh_protocol to be set !1093
- Update dependency gitlab-dangerfiles to '~> 4.8.0' !1094
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.11.5 !1091
- Update dependency danger-review to v1.4.0 !1090
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.11.4 !1085
- Update golangci to 1.59.1 !1089
v14.36.0
- Use the danger-review component !1086
- Update module google.golang.org/protobuf to v1.34.2 !1083
- Geo: Replace Git over HTTP calls with Workhorse HTTP endpoint for SSH pull !1081
- Update github.com/charmbracelet/git-lfs-transfer digest to 0ffd62e !1080
- Update dependency golang to v1.22.4 !1079
- Update module golang.org/x/crypto to v0.24.0 !1078
- Update golang default to 1.22 !1077
- Geo: Replace Git over HTTP calls with Workhorse HTTP endpoint for SSH push !1076
- Update module github.com/hashicorp/go-retryablehttp to v0.7.7 !1074
- Update CI image to latest one !1073
- Update module golang.org/x/sync to v0.7.0 !1072
- git-lfs-transfer: Add support for lock and unlocking of files !1071
- Update golangci to 1.58.2 !1069
- Update github.com/charmbracelet/git-lfs-transfer digest to 4ef8f58 !1067
- Continue work on Git LFS over SSH !1066
- Update module google.golang.org/grpc to v1.64.0 !1065
- Update module github.com/prometheus/client_golang to v1.19.1 !1063
- Update module github.com/hashicorp/go-retryablehttp to v0.7.6 !1061
- Update dependency golang to v1.22.3 !1060
- Update golangci to 1.58.1 !1057
- Update module google.golang.org/protobuf to v1.34.1 !1056
- Update module golang.org/x/crypto to v0.23.0 !1055
- Update github.com/charmbracelet/git-lfs-transfer digest to cc13460 !1054
- Add configuration objects to PAT token !1053
- Update module google.golang.org/protobuf to v1.34.0 !1052
- Fix lint issues for sshd server_config !1043
- Resolve `make lint` (golangci-lint) issues for `internal/sshd/sshd.go` and `internal/sshd/sshd_test.go` !1040
- Update github.com/charmbracelet/git-lfs-transfer digest to 9e9a21d !1038
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.11.3 !1037
- Resolve `make lint` (golangci-lint) issues for `internal/command/uploadarchive/uploadarchive.go` and `internal/command/uploadarchive/uploadarchive_test.go` !1034
- Resolve `make lint` (golangci-lint) issues for `internal/command/uploadpack/uploadpack.go` and `internal/command/uploadpack/uploadpack_test.go` !1033
- Resolve `make lint` (golangci-lint) issues for `internal/sshd/session.go` and `internal/sshd/session_test.go` !1032
- Resolve `make lint` (golangci-lint) issues for `internal/gitlabnet/authorizedkeys/client.go` and `internal/gitlabnet/authorizedkeys/client_test.go` !1031
- Resolve `make lint` (golangci-lint) issues for `internal/command/receivepack/receivepack.go` and `internal/command/receivepack/receivepack_test.go` !1030
- Resolve `make lint` (golangci-lint) issues for `internal/command/lfsauthenticate/lfsauthenticate.go` and `internal/command/lfsauthenticate/lfsauthenticate_test.go !1029
- Update HttpClient method name !1028
- Resolves `make lint` (golangci-lint) issues for `cmd/gitlab-shell-authorized-keys-check/main.go` !1027
- Resolve `make lint` (golangci-lint) issues for `internal/gitlabnet/git/client.go` and `internal/gitlabnet/git/client_test.go` !1026
- Resolve `make lint` (golangci-lint) issues or `internal/command/uploadpack/gitalycall.go` and `internal/command/uploadpack/gitalycall_test.go` !1025
- Resolve `make lint` (golangci-lint) issues for `internal/gitlabnet/twofactorverify/client.go` and `internal/gitlabnet/twofactorverify/client_test.go` !1024
- Resolve `make lint` (golangci-lint) issues for `internal/command/twofactorverify/twofactorverify.go` and `internal/command/twofactorverify/twofactorverify_test.go` !1023
- Resolve `make lint` (golangci-lint) issues for `internal/command/shared/customaction/customaction.go` and `internal/command/shared/customaction/customaction_test.go` !1022
- Resolve `make lint` (golangci-lint) issues for `internal/gitlabnet/accessverifier/client.go` and `internal/gitlabnet/accessverifier/client_test.go` !1021
- Resolve `make lint` (golangci-lint) issues for `cmd/gitlab-shell/command/command.go` and `cmd/gitlab-shell/command/command_test.go` !1020
- Resolve `make lint` (golangci-lint) issues for `internal/gitlabnet/discover/client.go` and `internal/gitlabnet/discover/client_test.go` !1019
- Resolve `make lint` (golangci-lint) issues for `cmd/check/command/command.go` and `cmd/check/command/command_test.go` !1018
- Resolve `make lint` (golangci-lint) issues for `internal/keyline/key_line.go` and `internal/keyline/key_line_test.go` !1017
- Resolve `make lint` (golangci-lint) issues for `internal/gitlabnet/lfsauthenticate/client.go` and `internal/gitlabnet/lfsauthenticate/client_test.go` !1016
- Resolve `make lint` (golangci-lint) issues for `internal/sshenv/sshenv.go` and `internal/sshenv/sshenv_test.go` !1015
- Resolve `make lint` (golangci-lint) issues for `cmd/gitlab-shell-authorized-keys-check/command/command.go` and `cmd/gitlab-shell-authorized-keys-check/command/command_test.go` !1014
- Fix `make lint` (golangci-lint) issues for `client/httpclient.go` and `client/httpsclient_test.go` !1013
- Fix `make lint` (golangci-lint) issues for `internal/handler/exec.go` and `internal/handler/exec_test.go` !1012
- Fix `make lint` (golangci-lint) issues for `internal/gitlabnet/personalaccesstoken/client.go` and `internal/gitlabnet/personalaccesstoken/client_test.go` !1011
- Fix `make lint` (golangci-lint) issues for `client/gitlabnet.go` !1010
- Fixes `make lint` (golangci-lint) issues for `internal/gitlabnet/twofactorrecover/client.go` and `internal/gitlabnet/twofactorrecover/client_test.go` !1009
- Fix `make lint` (golangci-lint) issues for `internal/sshd/connection.go` and `internal/sshd/connection_test.go` !1008
- Fix `make lint` (golangci-lint) issues for `internal/console/console.go` and `internal/console/console_test.go` !1007
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.11.0 !1006
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.10.3 !1005
- Fix golanci shadow warning !1004
- Fix lint issues in requesthandlers.go !1003
- Resolve Use golang-1.21 for GO_VERSION in CI !1001
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.10.2 !997
- Update github.com/charmbracelet/git-lfs-transfer digest to 3263d2f !996
- Update module golang.org/x/crypto to v0.22.0 !995
- Extend shell logs with additional metadata !991
- git-lfs-transfer: Add support for batch upload and get object !989
v14.35.0
- sshd: limit server_host_key_algorithms in server config !986
- Update github.com/charmbracelet/git-lfs-transfer digest to f0b226f !990
- Update module google.golang.org/grpc to v1.63.2 !993
- Update dependency golang to v1.22.2 !992
- Update golangci-lint to 1.57.2 !988
- Remove Gitlab-Shared-Secret reference that is no longer used !985
- git-lfs-transfer: Enable in shell and introduce batch download !942
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.10.0 !983
- Update golangci-lint to 1.57.1 !984
- Update github.com/charmbracelet/git-lfs-transfer digest to 6dbff1b !981
- Update dependency gitlab-dangerfiles to '~> 4.7.0' !982
- chore: Fix lint issues in cmd/gitlab-sshd/acceptance_test.go !979
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.9.2 !980
- Update module google.golang.org/protobuf to v1.33.0 !977
- Update module google.golang.org/grpc to v1.62.1 !976
- Update github.com/charmbracelet/git-lfs-transfer digest to 00bfe2e !974
- Update module github.com/golang-jwt/jwt/v5 to v5.2.1 !973
- Update module golang.org/x/crypto to v0.21.0 !972
- chore: Fixed lint issues in internal/testhelper/testhelper.go !978
- Update dependency golang to v1.22.1 !975
- Update module github.com/stretchr/testify to v1.9.0 !970
- Update github.com/charmbracelet/git-lfs-transfer digest to 3853b28 !968
- Update github.com/charmbracelet/git-lfs-transfer digest to df8ee50 !971
- Update module golang.org/x/crypto to v0.20.0 !966
- Update module github.com/prometheus/client_golang to v1.19.0 !967
- Update module google.golang.org/grpc to v1.62.0 !964
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.9.1 !963
v14.34.0
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.9.0 !960
- Update golangci-lint and gotestsum to latest stable !962
- Also test against go 1.22 !949
- Update dependency golang to v1.22.0 !952
- Update module google.golang.org/grpc to v1.61.1 !961
- Update github.com/charmbracelet/git-lfs-transfer digest to e8645ad !959
- Update github.com/charmbracelet/git-lfs-transfer digest to 8d8e152 !957
- Upgrade to using bookworm instead of bullseye !956
- Update GOLANGCI_LINT_VERSION to 1.56.1 !958
- Update golangci lint to v1.56.0 !954
- Set random correlation ID in uploadarchive test !955
- Update module golang.org/x/crypto to v0.19.0 !953
- Use GracefulStop() instead of Stop() !951
- Update dependency rspec to '~> 3.13.0' !947
- Fix scanner findings error !948
- Log error instead of warning when parsing keys !944
- Fix PureSSHProtocal name typo !945
- Update github.com/charmbracelet/git-lfs-transfer digest to 732ff5e !943
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.9.0-rc3 !941
- Run CI with FIPS_MODE enabled !940
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.8.1 !939
- Update module google.golang.org/grpc to v1.61.0 !937
- New lfs.pure_ssh_protocol setting !936
- Update local Ruby version !938
v14.33.0
- Load gssapi lib per server/connection !934
- Update module google.golang.org/grpc to v1.60.0 !912
- Expose error messages for failed Git operations !906
- Update module google.golang.org/protobuf to v1.32.0 !918
- Ensure build tags are used when testing !921
- Update module golang.org/x/sync to v0.6.0 !922
- Update module golang.org/x/crypto to v0.18.0 !923
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.8.0 !932
v14.32.0
- Geo: Add `done` pktline when git clone --depth option is given !905
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.6.1 !907
- Update module github.com/golang-jwt/jwt/v5 to v5.2.0 !908
- Update module golang.org/x/crypto to v0.16.0 !904
- Replace os.MkdirTemp() usages with t.TempDir() !909
- Update dependency golang to v1.21.5 !911
v14.31.0
- Update dependency gitlab-dangerfiles to '~> 4.6.0' !887
- Update module golang.org/x/crypto to v0.15.0 !884
- Revert workaround to start gitaly service in test !891
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.6.0 !890
- Remove the RPC call for Namespace removal !895
- Update module gitlab.com/gitlab-org/labkit to v1.21.0 !892
- Revert sending SSH certificate as a separate protocol !894
- Bump GO_VERSION to 1.21 !898
- Drop support for go 1.19 !899
- Move global tempDir into StartSocketHttpServer() !902
- New nilaway CI job !897
- Resolve "Remove NilAway detections for 'client' package" !896
- call git_autid_event during git pull/clone if in need !888
v14.30.1
- Update dependency golang to v1.21.4 !881
- Update module github.com/golang-jwt/jwt/v5 to v5.1.0 !882
- Set CI_DEBUG_SERVICES: true to assist debugging !883
- Update module github.com/hashicorp/go-retryablehttp to v0.7.5 !885
v14.30.0
- Disable GSSAPI when CGO is enabled to support DNS resolution !866
- Add log for public key authentication type !870
- Update dependency golang to v1.21.3 !867
- Update dependency gitlab-dangerfiles to '~> 4.3.2' !871
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.5.0 !873
- Update module google.golang.org/grpc to v1.59.0 !872
- Update dependency gitlab-dangerfiles to '~> 4.4.0' !874
- Update dependency gitlab-dangerfiles to '~> 4.5.1' !876
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.5.1 !877
- Update module golang.org/x/sync to v0.5.0 !879
- Fix race conditions in GSSAPI calls !875
v14.29.0
- Update module google.golang.org/grpc to v1.58.2 !850
- Update dependency gitlab-dangerfiles to v4 !852
- Optimize Ruby and Go job caching !805
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.4.0 !853
- Update module github.com/prometheus/client_golang to v1.17.0 !854
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.4.1 !856
- Update dependency gitlab-dangerfiles to '~> 4.1.0' !857
- Always return stdin/stdout errors !847
- Update module golang.org/x/sync to v0.4.0 !860
- Update dependency golang to v1.21.2 !862
- Removes module github.com/grpc-ecosystem/go-grpc-middleware !859
- Update module github.com/otiai10/copy to v1.14.0 !858
- Update module golang.org/x/crypto to v0.14.0 !861
- Allow only git commands for auth via SSH certs !864
- Send ssh_certificates as protocol !863
- Update module google.golang.org/grpc to v1.58.3 !868
v14.28.0
- Add PullCommand to githttp package !836
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.3.3 !849
- Fix `make lint` on aarch64 platforms !848
- Update dependency golang to v1.21.1 !844
- Update module google.golang.org/grpc to v1.58.0 !845
- Add golangci-lint to CI job !839
- Update module golang.org/x/crypto to v0.13.0 !842
v14.27.0
- Workaround to allow gitaly service to start !838
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.3.1 !837
- Resolve "GitLab sshd should include data transfer bytes in logs" !831
- Update dependency golang to v1.21.0 !828
- Log metadata refactor !832
- Support authentication using SSH Certificates !812
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.3.0 !833
- Implement geo_proxy_direct_to_primary feature flag !834
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.2.4 !830
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.2.2 !818
- Add Go v1.21 to CI !829
v14.26.0
- Include error and log as Error when recovering !825
- Fix the established session metric !826
- Require Go 1.19 and drop use of golang-crypto fork !806
- Update dependency gitlab-dangerfiles to '~> 3.13.0' !824
- Create gotestsum in support/bin and ignore !825
v14.25.0
- Ensure context is not nil before processing !820
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.2.1 !814
- Update module google.golang.org/grpc to v1.57.0 !815
- Update module gitlab.com/gitlab-org/labkit to v1.20.0 !817
- Update dependency golang to v1.20.7 !819
v14.24.1
- Return metadata context without using channels !810
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.2.0 !813
- Update dependency gitlab-dangerfiles to '~> 3.12.0' !811
v14.24.0
- Bump golang to 1.20.6 !808
- Ensure all binaries respond to -version !800
- Update module google.golang.org/grpc to v1.56.2 !804
- Update module golang.org/x/crypto to v0.11.0 !803
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.1.2 !802
- Add support for gotestsum !796
- Log 'access: finish' line with additional metadata !783
- Ensure prometheus counter has time to increment !795
- Use both go and ruby cache for test jobs !793
- Split caching of go and ruby jobs !792
- Optimise Ruby and Go based CI jobs !787
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.1.1 !794
- Update module google.golang.org/protobuf to v1.31.0 !789
- Update dependency gitlab-dangerfiles to '~> 3.11.0' !788
- New modules:tidy and modules:download jobs !784
- Update module google.golang.org/grpc to v1.56.1 !786
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.1.0 !785
- Tidy up go.mod and go.sum !781
- Create a 'msg: "access"' log entry at the completion of work, including a `duration_s` field !782
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.0.5 !779
- Update module github.com/otiai10/copy to v1.12.0 !780
- Ensure test cache is not used for 'go test' !778
- Update module google.golang.org/grpc to v1.56.0 !777
- Update module github.com/prometheus/client_golang to v1.16.0 !776
- Update module gitlab.com/gitlab-org/labkit to v1.19.0 !771
- Update module golang.org/x/sync to v0.3.0 !775
- Update module golang.org/x/crypto to v0.10.0 !774
- Update Ruby dependencies !773
- Update module gitlab.com/gitlab-org/gitaly/v16 to v16.0.4 !772
- Update dependency golang to v1.20.5 !768
- Use gitlab-shell maintainers group instead for CODEOWNERS !770
- Update module github.com/golang-jwt/jwt/v4 to v5 !759
- Update module github.com/hashicorp/go-retryablehttp to v0.7.4 !767
v14.23.0
- Update module github.com/golang-jwt/jwt/v4 to v5 !759
- Update module gopkg.in/yaml.v2 to v3 !763
- Update module gitlab.com/gitlab-org/gitaly/v15 to v16 !762
- Update logrus to v1.9.3 !760
- Update module golang.org/x/sync to v0.2.0 !757
- Update module github.com/pires/go-proxyproto to v0.7.0 !752
- Update module google.golang.org/grpc to v1.55.0 !758
- Update module github.com/prometheus/client_golang to v1.15.1 !756
- Update module github.com/otiai10/copy to v1.11.0 !751
- Make golang 1.20 the default for gitlab-shell development and CI !750
- Update module golang.org/x/crypto to v0.9.0 !742
- Update dependency golang to v1.20.4 !748
- Update module github.com/hashicorp/go-retryablehttp to v0.7.2 !745
v14.22.0
- Update dependency ruby to v3.2.2 !743
v14.21.0
- Use a separate HTTP Client for Geo requests !739
v14.20.0
- Configure a default ttl for personal access tokens !736
v14.19.0
- Bump go to 1.19.9 !730
- Update golang-crypto fork version !729
- Add build-package-and-qa job !728
- refactor: success api on acceptance tests !727
- Make the boringcrypto check POSIX shell compliant !725
- Fix CGO_CFLAGS to use output from `brew --prefix` !724
- Acceptance test for Geo Push !719
- Configure Gitaly storage acceptance tests !723
- Prepare for Go 1.19 FIPS support !721
- Make golang 1.19 the default !718
v14.18.0
- Perform HTTP request to primary on Geo push !716
- sshd: exclude gssapi when building without cgo !720
- Add DNS discovery support for Gitaly/Praefect !717
- Add bin/gitlab-sshd as an explicit Makefile target !714
v14.17.0
- Bump golang to 1.18.9 !712
v14.16.0
- feat: make retryable http default client !710
- Add support for the gssapi-with-mic auth method !682
- docs: Truncate pages, point users to GitLab repo !705
v14.15.0
- Incorporate older edits to README !696
- Upgrade to Ruby 3.x !706
- feat: retry on http error !703
v14.14.0
- Add developer documentation to sshd package !683
- Improve error message for Gitaly `LimitError`s !691
- Drop 1.16 compatibility in go.sum !692
- Bump x/text to 0.3.8 !692
- Update prometheus package to 1.13.1 !692
- Restrict IP access for PROXY protocol !693
- Fix broken Gitaly integration tests !694
- Clean up .gitlab-ci.yml file !695
- Use the images provided by Gitlab to run tests !698
- Use Ruby 2.7.7 as the default !699
- Use blocking reader to fix race in test !700
v14.13.0
- Update .tool-versions to Go 1.18.7 !688
Loading
Loading
source 'https://rubygems.org'
group :development, :test do
gem 'rspec', '~> 3.8.0'
gem 'rspec', '~> 3.13.0'
gem 'webrick', '~> 1.8', '>= 1.8.2'
end
group :development, :danger do
gem 'gitlab-dangerfiles', '~> 3.5.1'
gem 'gitlab-dangerfiles', '~> 4.8.0'
end
GEM
remote: https://rubygems.org/
specs:
addressable (2.8.0)
public_suffix (>= 2.0.2, < 5.0)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
bigdecimal (3.1.8)
claide (1.1.0)
claide-plugins (0.9.2)
cork
Loading
Loading
@@ -11,106 +12,94 @@ GEM
colored2 (3.1.2)
cork (0.3.0)
colored2 (~> 3.1)
danger (8.6.1)
csv (3.3.0)
danger (9.4.3)
claide (~> 1.0)
claide-plugins (>= 0.9.2)
colored2 (~> 3.1)
cork (~> 0.1)
faraday (>= 0.9.0, < 2.0)
faraday (>= 0.9.0, < 3.0)
faraday-http-cache (~> 2.0)
git (~> 1.7)
git (~> 1.13)
kramdown (~> 2.3)
kramdown-parser-gfm (~> 1.0)
no_proxy_fix
octokit (~> 4.7)
octokit (>= 4.0)
terminal-table (>= 1, < 4)
danger-gitlab (8.0.0)
danger
gitlab (~> 4.2, >= 4.2.0)
diff-lcs (1.3)
faraday (1.10.1)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
faraday-httpclient (~> 1.0)
faraday-multipart (~> 1.0)
faraday-net_http (~> 1.0)
faraday-net_http_persistent (~> 1.0)
faraday-patron (~> 1.0)
faraday-rack (~> 1.0)
faraday-retry (~> 1.0)
ruby2_keywords (>= 0.0.4)
faraday-em_http (1.0.0)
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-http-cache (2.4.1)
diff-lcs (1.5.1)
faraday (2.9.2)
faraday-net_http (>= 2.0, < 3.2)
faraday-http-cache (2.5.1)
faraday (>= 0.8)
faraday-httpclient (1.0.1)
faraday-multipart (1.0.4)
multipart-post (~> 2)
faraday-net_http (1.0.1)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
faraday-rack (1.0.0)
faraday-retry (1.0.3)
git (1.11.0)
faraday-net_http (3.1.0)
net-http
git (1.19.1)
addressable (~> 2.8)
rchardet (~> 1.8)
gitlab (4.19.0)
gitlab (4.20.1)
httparty (~> 0.20)
terminal-table (>= 1.5.1)
gitlab-dangerfiles (3.5.1)
danger (>= 8.4.5)
gitlab-dangerfiles (4.8.0)
danger (>= 9.3.0)
danger-gitlab (>= 8.0.0)
rake
httparty (0.20.0)
mime-types (~> 3.0)
rake (~> 13.0)
httparty (0.22.0)
csv
mini_mime (>= 1.0.0)
multi_xml (>= 0.5.2)
kramdown (2.4.0)
rexml
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
mime-types (3.4.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2022.0105)
multi_xml (0.6.0)
multipart-post (2.2.3)
mini_mime (1.1.5)
multi_xml (0.7.1)
bigdecimal (~> 3.1)
nap (1.1.0)
net-http (0.4.1)
uri
no_proxy_fix (0.1.2)
octokit (4.25.1)
octokit (6.1.1)
faraday (>= 1, < 3)
sawyer (~> 0.9)
open4 (1.3.4)
public_suffix (4.0.7)
rake (13.0.6)
public_suffix (5.1.1)
rake (13.2.1)
rchardet (1.8.0)
rexml (3.2.5)
rspec (3.8.0)
rspec-core (~> 3.8.0)
rspec-expectations (~> 3.8.0)
rspec-mocks (~> 3.8.0)
rspec-core (3.8.0)
rspec-support (~> 3.8.0)
rspec-expectations (3.8.1)
rexml (3.3.1)
strscan
rspec (3.13.0)
rspec-core (~> 3.13.0)
rspec-expectations (~> 3.13.0)
rspec-mocks (~> 3.13.0)
rspec-core (3.13.0)
rspec-support (~> 3.13.0)
rspec-expectations (3.13.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0)
rspec-mocks (3.8.0)
rspec-support (~> 3.13.0)
rspec-mocks (3.13.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0)
rspec-support (3.8.0)
ruby2_keywords (0.0.5)
rspec-support (~> 3.13.0)
rspec-support (3.13.0)
sawyer (0.9.2)
addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3)
strscan (3.1.0)
terminal-table (3.0.2)
unicode-display_width (>= 1.1.1, < 3)
unicode-display_width (2.2.0)
unicode-display_width (2.5.0)
uri (0.13.0)
webrick (1.8.2)
PLATFORMS
ruby
DEPENDENCIES
gitlab-dangerfiles (~> 3.5.1)
rspec (~> 3.8.0)
gitlab-dangerfiles (~> 4.8.0)
rspec (~> 3.13.0)
webrick (~> 1.8, >= 1.8.2)
BUNDLED WITH
2.3.15
2.5.11
.PHONY: validate verify verify_ruby verify_golang test test_ruby test_golang coverage coverage_golang setup _script_install build compile check clean install
.PHONY: validate verify verify_ruby verify_golang test test_ruby test_golang test_fancy test_golang_fancy coverage coverage_golang setup _script_install make_necessary_dirs build compile check clean install lint
FIPS_MODE ?= 0
GO_SOURCES := $(shell find . -name '*.go')
OS := $(shell uname | tr A-Z a-z)
GO_SOURCES := $(shell git ls-files \*.go)
VERSION_STRING := $(shell git describe --match v* 2>/dev/null || awk '$$0="v"$$0' VERSION 2>/dev/null || echo unknown)
BUILD_TIME := $(shell date -u +%Y%m%d.%H%M%S)
BUILD_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver
GO_TAGS := tracer_static tracer_static_jaeger continuous_profiler_stackdriver
ARCH ?= $(shell uname -m | sed -e 's/x86_64/amd64/' | sed -e 's/aarch64/arm64/')
GOTESTSUM_VERSION := 1.12.0
GOTESTSUM_FILE := support/bin/gotestsum-${GOTESTSUM_VERSION}
GOLANGCI_LINT_VERSION := 1.60.3
GOLANGCI_LINT_FILE := support/bin/golangci-lint-${GOLANGCI_LINT_VERSION}
export GOFLAGS := -mod=readonly
ifeq (${FIPS_MODE}, 1)
# boringcrypto tag is added automatically by golang-fips compiler
BUILD_TAGS += fips
GO_TAGS += fips
# If the golang-fips compiler is built with CGO_ENABLED=0, this needs to be
# explicitly switched on.
export CGO_ENABLED=1
# Go 1.19 now requires GOEXPERIMENT=boringcrypto for FIPS compilation.
# See https://github.com/golang/go/issues/51940 for more details.
BORINGCRYPTO_SUPPORT := $(shell GOEXPERIMENT=boringcrypto go version > /dev/null 2>&1; echo $$?)
ifeq ($(BORINGCRYPTO_SUPPORT), 0)
export GOEXPERIMENT=boringcrypto
endif
endif
ifneq (${CGO_ENABLED}, 0)
GO_TAGS += gssapi
endif
ifeq (${OS}, darwin) # Mac OS
BREW_PREFIX := $(shell brew --prefix 2>/dev/null || echo "/opt/homebrew")
# To be able to compile gssapi library
export CGO_CFLAGS="-I$(BREW_PREFIX)/opt/heimdal/include"
endif
GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(BUILD_TAGS)" -mod=mod
GOBUILD_FLAGS := -ldflags "-X main.Version=$(VERSION_STRING) -X main.BuildTime=$(BUILD_TIME)" -tags "$(GO_TAGS)" -mod=mod
PREFIX ?= /usr/local
build: bin/gitlab-shell
build: compile
validate: verify test
Loading
Loading
@@ -32,40 +61,67 @@ fmt:
test: test_ruby test_golang
test_fancy: test_ruby test_golang_fancy
# The Ruby tests are now all integration specs that test the Go implementation.
test_ruby:
bundle exec rspec --color --format d spec
test_golang:
go test -cover -coverprofile=cover.out ./...
go test -cover -coverprofile=cover.out -count 1 -tags "$(GO_TAGS)" ./...
test_golang_fancy: ${GOTESTSUM_FILE}
@${GOTESTSUM_FILE} --version
@${GOTESTSUM_FILE} --junitfile ./cover.xml --format pkgname -- -coverprofile=./cover.out -covermode=atomic -count 1 -tags "$(GO_TAGS)" ./...
${GOTESTSUM_FILE}:
mkdir -p $(shell dirname ${GOTESTSUM_FILE})
curl -L https://github.com/gotestyourself/gotestsum/releases/download/v${GOTESTSUM_VERSION}/gotestsum_${GOTESTSUM_VERSION}_${OS}_${ARCH}.tar.gz | tar -zOxf - gotestsum > ${GOTESTSUM_FILE} && chmod +x ${GOTESTSUM_FILE}
test_golang_race:
go test -race ./...
go test -race -count 1 ./...
coverage: coverage_golang
coverage_golang:
[ -f cover.out ] && go tool cover -func cover.out
setup: _script_install bin/gitlab-shell
lint:
@support/lint.sh ./...
golangci: ${GOLANGCI_LINT_FILE}
@${GOLANGCI_LINT_FILE} run --issues-exit-code 0 --print-issued-lines=false ${GOLANGCI_LINT_ARGS}
${GOLANGCI_LINT_FILE}:
@mkdir -p $(shell dirname ${GOLANGCI_LINT_FILE})
@curl -L https://github.com/golangci/golangci-lint/releases/download/v${GOLANGCI_LINT_VERSION}/golangci-lint-${GOLANGCI_LINT_VERSION}-${OS}-${ARCH}.tar.gz | tar --strip-components 1 -zOxf - golangci-lint-${GOLANGCI_LINT_VERSION}-${OS}-${ARCH}/golangci-lint > ${GOLANGCI_LINT_FILE} && chmod +x ${GOLANGCI_LINT_FILE}
setup: make_necessary_dirs bin/gitlab-shell
make_necessary_dirs:
support/make_necessary_dirs
compile: bin/gitlab-shell bin/gitlab-sshd
bin:
mkdir -p bin
_script_install:
bin/install
bin/gitlab-shell: bin $(GO_SOURCES)
go build $(GOBUILD_FLAGS) -o $(CURDIR)/bin ./cmd/...
compile: bin/gitlab-shell
bin/gitlab-shell: $(GO_SOURCES)
GOBIN="$(CURDIR)/bin" go install $(GOBUILD_FLAGS) ./cmd/...
bin/gitlab-sshd: bin $(GO_SOURCES)
go build $(GOBUILD_FLAGS) -o $(CURDIR)/bin/gitlab-sshd ./cmd/gitlab-sshd
check:
bin/check
bin/gitlab-shell-check
clean:
rm -f bin/check bin/gitlab-shell bin/gitlab-shell-authorized-keys-check bin/gitlab-shell-authorized-principals-check bin/gitlab-sshd
rm -f bin/*
install: compile
mkdir -p $(DESTDIR)$(PREFIX)/bin/
install -m755 bin/check $(DESTDIR)$(PREFIX)/bin/check
install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/gitlab-shell
install -m755 bin/gitlab-shell-authorized-keys-check $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-keys-check
install -m755 bin/gitlab-shell-authorized-principals-check $(DESTDIR)$(PREFIX)/bin/gitlab-shell-authorized-principals-check
install -m755 bin/gitlab-sshd $(DESTDIR)$(PREFIX)/bin/gitlab-sshd
install -m755 bin/gitlab-shell-check $(DESTDIR)$(PREFIX)/bin/
install -m755 bin/gitlab-shell $(DESTDIR)$(PREFIX)/bin/
install -m755 bin/gitlab-shell-authorized-keys-check $(DESTDIR)$(PREFIX)/bin/
install -m755 bin/gitlab-shell-authorized-principals-check $(DESTDIR)$(PREFIX)/bin/
install -m755 bin/gitlab-sshd $(DESTDIR)$(PREFIX)/bin/
## Releasing a new version
# GitLab Shell process
GitLab Shell is versioned by git tags, and the version used by the Rails
application is stored in
[`GITLAB_SHELL_VERSION`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/GITLAB_SHELL_VERSION).
For each version, there is a raw version and a tag version:
- The **raw version** is the version number. For instance, `15.2.8`.
- The **tag version** is the raw version prefixed with `v`. For instance, `v15.2.8`.
To release a new version of GitLab Shell and have that version available to the
Rails application:
1. Create a merge request to update the [`CHANGELOG`](CHANGELOG) with the
**tag version** and the [`VERSION`](VERSION) file with the **raw version**.
2. Ask a maintainer to review and merge the merge request. If you're already a
maintainer, second maintainer review is not required.
3. Add a new git tag with the **tag version**.
4. Update `GITLAB_SHELL_VERSION` in the Rails application to the **raw
version**. (Note: this can be done as a separate MR to that, or in and MR
that will make use of the latest GitLab Shell changes.)
## Security releases
GitLab Shell is included in the packages we create for GitLab, and each version of GitLab specifies the version of GitLab Shell it uses in the `GITLAB_SHELL_VERSION` file, so security fixes in GitLab Shell are tightly coupled to the [GitLab security release](https://about.gitlab.com/handbook/engineering/workflow/#security-issues) workflow.
For a security fix in GitLab Shell, two sets of merge requests are required:
* The fix itself, in the `gitlab-org/security/gitlab-shell` repository and its backports to the previous versions of GitLab Shell
* Merge requests to change the versions of GitLab Shell included in the GitLab security release, in the `gitlab-org/security/gitlab` repository
The first step could be to create a merge request with a fix targeting `main` in `gitlab-org/security/gitlab-shell`. When the merge request is approved by maintainers, backports targeting previous 3 versions of GitLab Shell must be created. The stable branches for those versions may not exist, feel free to ask a maintainer to create ones. The stable branches must be created out of the GitLab Shell tags/version used by the 3 previous GitLab releases. In order to find out the GitLab Shell version that is used on a particular GitLab stable release, the following steps may be helpful:
```shell
git fetch security 13-9-stable-ee
git show refs/remotes/security/13-9-stable-ee:GITLAB_SHELL_VERSION
```
These steps display the version that is used by `13.9` version of GitLab.
Close to the GitLab security release, a maintainer should merge the fix and backports and cut all the necessary GitLab Shell versions. This allows bumping the `GITLAB_SHELL_VERSION` for `gitlab-org/security/gitlab`. The GitLab merge request will be handled by the general GitLab security release process.
Once the security release is done, a GitLab Shell maintainer is responsible for syncing tags and `main` to the `gitlab-org/gitlab-shell` repository.
This page [has moved into the `gitlab` repository](https://docs.gitlab.com/ee/development/gitlab_shell/process.html).
Loading
Loading
@@ -4,101 +4,48 @@ group: Source Code
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# GitLab Shell
## GitLab Shell handles git SSH sessions for GitLab
GitLab Shell handles git SSH sessions for GitLab and modifies the list of authorized keys.
GitLab Shell is not a Unix shell nor a replacement for Bash or Zsh.
When you access the GitLab server over SSH then GitLab Shell will:
1. Limit you to predefined git commands (git push, git pull).
1. Call the GitLab Rails API to check if you are authorized, and what Gitaly server your repository is on
1. Copy data back and forth between the SSH client and the Gitaly server
If you access a GitLab server over HTTP(S) you end up in [gitlab-workhorse](https://gitlab.com/gitlab-org/gitlab/tree/master/workhorse).
An overview of the four cases described above:
1. git pull over SSH -> gitlab-shell -> API call to gitlab-rails (Authorization) -> accept or decline -> establish Gitaly session
1. git push over SSH -> gitlab-shell (git command is not executed yet) -> establish Gitaly session -> (in Gitaly) gitlab-shell pre-receive hook -> API call to gitlab-rails (authorization) -> accept or decline push
[Full feature list](doc/features.md)
## Code status
[![pipeline status](https://gitlab.com/gitlab-org/gitlab-shell/badges/main/pipeline.svg)](https://gitlab.com/gitlab-org/gitlab-shell/-/pipelines?ref=main)
[![coverage report](https://gitlab.com/gitlab-org/gitlab-shell/badges/main/coverage.svg)](https://gitlab.com/gitlab-org/gitlab-shell/-/pipelines?ref=main)
[![Code Climate](https://codeclimate.com/github/gitlabhq/gitlab-shell.svg)](https://codeclimate.com/github/gitlabhq/gitlab-shell)
## Requirements
GitLab Shell is written in Go, and needs a Go compiler to build. It still requires
Ruby to build and test, but not to run.
Download and install the current version of Go from https://golang.org/dl/
We follow the [Golang Release Policy](https://golang.org/doc/devel/release.html#policy)
of supporting the current stable version and the previous two major versions.
## Rate Limiting
GitLab Shell performs rate-limiting by user account and project for git operations. GitLab Shell accepts git operation requests and then makes a call to the Rails rate-limiter (backed by Redis). If the `user + project` exceeds the rate limit then GitLab Shell will then drop further connection requests for that `user + project`.
The rate-limiter is applied at the git command (plumbing) level. Each command has a rate limit of 600/minute. For example, `git push` has 600/minute and `git pull` has another 600/minute.
# GitLab Shell
Because they are using the same plumbing command `git-upload-pack`, `git pull` and `git clone` are in effect the same command for the purposes of rate-limiting.
GitLab Shell handles Git SSH sessions for GitLab and modifies the list of
authorized keys. GitLab Shell is not a Unix shell nor a replacement for Bash or Zsh.
There is also a rate-limiter in place in Gitaly, but the calls will never be made to Gitaly if the rate limit is exceeded in Gitlab Shell (Rails).
GitLab supports Git LFS authentication through SSH.
## GitLab SaaS
## Development Documentation
A diagram of the flow of `gitlab-shell` on GitLab.com:
Development documentation for GitLab Shell [has moved into the `gitlab` repository](https://docs.gitlab.com/ee/development/gitlab_shell/).
```mermaid
graph LR
a2 --> b2
a2 --> b3
a2 --> b4
b2 --> c1
b3 --> c1
b4 --> c1
c2 --> d1
c2 --> d2
c2 --> d3
d1 --> e1
d2 --> e1
d3 --> e1
a1[Cloudflare] --> a2[TCP<br/> load balancer]
e1[Git]
## Project structure
subgraph HAProxy Fleet
b2[HAProxy]
b3[HAProxy]
b4[HAProxy]
end
| Directory | Description |
|-----------|-------------|
| `cmd/` | 'Commands' that will ultimately be compiled into binaries. |
| `internal/` | Internal Go source code that is not intended to be used outside of the project/module. |
| `client/` | HTTP and GitLab client logic that is used internally and by other modules, e.g. Gitaly. |
| `bin/` | Compiled binaries are created here. |
| `support/` | Scripts and tools that assist in development and/or testing. |
| `spec/` | Ruby based integration tests. |
subgraph GKE
c1[Internal TCP<br/> load balancer<br/>port 2222] --> c2[GitLab-shell<br/> pods]
end
## Building
subgraph Gitaly
d1[Gitaly]
d2[Gitaly]
d3[Gitaly]
end
```
Run `make` or `make build`.
## Releasing
## Testing
See [PROCESS.md](./PROCESS.md)
Run `make test`.
## Contributing
## Release Process
- See [CONTRIBUTING.md](./CONTRIBUTING.md).
- See the [beginner's guide](doc/beginners_guide.md).
1. Create a `gitlab-org/gitlab-shell` MR to update [`VERSION`](https://gitlab.com/gitlab-org/gitlab-shell/-/blob/main/VERSION) and [`CHANGELOG`](https://gitlab.com/gitlab-org/gitlab-shell/-/blob/main/CHANGELOG) files, e.g. [Release v14.39.0](https://gitlab.com/gitlab-org/gitlab-shell/-/merge_requests/1123).
2. Once `gitlab-org/gitlab-shell` MR is merged, create the corresponding git tag, e.g. https://gitlab.com/gitlab-org/gitlab-shell/-/tags/v14.39.0.
3. Create a `gitlab-org/gitlab` MR to update [`GITLAB_SHELL_VERSION`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/GITLAB_SHELL_VERSION) to the proposed tag, e.g. [Bump GitLab Shell to 14.39.0](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/162661).
4. Announce in `#gitlab-shell` a new version has been created.
## License
## Licensing
See [LICENSE](./LICENSE).
See the `LICENSE` file for licensing information as it pertains to files in
this repository.
14.13.0
14.39.0
Loading
Loading
@@ -6,12 +6,14 @@ import (
"fmt"
"io"
"net/http"
"net/http/httptest"
"path"
"strings"
"testing"
"time"
"github.com/golang-jwt/jwt/v4"
"github.com/golang-jwt/jwt/v5"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver"
Loading
Loading
@@ -19,11 +21,12 @@ import (
)
var (
secret = "sssh, it's a secret"
secret = "sssh, it's a secret"
defaultHttpOpts = []HTTPClientOpt{WithHTTPRetryOpts(time.Millisecond, time.Millisecond, 2)}
)
func TestClients(t *testing.T) {
testhelper.PrepareTestRootDir(t)
testRoot := testhelper.PrepareTestRootDir(t)
testCases := []struct {
desc string
Loading
Loading
@@ -34,49 +37,54 @@ func TestClients(t *testing.T) {
}{
{
desc: "Socket client",
server: testserver.StartSocketHttpServer,
server: testserver.StartSocketHTTPServer,
secret: secret,
},
{
desc: "Socket client with a relative URL at /",
relativeURLRoot: "/",
server: testserver.StartSocketHttpServer,
server: testserver.StartSocketHTTPServer,
secret: secret,
},
{
desc: "Socket client with relative URL at /gitlab",
relativeURLRoot: "/gitlab",
server: testserver.StartSocketHttpServer,
server: testserver.StartSocketHTTPServer,
secret: secret,
},
{
desc: "Http client",
server: testserver.StartHttpServer,
server: testserver.StartHTTPServer,
secret: secret,
},
{
desc: "Https client",
caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"),
caFile: path.Join(testRoot, "certs/valid/server.crt"),
server: func(t *testing.T, handlers []testserver.TestRequestHandler) string {
return testserver.StartHttpsServer(t, handlers, "")
return testserver.StartHTTPSServer(t, handlers, "")
},
secret: secret,
},
{
desc: "Secret with newlines",
caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"),
caFile: path.Join(testRoot, "certs/valid/server.crt"),
server: func(t *testing.T, handlers []testserver.TestRequestHandler) string {
return testserver.StartHttpsServer(t, handlers, "")
return testserver.StartHTTPSServer(t, handlers, "")
},
secret: "\n" + secret + "\n",
},
{
desc: "Retry client",
server: testserver.StartRetryHTTPServer,
secret: secret,
},
}
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
url := tc.server(t, buildRequests(t, tc.relativeURLRoot))
httpClient, err := NewHTTPClientWithOpts(url, tc.relativeURLRoot, tc.caFile, "", 1, nil)
httpClient, err := NewHTTPClientWithOpts(url, tc.relativeURLRoot, tc.caFile, "", 1, defaultHttpOpts)
require.NoError(t, err)
client, err := NewGitlabNetClient("", "", tc.secret, httpClient)
Loading
Loading
@@ -233,7 +241,7 @@ func buildRequests(t *testing.T, relativeURLRoot string) []testserver.TestReques
{
Path: "/api/v4/internal/hello",
Handler: func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, http.MethodGet, r.Method)
assert.Equal(t, http.MethodGet, r.Method)
fmt.Fprint(w, "Hello")
},
Loading
Loading
@@ -241,22 +249,16 @@ func buildRequests(t *testing.T, relativeURLRoot string) []testserver.TestReques
{
Path: "/api/v4/internal/post_endpoint",
Handler: func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, http.MethodPost, r.Method)
assert.Equal(t, http.MethodPost, r.Method)
b, err := io.ReadAll(r.Body)
defer r.Body.Close()
require.NoError(t, err)
assert.NoError(t, err)
fmt.Fprint(w, "Echo: "+string(b))
},
},
{
Path: "/api/v4/internal/auth",
Handler: func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, r.Header.Get(secretHeaderName))
},
},
{
Path: "/api/v4/internal/jwt_auth",
Handler: func(w http.ResponseWriter, r *http.Request) {
Loading
Loading
@@ -297,3 +299,22 @@ func buildRequests(t *testing.T, relativeURLRoot string) []testserver.TestReques
return requests
}
func TestRetryOnFailure(t *testing.T) {
reqAttempts := 0
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
reqAttempts++
w.WriteHeader(500)
}))
defer srv.Close()
httpClient, err := NewHTTPClientWithOpts(srv.URL, "/", "", "", 1, defaultHttpOpts)
require.NoError(t, err)
require.NotNil(t, httpClient.RetryableHTTP)
client, err := NewGitlabNetClient("", "", "", httpClient)
require.NoError(t, err)
_, err = client.Get(context.Background(), "/")
require.EqualError(t, err, "Internal API unreachable")
require.Equal(t, 3, reqAttempts)
}
// Package client provides a client for interacting with GitLab API
package client
import (
Loading
Loading
@@ -10,52 +11,53 @@ import (
"strings"
"time"
"github.com/golang-jwt/jwt/v4"
"gitlab.com/gitlab-org/labkit/log"
"github.com/golang-jwt/jwt/v5"
"github.com/hashicorp/go-retryablehttp"
)
const (
internalApiPath = "/api/v4/internal"
secretHeaderName = "Gitlab-Shared-Secret"
apiSecretHeaderName = "Gitlab-Shell-Api-Request"
internalAPIPath = "/api/v4/internal"
apiSecretHeaderName = "Gitlab-Shell-Api-Request" // #nosec G101
defaultUserAgent = "GitLab-Shell"
jwtTTL = time.Minute
jwtIssuer = "gitlab-shell"
)
// ErrorResponse represents an error response from the API
type ErrorResponse struct {
Message string `json:"message"`
}
// GitlabNetClient is a client for interacting with GitLab API
type GitlabNetClient struct {
httpClient *HttpClient
httpClient *HTTPClient
user string
password string
secret string
userAgent string
}
type ApiError struct {
// APIError represents an API error
type APIError struct {
Msg string
}
// To use as the key in a Context to set an X-Forwarded-For header in a request
// OriginalRemoteIPContextKey is used as the key in a Context to set an X-Forwarded-For header in a request
type OriginalRemoteIPContextKey struct{}
func (e *ApiError) Error() string {
func (e *APIError) Error() string {
return e.Msg
}
// NewGitlabNetClient creates a new GitlabNetClient instance
func NewGitlabNetClient(
user,
password,
secret string,
httpClient *HttpClient,
httpClient *HTTPClient,
) (*GitlabNetClient, error) {
if httpClient == nil {
return nil, fmt.Errorf("Unsupported protocol")
return nil, fmt.Errorf("unsupported protocol")
}
return &GitlabNetClient{
Loading
Loading
@@ -78,8 +80,8 @@ func normalizePath(path string) string {
path = "/" + path
}
if !strings.HasPrefix(path, internalApiPath) {
path = internalApiPath + path
if !strings.HasPrefix(path, internalAPIPath) {
path = internalAPIPath + path
}
return path
}
Loading
Loading
@@ -88,7 +90,7 @@ func appendPath(host string, path string) string {
return strings.TrimSuffix(host, "/") + "/" + strings.TrimPrefix(path, "/")
}
func newRequest(ctx context.Context, method, host, path string, data interface{}) (*http.Request, error) {
func newRequest(ctx context.Context, method, host, path string, data interface{}) (*retryablehttp.Request, error) {
var jsonReader io.Reader
if data != nil {
jsonData, err := json.Marshal(data)
Loading
Loading
@@ -99,7 +101,7 @@ func newRequest(ctx context.Context, method, host, path string, data interface{}
jsonReader = bytes.NewReader(jsonData)
}
request, err := http.NewRequestWithContext(ctx, method, appendPath(host, path), jsonReader)
request, err := retryablehttp.NewRequestWithContext(ctx, method, appendPath(host, path), jsonReader)
if err != nil {
return nil, err
}
Loading
Loading
@@ -107,29 +109,44 @@ func newRequest(ctx context.Context, method, host, path string, data interface{}
return request, nil
}
func parseError(resp *http.Response) error {
func parseError(resp *http.Response, respErr error) error {
if resp == nil || respErr != nil {
return &APIError{"Internal API unreachable"}
}
if resp.StatusCode >= 200 && resp.StatusCode <= 399 {
return nil
}
defer resp.Body.Close()
defer func() { _ = resp.Body.Close() }()
parsedResponse := &ErrorResponse{}
if err := json.NewDecoder(resp.Body).Decode(parsedResponse); err != nil {
return &ApiError{fmt.Sprintf("Internal API error (%v)", resp.StatusCode)}
} else {
return &ApiError{parsedResponse.Message}
return &APIError{fmt.Sprintf("Internal API error (%v)", resp.StatusCode)}
}
return &APIError{parsedResponse.Message}
}
// Get makes a GET request
func (c *GitlabNetClient) Get(ctx context.Context, path string) (*http.Response, error) {
return c.DoRequest(ctx, http.MethodGet, normalizePath(path), nil)
}
// Post makes a POST request
func (c *GitlabNetClient) Post(ctx context.Context, path string, data interface{}) (*http.Response, error) {
return c.DoRequest(ctx, http.MethodPost, normalizePath(path), data)
}
// Do executes a request
func (c *GitlabNetClient) Do(request *http.Request) (*http.Response, error) {
response, respErr := c.httpClient.RetryableHTTP.HTTPClient.Do(request)
if err := parseError(response, respErr); err != nil {
return nil, err
}
return response, nil
}
// DoRequest executes a request with the given method, path, and data
func (c *GitlabNetClient) DoRequest(ctx context.Context, method, path string, data interface{}) (*http.Response, error) {
request, err := newRequest(ctx, method, c.httpClient.Host, path, data)
if err != nil {
Loading
Loading
@@ -153,42 +170,13 @@ func (c *GitlabNetClient) DoRequest(ctx context.Context, method, path string, da
}
request.Header.Set(apiSecretHeaderName, tokenString)
originalRemoteIP, ok := ctx.Value(OriginalRemoteIPContextKey{}).(string)
if ok {
request.Header.Add("X-Forwarded-For", originalRemoteIP)
}
request.Header.Add("Content-Type", "application/json")
request.Header.Add("User-Agent", c.userAgent)
request.Close = true
start := time.Now()
response, err := c.httpClient.Do(request)
fields := log.Fields{
"method": method,
"url": request.URL.String(),
"duration_ms": time.Since(start) / time.Millisecond,
}
logger := log.WithContextFields(ctx, fields)
if err != nil {
logger.WithError(err).Error("Internal API unreachable")
return nil, &ApiError{"Internal API unreachable"}
}
if response != nil {
logger = logger.WithField("status", response.StatusCode)
}
if err := parseError(response); err != nil {
logger.WithError(err).Error("Internal API error")
response, respErr := c.httpClient.RetryableHTTP.Do(request)
if err := parseError(response, respErr); err != nil {
return nil, err
}
if response.ContentLength >= 0 {
logger = logger.WithField("content_length_bytes", response.ContentLength)
}
logger.Info("Finished HTTP request")
return response, nil
}
// Package client provides functionality for interacting with HTTP clients
package client
import (
Loading
Loading
@@ -13,30 +14,34 @@ import (
"strings"
"time"
"gitlab.com/gitlab-org/labkit/correlation"
"gitlab.com/gitlab-org/labkit/tracing"
"github.com/hashicorp/go-retryablehttp"
)
const (
socketBaseUrl = "http://unix"
socketBaseURL = "http://unix"
unixSocketProtocol = "http+unix://"
httpProtocol = "http://"
httpsProtocol = "https://"
defaultReadTimeoutSeconds = 300
defaultRetryWaitMinimum = time.Second
defaultRetryWaitMaximum = 15 * time.Second
defaultRetryMax = 2
)
var (
ErrCafileNotFound = errors.New("cafile not found")
)
// ErrCafileNotFound indicates that the specified CA file was not found
var ErrCafileNotFound = errors.New("cafile not found")
type HttpClient struct {
*http.Client
Host string
// HTTPClient provides an HTTP client with retry capabilities
type HTTPClient struct {
RetryableHTTP *retryablehttp.Client
Host string
}
type httpClientCfg struct {
keyPath, certPath string
caFile, caPath string
keyPath, certPath string
caFile, caPath string
retryWaitMin, retryWaitMax time.Duration
retryMax int
}
func (hcc httpClientCfg) HaveCertAndKey() bool { return hcc.keyPath != "" && hcc.certPath != "" }
Loading
Loading
@@ -53,6 +58,15 @@ func WithClientCert(certPath, keyPath string) HTTPClientOpt {
}
}
// WithHTTPRetryOpts configures HTTP retry options for the HttpClient
func WithHTTPRetryOpts(waitMin, waitMax time.Duration, maxAttempts int) HTTPClientOpt {
return func(hcc *httpClientCfg) {
hcc.retryWaitMin = waitMin
hcc.retryWaitMax = waitMax
hcc.retryMax = maxAttempts
}
}
func validateCaFile(filename string) error {
if filename == "" {
return nil
Loading
Loading
@@ -70,43 +84,49 @@ func validateCaFile(filename string) error {
}
// NewHTTPClientWithOpts builds an HTTP client using the provided options
func NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, readTimeoutSeconds uint64, opts []HTTPClientOpt) (*HttpClient, error) {
func NewHTTPClientWithOpts(gitlabURL, gitlabRelativeURLRoot, caFile, caPath string, readTimeoutSeconds uint64, opts []HTTPClientOpt) (*HTTPClient, error) {
hcc := &httpClientCfg{
caFile: caFile,
caPath: caPath,
retryWaitMin: defaultRetryWaitMinimum,
retryWaitMax: defaultRetryWaitMaximum,
retryMax: defaultRetryMax,
}
for _, opt := range opts {
opt(hcc)
}
var transport *http.Transport
var host string
var err error
if strings.HasPrefix(gitlabURL, unixSocketProtocol) {
switch {
case strings.HasPrefix(gitlabURL, unixSocketProtocol):
transport, host = buildSocketTransport(gitlabURL, gitlabRelativeURLRoot)
} else if strings.HasPrefix(gitlabURL, httpProtocol) {
transport, host = buildHttpTransport(gitlabURL)
} else if strings.HasPrefix(gitlabURL, httpsProtocol) {
case strings.HasPrefix(gitlabURL, httpProtocol):
transport, host = buildHTTPTransport(gitlabURL)
case strings.HasPrefix(gitlabURL, httpsProtocol):
err = validateCaFile(caFile)
if err != nil {
return nil, err
}
hcc := &httpClientCfg{
caFile: caFile,
caPath: caPath,
}
for _, opt := range opts {
opt(hcc)
}
transport, host, err = buildHttpsTransport(*hcc, gitlabURL)
transport, host, err = buildHTTPSTransport(*hcc, gitlabURL)
if err != nil {
return nil, err
}
} else {
default:
return nil, errors.New("unknown GitLab URL prefix")
}
c := &http.Client{
Transport: correlation.NewInstrumentedRoundTripper(tracing.NewRoundTripper(transport)),
Timeout: readTimeout(readTimeoutSeconds),
}
c := retryablehttp.NewClient()
c.RetryMax = hcc.retryMax
c.RetryWaitMax = hcc.retryWaitMax
c.RetryWaitMin = hcc.retryWaitMin
c.Logger = nil
c.HTTPClient.Transport = NewTransport(transport)
c.HTTPClient.Timeout = readTimeout(readTimeoutSeconds)
client := &HttpClient{Client: c, Host: host}
client := &HTTPClient{RetryableHTTP: c, Host: host}
return client, nil
}
Loading
Loading
@@ -121,7 +141,7 @@ func buildSocketTransport(gitlabURL, gitlabRelativeURLRoot string) (*http.Transp
},
}
host := socketBaseUrl
host := socketBaseURL
gitlabRelativeURLRoot = strings.Trim(gitlabRelativeURLRoot, "/")
if gitlabRelativeURLRoot != "" {
host = host + "/" + gitlabRelativeURLRoot
Loading
Loading
@@ -130,9 +150,8 @@ func buildSocketTransport(gitlabURL, gitlabRelativeURLRoot string) (*http.Transp
return transport, host
}
func buildHttpsTransport(hcc httpClientCfg, gitlabURL string) (*http.Transport, string, error) {
func buildHTTPSTransport(hcc httpClientCfg, gitlabURL string) (*http.Transport, string, error) {
certPool, err := x509.SystemCertPool()
if err != nil {
certPool = x509.NewCertPool()
}
Loading
Loading
@@ -157,9 +176,9 @@ func buildHttpsTransport(hcc httpClientCfg, gitlabURL string) (*http.Transport,
}
if hcc.HaveCertAndKey() {
cert, err := tls.LoadX509KeyPair(hcc.certPath, hcc.keyPath)
if err != nil {
return nil, "", err
cert, loadErr := tls.LoadX509KeyPair(hcc.certPath, hcc.keyPath)
if loadErr != nil {
return nil, "", loadErr
}
tlsConfig.Certificates = []tls.Certificate{cert}
}
Loading
Loading
@@ -172,13 +191,13 @@ func buildHttpsTransport(hcc httpClientCfg, gitlabURL string) (*http.Transport,
}
func addCertToPool(certPool *x509.CertPool, fileName string) {
cert, err := os.ReadFile(fileName)
cert, err := os.ReadFile(filepath.Clean(fileName))
if err == nil {
certPool.AppendCertsFromPEM(cert)
}
}
func buildHttpTransport(gitlabURL string) (*http.Transport, string) {
func buildHTTPTransport(gitlabURL string) (*http.Transport, string) {
return &http.Transport{}, gitlabURL
}
Loading
Loading
Loading
Loading
@@ -10,6 +10,7 @@ import (
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver"
)
Loading
Loading
@@ -21,7 +22,7 @@ func TestReadTimeout(t *testing.T) {
require.NoError(t, err)
require.NotNil(t, client)
require.Equal(t, time.Duration(expectedSeconds)*time.Second, client.Client.Timeout)
require.Equal(t, time.Duration(expectedSeconds)*time.Second, client.RetryableHTTP.HTTPClient.Timeout)
}
const (
Loading
Loading
@@ -34,7 +35,7 @@ func TestBasicAuthSettings(t *testing.T) {
{
Path: "/api/v4/internal/get_endpoint",
Handler: func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, http.MethodGet, r.Method)
assert.Equal(t, http.MethodGet, r.Method)
fmt.Fprint(w, r.Header.Get("Authorization"))
},
Loading
Loading
@@ -42,7 +43,7 @@ func TestBasicAuthSettings(t *testing.T) {
{
Path: "/api/v4/internal/post_endpoint",
Handler: func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, http.MethodPost, r.Method)
assert.Equal(t, http.MethodPost, r.Method)
fmt.Fprint(w, r.Header.Get("Authorization"))
},
Loading
Loading
@@ -68,6 +69,7 @@ func testBasicAuthHeaders(t *testing.T, response *http.Response) {
require.NoError(t, err)
headerParts := strings.Split(string(responseBody), " ")
require.NotNil(t, headerParts)
require.Equal(t, "Basic", headerParts[0])
credentials, err := base64.StdEncoding.DecodeString(headerParts[1])
Loading
Loading
@@ -80,16 +82,17 @@ func TestEmptyBasicAuthSettings(t *testing.T) {
requests := []testserver.TestRequestHandler{
{
Path: "/api/v4/internal/empty_basic_auth",
Handler: func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, "", r.Header.Get("Authorization"))
Handler: func(_ http.ResponseWriter, r *http.Request) {
assert.Equal(t, "", r.Header.Get("Authorization"))
},
},
}
client := setup(t, "", "", requests)
_, err := client.Get(context.Background(), "/empty_basic_auth")
resp, err := client.Get(context.Background(), "/empty_basic_auth")
require.NoError(t, err)
resp.Body.Close()
}
func TestRequestWithUserAgent(t *testing.T) {
Loading
Loading
@@ -97,31 +100,33 @@ func TestRequestWithUserAgent(t *testing.T) {
requests := []testserver.TestRequestHandler{
{
Path: "/api/v4/internal/default_user_agent",
Handler: func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, defaultUserAgent, r.UserAgent())
Handler: func(_ http.ResponseWriter, r *http.Request) {
assert.Equal(t, defaultUserAgent, r.UserAgent())
},
},
{
Path: "/api/v4/internal/override_user_agent",
Handler: func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, gitalyUserAgent, r.UserAgent())
Handler: func(_ http.ResponseWriter, r *http.Request) {
assert.Equal(t, gitalyUserAgent, r.UserAgent())
},
},
}
client := setup(t, "", "", requests)
_, err := client.Get(context.Background(), "/default_user_agent")
defaultUserAgentResp, err := client.Get(context.Background(), "/default_user_agent")
require.NoError(t, err)
client.SetUserAgent(gitalyUserAgent)
_, err = client.Get(context.Background(), "/override_user_agent")
overriddenUserAgentResp, err := client.Get(context.Background(), "/override_user_agent")
require.NoError(t, err)
defaultUserAgentResp.Body.Close()
overriddenUserAgentResp.Body.Close()
}
func setup(t *testing.T, username, password string, requests []testserver.TestRequestHandler) *GitlabNetClient {
url := testserver.StartHttpServer(t, requests)
url := testserver.StartHTTPServer(t, requests)
httpClient, err := NewHTTPClientWithOpts(url, "", "", "", 1, nil)
require.NoError(t, err)
Loading
Loading
Loading
Loading
@@ -8,6 +8,7 @@ import (
"path"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitlab-shell/v14/client/testserver"
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper"
Loading
Loading
@@ -15,6 +16,8 @@ import (
//go:generate openssl req -newkey rsa:4096 -new -nodes -x509 -days 3650 -out ../internal/testhelper/testdata/testroot/certs/client/server.crt -keyout ../internal/testhelper/testdata/testroot/certs/client/key.pem -subj "/C=US/ST=California/L=San Francisco/O=GitLab/OU=GitLab-Shell/CN=localhost"
func TestSuccessfulRequests(t *testing.T) {
testRoot := testhelper.PrepareTestRootDir(t)
testCases := []struct {
desc string
caFile, caPath string
Loading
Loading
@@ -22,25 +25,25 @@ func TestSuccessfulRequests(t *testing.T) {
}{
{
desc: "Valid CaFile",
caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"),
caFile: path.Join(testRoot, "certs/valid/server.crt"),
},
{
desc: "Valid CaPath",
caPath: path.Join(testhelper.TestRoot, "certs/valid"),
caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"),
caPath: path.Join(testRoot, "certs/valid"),
caFile: path.Join(testRoot, "certs/valid/server.crt"),
},
{
desc: "Invalid cert with self signed cert option enabled",
caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"),
caFile: path.Join(testRoot, "certs/valid/server.crt"),
},
{
desc: "Client certs with CA",
caFile: path.Join(testhelper.TestRoot, "certs/valid/server.crt"),
caFile: path.Join(testRoot, "certs/valid/server.crt"),
// Run the command "go generate httpsclient_test.go" to
// regenerate the following test fixtures:
clientCAPath: path.Join(testhelper.TestRoot, "certs/client/server.crt"),
clientCertPath: path.Join(testhelper.TestRoot, "certs/client/server.crt"),
clientKeyPath: path.Join(testhelper.TestRoot, "certs/client/key.pem"),
clientCAPath: path.Join(testRoot, "certs/client/server.crt"),
clientCertPath: path.Join(testRoot, "certs/client/server.crt"),
clientKeyPath: path.Join(testRoot, "certs/client/key.pem"),
},
}
Loading
Loading
@@ -63,6 +66,8 @@ func TestSuccessfulRequests(t *testing.T) {
}
func TestFailedRequests(t *testing.T) {
testRoot := testhelper.PrepareTestRootDir(t)
testCases := []struct {
desc string
caFile string
Loading
Loading
@@ -72,17 +77,17 @@ func TestFailedRequests(t *testing.T) {
}{
{
desc: "Invalid CaFile",
caFile: path.Join(testhelper.TestRoot, "certs/invalid/server.crt"),
caFile: path.Join(testRoot, "certs/invalid/server.crt"),
expectedError: "Internal API unreachable",
},
{
desc: "Missing CaFile",
caFile: path.Join(testhelper.TestRoot, "certs/invalid/missing.crt"),
caFile: path.Join(testRoot, "certs/invalid/missing.crt"),
expectedCaFileNotFound: true,
},
{
desc: "Invalid CaPath",
caPath: path.Join(testhelper.TestRoot, "certs/invalid"),
caPath: path.Join(testRoot, "certs/invalid"),
expectedError: "Internal API unreachable",
},
{
Loading
Loading
@@ -108,22 +113,20 @@ func TestFailedRequests(t *testing.T) {
}
func setupWithRequests(t *testing.T, caFile, caPath, clientCAPath, clientCertPath, clientKeyPath string) (*GitlabNetClient, error) {
testhelper.PrepareTestRootDir(t)
requests := []testserver.TestRequestHandler{
{
Path: "/api/v4/internal/hello",
Handler: func(w http.ResponseWriter, r *http.Request) {
require.Equal(t, http.MethodGet, r.Method)
assert.Equal(t, http.MethodGet, r.Method)
fmt.Fprint(w, "Hello")
},
},
}
url := testserver.StartHttpsServer(t, requests, clientCAPath)
url := testserver.StartHTTPSServer(t, requests, clientCAPath)
var opts []HTTPClientOpt
opts := defaultHttpOpts
if clientCertPath != "" && clientKeyPath != "" {
opts = append(opts, WithClientCert(clientCertPath, clientKeyPath))
}
Loading
Loading
Loading
Loading
@@ -10,8 +10,8 @@ import (
"testing"
"github.com/stretchr/testify/require"
"gitlab.com/gitlab-org/gitaly/v15/client"
pb "gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"
"gitlab.com/gitlab-org/gitaly/v16/client"
pb "gitlab.com/gitlab-org/gitaly/v16/proto/go/gitalypb"
"gitlab.com/gitlab-org/labkit/log"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
Loading
Loading
@@ -32,9 +32,7 @@ func (s *TestGitalyServer) SSHReceivePack(stream pb.SSHService_SSHReceivePackSer
s.ReceivedMD, _ = metadata.FromIncomingContext(stream.Context())
response := []byte("ReceivePack: " + req.GlId + " " + req.Repository.GlRepository)
stream.Send(&pb.SSHReceivePackResponse{Stdout: response})
return nil
return stream.Send(&pb.SSHReceivePackResponse{Stdout: response})
}
func (s *TestGitalyServer) SSHUploadPack(stream pb.SSHService_SSHUploadPackServer) error {
Loading
Loading
@@ -46,9 +44,7 @@ func (s *TestGitalyServer) SSHUploadPack(stream pb.SSHService_SSHUploadPackServe
s.ReceivedMD, _ = metadata.FromIncomingContext(stream.Context())
response := []byte("UploadPack: " + req.Repository.GlRepository)
stream.Send(&pb.SSHUploadPackResponse{Stdout: response})
return nil
return stream.Send(&pb.SSHUploadPackResponse{Stdout: response})
}
func (s *TestGitalyServer) SSHUploadPackWithSidechannel(ctx context.Context, req *pb.SSHUploadPackWithSidechannelRequest) (*pb.SSHUploadPackWithSidechannelResponse, error) {
Loading
Loading
@@ -80,35 +76,61 @@ func (s *TestGitalyServer) SSHUploadArchive(stream pb.SSHService_SSHUploadArchiv
s.ReceivedMD, _ = metadata.FromIncomingContext(stream.Context())
response := []byte("UploadArchive: " + req.Repository.GlRepository)
stream.Send(&pb.SSHUploadArchiveResponse{Stdout: response})
return nil
return stream.Send(&pb.SSHUploadArchiveResponse{Stdout: response})
}
func StartGitalyServer(t *testing.T) (string, *TestGitalyServer) {
func StartGitalyServer(t *testing.T, network string) (string, *TestGitalyServer) {
t.Helper()
tempDir, _ := os.MkdirTemp("", "gitlab-shell-test-api")
gitalySocketPath := path.Join(tempDir, "gitaly.sock")
t.Cleanup(func() { os.RemoveAll(tempDir) })
err := os.MkdirAll(filepath.Dir(gitalySocketPath), 0700)
require.NoError(t, err)
switch network {
case "unix":
// We can't use t.TempDir() here because it will create a directory that
// far exceeds the 108 character limit which results in the socket failing
// to be created.
//
// See https://gitlab.com/gitlab-org/gitlab-shell/-/issues/696#note_1664726924
// for more detail.
tempDir, err := os.MkdirTemp("", "gitaly")
require.NoError(t, err)
t.Cleanup(func() { require.NoError(t, os.RemoveAll(tempDir)) })
gitalySocketPath := path.Join(tempDir, "gitaly.sock")
err = os.MkdirAll(filepath.Dir(gitalySocketPath), 0700)
require.NoError(t, err)
addr, testServer := doStartTestServer(t, "unix", gitalySocketPath)
return fmt.Sprintf("unix:%s", addr), testServer
case "tcp":
addr, testServer := doStartTestServer(t, "tcp", "127.0.0.1:0")
return fmt.Sprintf("tcp://%s", addr), testServer
case "dns":
addr, testServer := doStartTestServer(t, "tcp", "127.0.0.1:0")
// gRPC URL with DNS scheme follows this format: https://grpc.github.io/grpc/core/md_doc_naming.html
// When the authority is dropped, the URL have 3 splashes.
return fmt.Sprintf("dns:///%s", addr), testServer
default:
panic(fmt.Sprintf("Unsupported network %s", network))
}
}
func doStartTestServer(t *testing.T, network string, path string) (string, *TestGitalyServer) {
server := grpc.NewServer(
client.SidechannelServer(log.ContextLogger(context.Background()), insecure.NewCredentials()),
)
listener, err := net.Listen("unix", gitalySocketPath)
listener, err := net.Listen(network, path)
require.NoError(t, err)
testServer := TestGitalyServer{}
pb.RegisterSSHServiceServer(server, &testServer)
go server.Serve(listener)
t.Cleanup(func() { server.Stop() })
gitalySocketUrl := "unix:" + gitalySocketPath
go func() {
require.NoError(t, server.Serve(listener))
}()
t.Cleanup(func() { server.GracefulStop() })
return gitalySocketUrl, &testServer
return listener.Addr().String(), &testServer
}
Loading
Loading
@@ -17,22 +17,28 @@ import (
"gitlab.com/gitlab-org/gitlab-shell/v14/internal/testhelper"
)
var (
tempDir, _ = os.MkdirTemp("", "gitlab-shell-test-api")
testSocket = path.Join(tempDir, "internal.sock")
)
type TestRequestHandler struct {
Path string
Handler func(w http.ResponseWriter, r *http.Request)
}
func StartSocketHttpServer(t *testing.T, handlers []TestRequestHandler) string {
// StartSocketHTTPServer starts a socket based HTTP server
func StartSocketHTTPServer(t *testing.T, handlers []TestRequestHandler) string {
t.Helper()
err := os.MkdirAll(filepath.Dir(testSocket), 0700)
// We can't use t.TempDir() here because it will create a directory that
// far exceeds the 108 character limit which results in the socket failing
// to be created.
//
// See https://gitlab.com/gitlab-org/gitlab-shell/-/issues/696#note_1664726924
// for more detail.
tempDir, err := os.MkdirTemp("", "http")
require.NoError(t, err)
t.Cleanup(func() { require.NoError(t, os.RemoveAll(tempDir)) })
testSocket := path.Join(tempDir, "internal.sock")
err = os.MkdirAll(filepath.Dir(testSocket), 0700)
require.NoError(t, err)
t.Cleanup(func() { os.RemoveAll(tempDir) })
socketListener, err := net.Listen("unix", testSocket)
require.NoError(t, err)
Loading
Loading
@@ -50,7 +56,8 @@ func StartSocketHttpServer(t *testing.T, handlers []TestRequestHandler) string {
return url
}
func StartHttpServer(t *testing.T, handlers []TestRequestHandler) string {
// StartHTTPServer starts a TCP based HTTP server
func StartHTTPServer(t *testing.T, handlers []TestRequestHandler) string {
t.Helper()
server := httptest.NewServer(buildHandler(handlers))
Loading
Loading
@@ -59,11 +66,43 @@ func StartHttpServer(t *testing.T, handlers []TestRequestHandler) string {
return server.URL
}
func StartHttpsServer(t *testing.T, handlers []TestRequestHandler, clientCAPath string) string {
// StartRetryHTTPServer starts a TCP based HTTP server with retry capabilities
func StartRetryHTTPServer(t *testing.T, handlers []TestRequestHandler) string {
attempts := map[string]int{}
retryMiddileware := func(next func(w http.ResponseWriter, r *http.Request)) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
attempts[r.URL.String()+r.Method]++
if attempts[r.URL.String()+r.Method] == 1 {
w.WriteHeader(500)
return
}
http.HandlerFunc(next).ServeHTTP(w, r)
})
}
t.Helper()
h := http.NewServeMux()
for _, handler := range handlers {
h.Handle(handler.Path, retryMiddileware(handler.Handler))
}
server := httptest.NewServer(h)
t.Cleanup(func() { server.Close() })
return server.URL
}
// StartHTTPSServer starts a TCP based HTTPS capable server
func StartHTTPSServer(t *testing.T, handlers []TestRequestHandler, clientCAPath string) string {
t.Helper()
crt := path.Join(testhelper.TestRoot, "certs/valid/server.crt")
key := path.Join(testhelper.TestRoot, "certs/valid/server.key")
testRoot := testhelper.PrepareTestRootDir(t)
crt := path.Join(testRoot, "certs/valid/server.crt")
key := path.Join(testRoot, "certs/valid/server.key")
server := httptest.NewUnstartedServer(buildHandler(handlers))
cer, err := tls.LoadX509KeyPair(crt, key)
Loading
Loading