Skip to content
Merged
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
191 changes: 191 additions & 0 deletions .github/workflows/dd-build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
name: Build and Push etcd releases

on:
push:
# Sequence of patterns matched against refs/heads
tags:
# Push events on datadog tags
- "*-dd*"
permissions: write-all
jobs:
build-amd64:
strategy:
matrix:
platform: ["linux/amd64"]
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
with:
fetch-depth: 0
- name: Set environment variables
id: set_env
run: |
echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
echo "TARGET_OS=$(echo ${{ matrix.platform }} | cut -d'/' -f1)" >> $GITHUB_ENV
echo "TARGET_ARCH=$(echo ${{ matrix.platform }} | cut -d'/' -f2)" >> $GITHUB_ENV
env:
GITHUB_REF: ${{ github.ref }}
- name: Build etcd
run: |
REPOSITORY=https://github.com/${{ env.GITHUB_REPOSITORY }}.git \
CGO_ENABLED=1 \
GOEXPERIMENT=boringcrypto \
GO_BUILD_FLAGS="-tags=fips" \
TARGET_OS=${TARGET_OS} \
TARGET_ARCH=${TARGET_ARCH} \
./scripts/build-binary-single-target ${{ env.RELEASE_VERSION }}
env:
GITHUB_REPOSITORY: ${{ github.repository }}
- name: Calculate checksums
id: calculate_checksums
shell: bash
working-directory: release/
run: ls . | grep -E '\.tar.gz$|\.zip$' | xargs shasum -a 256 > ./SHA256SUMS
- uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: etcd_output_amd64
path: release/
build-arm64:
strategy:
matrix:
platform: ["linux/arm64"]
runs-on: ubuntu-24.04-arm
steps:
- uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0
with:
fetch-depth: 0
- name: Set environment variables
id: set_env
run: |
echo "RELEASE_VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_ENV
echo "TARGET_OS=$(echo ${{ matrix.platform }} | cut -d'/' -f1)" >> $GITHUB_ENV
echo "TARGET_ARCH=$(echo ${{ matrix.platform }} | cut -d'/' -f2)" >> $GITHUB_ENV
env:
GITHUB_REF: ${{ github.ref }}
- name: Build etcd
run: |
REPOSITORY=https://github.com/${{ env.GITHUB_REPOSITORY }}.git \
CGO_ENABLED=1 \
GOEXPERIMENT=boringcrypto \
GO_BUILD_FLAGS="-tags=fips" \
TARGET_OS=${TARGET_OS} \
TARGET_ARCH=${TARGET_ARCH} \
./scripts/build-binary-single-target ${{ env.RELEASE_VERSION }}
env:
GITHUB_REPOSITORY: ${{ github.repository }}
- name: Calculate checksums
id: calculate_checksums
shell: bash
working-directory: release/
run: ls . | grep -E '\.tar.gz$|\.zip$' | xargs shasum -a 256 > ./SHA256SUMS
- uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
with:
name: etcd_output_arm64
path: release/
release:
permissions:
contents: write
runs-on: ubuntu-latest
needs: [build-amd64, build-arm64]
outputs:
upload_url: ${{ steps.create_release_branch.outputs.upload_url }}${{ steps.create_release_tags.outputs.upload_url }}
steps:
- name: Extract branch name
shell: bash
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
id: extract_branch
env:
GITHUB_REF: ${{ github.ref }}
if: startsWith(github.ref, 'refs/heads/')
- name: Create Release for Branch
id: create_release_branch
uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe # v2.4.2
if: startsWith(github.ref, 'refs/heads/')
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
token: ${{ secrets.GITHUB_TOKEN }}
name: branch@${{ steps.extract_branch.outputs.branch }}
tag_name: branch@${{ steps.extract_branch.outputs.branch }}
draft: false
prerelease: false
- name: Extract tags name
shell: bash
run: echo "##[set-output name=tags;]$(echo ${GITHUB_REF#refs/tags/})"
id: extract_tags
env:
GITHUB_REF: ${{ github.ref }}
if: startsWith(github.ref, 'refs/tags/')
- name: Create Release for Tags
id: create_release_tags
uses: softprops/action-gh-release@5be0e66d93ac7ed76da52eca8bb058f665c3a5fe # v2.4.2
if: ${{ startsWith(github.ref, 'refs/tags/') }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
token: ${{ secrets.GITHUB_TOKEN }}
name: ${{ steps.extract_tags.outputs.tags }}
tag_name: ${{ steps.extract_tags.outputs.tags }}
release_name: ${{ steps.extract_tags.outputs.tags }}
draft: false
prerelease: false
releaseassets:
runs-on: ubuntu-latest
needs: release
strategy:
matrix:
platform: ["linux-arm64","linux-amd64"]
extension: ["tar.gz"]
steps:
- name: Set artifact name
id: set_artifact
run: |
if [[ "${{ matrix.platform }}" == *"arm64"* ]]; then
echo "ARTIFACT_NAME=etcd_output_arm64" >> $GITHUB_ENV
else
echo "ARTIFACT_NAME=etcd_output_amd64" >> $GITHUB_ENV
fi
- name: Download artifacts
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
name: ${{ env.ARTIFACT_NAME }}
path: _output/release-tars
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Set release version environment variable
run: echo RELEASE_VERSION=${GITHUB_REF#refs/tags/} >> $GITHUB_ENV
env:
GITHUB_REF: ${{ github.ref }}
- name: Upload Release Asset
id: upload-release-asset
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.release.outputs.upload_url }}
asset_path: ./_output/release-tars/etcd-${{ env.RELEASE_VERSION }}-${{ matrix.platform }}.${{ matrix.extension }}
asset_name: etcd-${{ env.RELEASE_VERSION }}-${{ matrix.platform }}.${{ matrix.extension }}
asset_content_type: application/tar+gzip
addchecksum:
runs-on: ubuntu-latest
needs: release
steps:
- name: Create output directory
run: mkdir -p _output/checksums
- name: Download all artifacts
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
with:
path: _output/artifacts
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Combine checksums
run: |
find _output/artifacts -name "SHA256SUMS" -exec cat {} \; > _output/checksums/SHA256SUMS
- name: Upload checksums
id: upload-checksums
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ needs.release.outputs.upload_url }}
asset_path: ./_output/checksums/SHA256SUMS
asset_name: SHA256SUMS
asset_content_type: text/plain
2 changes: 1 addition & 1 deletion api/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
var (
// MinClusterVersion is the min cluster version this etcd binary is compatible with.
MinClusterVersion = "3.0.0"
Version = "3.5.25"
Version = "3.5.25-dd.1"
APIVersion = "unknown"

// Git SHA Value will be set during build
Expand Down
3 changes: 2 additions & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ GOOS=${GOOS:-$(go env GOOS)}
GOARCH=${GOARCH:-$(go env GOARCH)}

CGO_ENABLED="${CGO_ENABLED:-0}"
GOEXPERIMENT="${GOEXPERIMENT:-}"

# Set GO_LDFLAGS="-s" for building without symbols for debugging.
# shellcheck disable=SC2206
GO_LDFLAGS=(${GO_LDFLAGS:-} "-X=${VERSION_SYMBOL}=${GIT_SHA}")
GO_BUILD_ENV=("CGO_ENABLED=${CGO_ENABLED}" "GO_BUILD_FLAGS=${GO_BUILD_FLAGS:-}" "GOOS=${GOOS}" "GOARCH=${GOARCH}")
GO_BUILD_ENV=("CGO_ENABLED=${CGO_ENABLED}" "GO_BUILD_FLAGS=${GO_BUILD_FLAGS:-}" "GOOS=${GOOS}" "GOARCH=${GOARCH}" "GOEXPERIMENT=${GOEXPERIMENT}")

GOFAIL_VERSION=$(cd tools/mod && go list -m -f '{{.Version}}' go.etcd.io/gofail)
# enable/disable failpoints
Expand Down
41 changes: 28 additions & 13 deletions client/pkg/transport/listener.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,10 @@ type TLSInfo struct {
// TLS certificate provided by a client.
AllowedHostnames []string

// AllowedURIs is a list of acceptable subjective alternative name URIs that must match the
// TLS certificate provided by a client.
AllowedURIs []string

// Logger logs TLS errors.
// If nil, all logs are discarded.
Logger *zap.Logger
Expand Down Expand Up @@ -415,23 +419,20 @@ func (info TLSInfo) baseConfig() (*tls.Config, error) {
cfg.CipherSuites = info.CipherSuites
}

var definedRestrictions int
for _, restriction := range []int{len(info.AllowedCN), len(info.AllowedCNs), len(info.AllowedHostname), len(info.AllowedHostnames), len(info.AllowedURIs)} {
if restriction > 0 {
definedRestrictions++
if definedRestrictions > 1 {
return nil, errors.New("exactly one of AllowedCNs, AllowedHostnames, or AllowedURIs can be defined")
}
}
}

// Client certificates may be verified by either an exact match on the CN,
// or a more general check of the CN and SANs.
var verifyCertificate func(*x509.Certificate) bool

if info.AllowedCN != "" && len(info.AllowedCNs) > 0 {
return nil, fmt.Errorf("AllowedCN and AllowedCNs are mutually exclusive (cn=%q, cns=%q)", info.AllowedCN, info.AllowedCNs)
}
if info.AllowedHostname != "" && len(info.AllowedHostnames) > 0 {
return nil, fmt.Errorf("AllowedHostname and AllowedHostnames are mutually exclusive (hostname=%q, hostnames=%q)", info.AllowedHostname, info.AllowedHostnames)
}
if info.AllowedCN != "" && info.AllowedHostname != "" {
return nil, fmt.Errorf("AllowedCN and AllowedHostname are mutually exclusive (cn=%q, hostname=%q)", info.AllowedCN, info.AllowedHostname)
}
if len(info.AllowedCNs) > 0 && len(info.AllowedHostnames) > 0 {
return nil, fmt.Errorf("AllowedCNs and AllowedHostnames are mutually exclusive (cns=%q, hostnames=%q)", info.AllowedCNs, info.AllowedHostnames)
}

if info.AllowedCN != "" {
info.Logger.Warn("AllowedCN is deprecated, use AllowedCNs instead")
verifyCertificate = func(cert *x509.Certificate) bool {
Expand All @@ -444,6 +445,7 @@ func (info TLSInfo) baseConfig() (*tls.Config, error) {
return cert.VerifyHostname(info.AllowedHostname) == nil
}
}

if len(info.AllowedCNs) > 0 {
verifyCertificate = func(cert *x509.Certificate) bool {
for _, allowedCN := range info.AllowedCNs {
Expand All @@ -454,6 +456,7 @@ func (info TLSInfo) baseConfig() (*tls.Config, error) {
return false
}
}

if len(info.AllowedHostnames) > 0 {
verifyCertificate = func(cert *x509.Certificate) bool {
for _, allowedHostname := range info.AllowedHostnames {
Expand All @@ -464,6 +467,18 @@ func (info TLSInfo) baseConfig() (*tls.Config, error) {
return false
}
}
if len(info.AllowedURIs) > 0 {
verifyCertificate = func(cert *x509.Certificate) bool {
for _, allowedURI := range info.AllowedURIs {
for _, uri := range cert.URIs {
if allowedURI == uri.String() {
return true
}
}
}
return false
}
}
if verifyCertificate != nil {
cfg.VerifyPeerCertificate = func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
for _, chains := range verifiedChains {
Expand Down
4 changes: 2 additions & 2 deletions client/v2/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ toolchain go1.24.10
require (
github.com/json-iterator/go v1.1.11
github.com/modern-go/reflect2 v1.0.1
go.etcd.io/etcd/api/v3 v3.5.25
go.etcd.io/etcd/client/pkg/v3 v3.5.25
go.etcd.io/etcd/api/v3 v3.5.25-dd.1
go.etcd.io/etcd/client/pkg/v3 v3.5.25-dd.1
)

require (
Expand Down
4 changes: 2 additions & 2 deletions client/v3/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ require (
github.com/dustin/go-humanize v1.0.0
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
github.com/prometheus/client_golang v1.11.1
go.etcd.io/etcd/api/v3 v3.5.25
go.etcd.io/etcd/client/pkg/v3 v3.5.25
go.etcd.io/etcd/api/v3 v3.5.25-dd.1
go.etcd.io/etcd/client/pkg/v3 v3.5.25-dd.1
go.uber.org/zap v1.17.0
google.golang.org/grpc v1.71.1
sigs.k8s.io/yaml v1.2.0
Expand Down
6 changes: 6 additions & 0 deletions etcdctl/fips.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//go:build fips

package main

// enforce fips compliance if boringcrypto is enabled
import _ "crypto/tls/fipsonly"
14 changes: 7 additions & 7 deletions etcdctl/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ require (
github.com/spf13/cobra v1.1.3
github.com/spf13/pflag v1.0.5
github.com/urfave/cli v1.22.4
go.etcd.io/etcd/api/v3 v3.5.25
go.etcd.io/etcd/client/pkg/v3 v3.5.25
go.etcd.io/etcd/api/v3 v3.5.25-dd.1
go.etcd.io/etcd/client/pkg/v3 v3.5.25-dd.1
go.etcd.io/etcd/client/v2 v2.305.25
go.etcd.io/etcd/client/v3 v3.5.25
go.etcd.io/etcd/etcdutl/v3 v3.5.25
go.etcd.io/etcd/pkg/v3 v3.5.25
go.etcd.io/etcd/client/v3 v3.5.25-dd.1
go.etcd.io/etcd/etcdutl/v3 v3.5.25-dd.1
go.etcd.io/etcd/pkg/v3 v3.5.25-dd.1
go.uber.org/zap v1.17.0
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba
google.golang.org/grpc v1.71.1
Expand Down Expand Up @@ -51,8 +51,8 @@ require (
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
go.etcd.io/bbolt v1.3.12 // indirect
go.etcd.io/etcd/raft/v3 v3.5.25 // indirect
go.etcd.io/etcd/server/v3 v3.5.25 // indirect
go.etcd.io/etcd/raft/v3 v3.5.25-dd.1 // indirect
go.etcd.io/etcd/server/v3 v3.5.25-dd.1 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.46.0 // indirect
go.opentelemetry.io/otel v1.34.0 // indirect
Expand Down
6 changes: 6 additions & 0 deletions etcdutl/fips.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
//go:build fips

package main

// enforce fips compliance if boringcrypto is enabled
import _ "crypto/tls/fipsonly"
12 changes: 6 additions & 6 deletions etcdutl/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ require (
github.com/olekukonko/tablewriter v0.0.5
github.com/spf13/cobra v1.1.3
go.etcd.io/bbolt v1.3.12
go.etcd.io/etcd/api/v3 v3.5.25
go.etcd.io/etcd/client/pkg/v3 v3.5.25
go.etcd.io/etcd/client/v3 v3.5.25
go.etcd.io/etcd/pkg/v3 v3.5.25
go.etcd.io/etcd/raft/v3 v3.5.25
go.etcd.io/etcd/server/v3 v3.5.25
go.etcd.io/etcd/api/v3 v3.5.25-dd.1
go.etcd.io/etcd/client/pkg/v3 v3.5.25-dd.1
go.etcd.io/etcd/client/v3 v3.5.25-dd.1
go.etcd.io/etcd/pkg/v3 v3.5.25-dd.1
go.etcd.io/etcd/raft/v3 v3.5.25-dd.1
go.etcd.io/etcd/server/v3 v3.5.25-dd.1
go.uber.org/zap v1.17.0
)

Expand Down
Loading