Skip to content

Commit

Permalink
Merge pull request #77 from jt-nti/service-account
Browse files Browse the repository at this point in the history
Add service account configuration
  • Loading branch information
jkneubuh authored Jan 26, 2023
2 parents 3b1af27 + 314b670 commit 73afa85
Show file tree
Hide file tree
Showing 24 changed files with 324 additions and 51 deletions.
1 change: 1 addition & 0 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ jobs:
run: go test -v ./...
env:
FABRIC_K8S_BUILDER_DEBUG: 'true'
INCLUDE_KIND_TESTS: ${{ matrix.os == 'ubuntu-latest' && 'true' || 'false' }}

- name: Package
run: |
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ jobs:
go-version: 1.17
- uses: actions/checkout@v3
- name: golangci-lint
uses: golangci/golangci-lint-action@537aa1903e5d359d0b27dbc19ddd22c5087f3fbc
uses: golangci/golangci-lint-action@08e2f20817b15149a52b5b3ebe7de50aff2ba8c5
with:
version: v1.46.2
version: v1.50.1
7 changes: 2 additions & 5 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ linters:
- containedctx
- contextcheck
- cyclop
- deadcode
- decorder
- depguard
- dogsled
Expand Down Expand Up @@ -45,11 +44,9 @@ linters:
- gosimple
- govet
- grouper
- ifshort
- importas
- ineffassign
- ireturn
- lll
- maintidx
- makezero
- misspell
Expand All @@ -69,7 +66,6 @@ linters:
- rowserrcheck
- sqlclosecheck
- staticcheck
- structcheck
- stylecheck
- tenv
- testpackage
Expand All @@ -79,14 +75,15 @@ linters:
- unconvert
- unparam
- unused
- varcheck
- varnamelen
- wastedassign
- whitespace
- wsl
linters-settings:
errorlint:
errorf: true
funlen:
lines: 100
nolintlint:
require-explanation: true
require-specific: true
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@ With the k8s-builder, _chaincode just works!_

The k8s builder can be run in cluster using the `KUBERNETES_SERVICE_HOST` and `KUBERNETES_SERVICE_PORT` environment variables, or it can connect using a `KUBECONFIG_PATH` environment variable.

An optional `FABRIC_K8S_BUILDER_NAMESPACE` can be used to specify the namespace to deploy chaincode to.
The following optional environment variables can be used to configure the k8s builder:

- `FABRIC_K8S_BUILDER_DEBUG` whether to enable additional logging
- `FABRIC_K8S_BUILDER_NAMESPACE` specifies the namespace to deploy chaincode to
- `FABRIC_K8S_BUILDER_SERVICE_ACCOUNT` specifies the service account for the chaincode pod

A `CORE_PEER_ID` environment variable is also currently required.

Expand All @@ -64,6 +68,7 @@ External builders are configured in the `core.yaml` file, for example:
- CORE_PEER_ID
- FABRIC_K8S_BUILDER_DEBUG
- FABRIC_K8S_BUILDER_NAMESPACE
- FABRIC_K8S_BUILDER_SERVICE_ACCOUNT
- KUBERNETES_SERVICE_HOST
- KUBERNETES_SERVICE_PORT
```
Expand Down
3 changes: 3 additions & 0 deletions cmd/build/build_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main_test

import (
"testing"
"time"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
Expand All @@ -17,6 +18,8 @@ func TestBuild(t *testing.T) {
}

var _ = BeforeSuite(func() {
SetDefaultEventuallyTimeout(2 * time.Second)

var err error
buildCmdPath, err = gexec.Build("github.com/hyperledger-labs/fabric-builder-k8s/cmd/build")
Expect(err).NotTo(HaveOccurred())
Expand Down
4 changes: 3 additions & 1 deletion cmd/build/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ func main() {
logger := log.New(ctx)

if len(os.Args) != expectedArgsLength {
logger.Println("Expected CHAINCODE_SOURCE_DIR, CHAINCODE_METADATA_DIR and BUILD_OUTPUT_DIR arguments")
logger.Println(
"Expected CHAINCODE_SOURCE_DIR, CHAINCODE_METADATA_DIR and BUILD_OUTPUT_DIR arguments",
)
os.Exit(1)
}

Expand Down
7 changes: 6 additions & 1 deletion cmd/build/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@ var _ = Describe("Main", func() {
return []string{"CHAINCODE_SOURCE_DIR"}
}),
Entry("When too many arguments are provided", 1, func() []string {
return []string{"CHAINCODE_SOURCE_DIR", "CHAINCODE_METADATA_DIR", "BUILD_OUTPUT_DIR", "UNEXPECTED_ARGUMENT"}
return []string{
"CHAINCODE_SOURCE_DIR",
"CHAINCODE_METADATA_DIR",
"BUILD_OUTPUT_DIR",
"UNEXPECTED_ARGUMENT",
}
}),
)

Expand Down
3 changes: 3 additions & 0 deletions cmd/detect/detect_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main_test

import (
"testing"
"time"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
Expand All @@ -17,6 +18,8 @@ func TestDetect(t *testing.T) {
}

var _ = BeforeSuite(func() {
SetDefaultEventuallyTimeout(2 * time.Second)

var err error
detectCmdPath, err = gexec.Build("github.com/hyperledger-labs/fabric-builder-k8s/cmd/detect")
Expect(err).NotTo(HaveOccurred())
Expand Down
31 changes: 26 additions & 5 deletions cmd/detect/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,39 @@ import (
)

var _ = Describe("Main", func() {
DescribeTable("Running the detect command produces the correct error code",
DescribeTable(
"Running the detect command produces the correct error code",
func(expectedErrorCode int, args ...string) {
command := exec.Command(detectCmdPath, args...)
session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
Expect(err).NotTo(HaveOccurred())

Eventually(session).Should(gexec.Exit(expectedErrorCode))
},
Entry("When the metadata contains a valid type", 0, "CHAINCODE_SOURCE_DIR", "./testdata/validtype"),
Entry("When the metadata contains an invalid type", 1, "CHAINCODE_SOURCE_DIR", "./testdata/invalidtype"),
Entry("When the metadata contents are invalid", 1, "CHAINCODE_SOURCE_DIR", "./testdata/invalidfile"),
Entry("When the metadata does not exist", 1, "CHAINCODE_SOURCE_DIR", "CHAINCODE_METADATA_DIR"),
Entry(
"When the metadata contains a valid type",
0,
"CHAINCODE_SOURCE_DIR",
"./testdata/validtype",
),
Entry(
"When the metadata contains an invalid type",
1,
"CHAINCODE_SOURCE_DIR",
"./testdata/invalidtype",
),
Entry(
"When the metadata contents are invalid",
1,
"CHAINCODE_SOURCE_DIR",
"./testdata/invalidfile",
),
Entry(
"When the metadata does not exist",
1,
"CHAINCODE_SOURCE_DIR",
"CHAINCODE_METADATA_DIR",
),
Entry("When too few arguments are provided", 1, "CHAINCODE_SOURCE_DIR"),
Entry(
"When too many arguments are provided",
Expand Down
9 changes: 8 additions & 1 deletion cmd/release/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,14 @@ var _ = Describe("Main", func() {
Expect(indexPath).To(BeARegularFile())
textPath := filepath.Join(tempDir, "statedb", "couchdb", "indexes", "test.txt")
Expect(textPath).NotTo(BeAnExistingFile())
subdirPath := filepath.Join(tempDir, "statedb", "couchdb", "indexes", "subdir", "indexOwner.json")
subdirPath := filepath.Join(
tempDir,
"statedb",
"couchdb",
"indexes",
"subdir",
"indexOwner.json",
)
Expect(subdirPath).NotTo(BeAnExistingFile())
})
})
3 changes: 3 additions & 0 deletions cmd/release/release_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main_test

import (
"testing"
"time"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
Expand All @@ -17,6 +18,8 @@ func TestRelease(t *testing.T) {
}

var _ = BeforeSuite(func() {
SetDefaultEventuallyTimeout(2 * time.Second)

var err error
releaseCmdPath, err = gexec.Build("github.com/hyperledger-labs/fabric-builder-k8s/cmd/release")
Expect(err).NotTo(HaveOccurred())
Expand Down
4 changes: 4 additions & 0 deletions cmd/run/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,16 @@ func main() {
}
}

kubeServiceAccount := util.GetOptionalEnv(util.ChaincodeServiceAccountVariable, "default")
logger.Debugf("%s=%s", util.ChaincodeServiceAccountVariable, kubeServiceAccount)

run := &builder.Run{
BuildOutputDirectory: buildOutputDirectory,
RunMetadataDirectory: runMetadataDirectory,
PeerID: peerID,
KubeconfigPath: kubeconfigPath,
KubeNamespace: kubeNamespace,
KubeServiceAccount: kubeServiceAccount,
}

if err := run.Run(ctx); err != nil {
Expand Down
64 changes: 64 additions & 0 deletions cmd/run/main_test.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package main_test

import (
"fmt"
"os"
"os/exec"

"github.com/bitfield/script"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gbytes"
"github.com/onsi/gomega/gexec"
)

Expand All @@ -26,4 +30,64 @@ var _ = Describe("Main", func() {
"UNEXPECTED_ARGUMENT",
),
)

It(
"should start a chaincode pod using the supplied configuration environment variables",
Label("kind"),
func() {
homedir, err := os.UserHomeDir()
Expect(err).NotTo(HaveOccurred())

args := []string{"./testdata/validimage", "./testdata/validchaincode"}
command := exec.Command(runCmdPath, args...)
command.Env = append(os.Environ(),
fmt.Sprintf("KUBECONFIG_PATH=%s/.kube/config", homedir),
"CORE_PEER_ID=core-peer-id-abcdefghijklmnopqrstuvwxyz-0123456789",
"FABRIC_K8S_BUILDER_DEBUG=true",
"FABRIC_K8S_BUILDER_NAMESPACE=chaincode",
"FABRIC_K8S_BUILDER_SERVICE_ACCOUNT=chaincode",
)
session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
Expect(err).NotTo(HaveOccurred())

Eventually(session).ShouldNot(gexec.Exit())
Eventually(
session.Err,
).Should(gbytes.Say(`run \[\d+\] DEBUG: FABRIC_K8S_BUILDER_NAMESPACE=chaincode`))
Eventually(
session.Err,
).Should(gbytes.Say(`run \[\d+\] DEBUG: FABRIC_K8S_BUILDER_SERVICE_ACCOUNT=chaincode`))
Eventually(
session.Err,
).Should(gbytes.Say(`run \[\d+\]: Running chaincode ID CHAINCODE_ID in kubernetes pod chaincode/cc-mspid-core-peer-id-abcdefghijklmnopqrstuvwxyz-0123456789chai`))

pipe := script.Exec(
"kubectl wait --for=condition=ready pod --timeout=120s --namespace=chaincode -l fabric-builder-k8s-peerid=core-peer-id-abcdefghijklmnopqrstuvwxyz-0123456789",
)
_, err = pipe.Stdout()
Expect(err).NotTo(HaveOccurred())
Expect(pipe.ExitStatus()).To(Equal(0))

descArgs := []string{
"describe",
"pod",
"--namespace=chaincode",
"-l",
"fabric-builder-k8s-peerid=core-peer-id-abcdefghijklmnopqrstuvwxyz-0123456789",
}
descCommand := exec.Command("kubectl", descArgs...)
descSession, err := gexec.Start(descCommand, GinkgoWriter, GinkgoWriter)
Expect(err).NotTo(HaveOccurred())

Eventually(descSession).Should(gexec.Exit(0))
Eventually(descSession.Out).Should(gbytes.Say(`Namespace:\s+chaincode`))
Eventually(descSession.Out).Should(gbytes.Say(`fabric-builder-k8s-mspid=MSPID`))
Eventually(
descSession.Out,
).Should(gbytes.Say(`fabric-builder-k8s-ccid:\s+CHAINCODE_ID`))
Eventually(descSession.Out).Should(gbytes.Say(`CORE_CHAINCODE_ID_NAME:\s+CHAINCODE_ID`))
Eventually(descSession.Out).Should(gbytes.Say(`CORE_PEER_ADDRESS:\s+PEER_ADDRESS`))
Eventually(descSession.Out).Should(gbytes.Say(`CORE_PEER_LOCALMSPID:\s+MSPID`))
},
)
})
53 changes: 51 additions & 2 deletions cmd/run/run_suite_test.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,76 @@
package main_test

import (
"os"
"testing"
"time"

"github.com/bitfield/script"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/gexec"
)

//nolint:gochecknoglobals // not sure how to avoid this
var runCmdPath string
var (
includeKindTests bool
runCmdPath string
)

func TestRun(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Run Suite")

suiteConfig, _ := GinkgoConfiguration()

kindEnv := os.Getenv("INCLUDE_KIND_TESTS")
if kindEnv == "true" {
includeKindTests = true
} else {
includeKindTests = false
}

if !includeKindTests {
if suiteConfig.LabelFilter == "" {
suiteConfig.LabelFilter = "!kind"
} else {
suiteConfig.LabelFilter = "(" + suiteConfig.LabelFilter + ") && !kind"
}
}

RunSpecs(t, "Run Suite", suiteConfig)
}

var _ = BeforeSuite(func() {
SetDefaultEventuallyTimeout(2 * time.Second)

var err error
runCmdPath, err = gexec.Build("github.com/hyperledger-labs/fabric-builder-k8s/cmd/run")
Expect(err).NotTo(HaveOccurred())

if includeKindTests {
script.Exec("kind delete cluster --name fabric-builder-k8s-test")

pipe := script.Exec("kind create cluster --name fabric-builder-k8s-test")
_, err = pipe.Stdout()
Expect(err).NotTo(HaveOccurred())
Expect(pipe.ExitStatus()).To(Equal(0))

pipe = script.Exec("kubectl create namespace chaincode")
_, err = pipe.Stdout()
Expect(err).NotTo(HaveOccurred())
Expect(pipe.ExitStatus()).To(Equal(0))

pipe = script.Exec("kubectl create serviceaccount chaincode --namespace=chaincode")
_, err = pipe.Stdout()
Expect(err).NotTo(HaveOccurred())
Expect(pipe.ExitStatus()).To(Equal(0))
}
})

var _ = AfterSuite(func() {
gexec.CleanupBuildArtifacts()
if includeKindTests {
_, err := script.Exec("kind delete cluster --name fabric-builder-k8s-test").Stdout()
Expect(err).NotTo(HaveOccurred())
}
})
Loading

0 comments on commit 73afa85

Please sign in to comment.