Unverified Commit 769cff55 authored by Brian Kassouf's avatar Brian Kassouf Committed by GitHub
Browse files

Update triton-go package (#8751)

parent 0f1a1b8b
Showing with 525 additions and 177 deletions
+525 -177
......@@ -14,7 +14,6 @@ require (
github.com/NYTimes/gziphandler v1.1.1
github.com/SAP/go-hdb v0.14.1
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect
github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af // indirect
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190620160927-9418d7b0cd0f
github.com/aliyun/aliyun-oss-go-sdk v0.0.0-20190307165228-86c17b95fcd5
github.com/apple/foundationdb/bindings/go v0.0.0-20190411004307-cd5c9d91fad2
......@@ -26,7 +25,6 @@ require (
github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 // indirect
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
github.com/chrismalek/oktasdk-go v0.0.0-20181212195951-3430665dfaa0
github.com/cockroachdb/apd v1.1.0 // indirect
github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c
github.com/coreos/go-semver v0.2.0
github.com/denisenkom/go-mssqldb v0.0.0-20190412130859-3b1d194e553a
......@@ -91,12 +89,10 @@ require (
github.com/hashicorp/vault/api v1.0.5-0.20200215224050-f6547fa8e820
github.com/hashicorp/vault/sdk v0.1.14-0.20200305172021-03a3749f220d
github.com/influxdata/influxdb v0.0.0-20190411212539-d24b7ba8c4c4
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 // indirect
github.com/jackc/pgx v3.3.0+incompatible // indirect
github.com/jcmturner/gokrb5/v8 v8.0.0
github.com/jefferai/isbadcipher v0.0.0-20190226160619-51d2077c035f
github.com/jefferai/jsonx v1.0.0
github.com/joyent/triton-go v0.0.0-20190112182421-51ffac552869
github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f
github.com/keybase/go-crypto v0.0.0-20190403132359-d65b6b94177f
github.com/kr/pretty v0.1.0
github.com/kr/text v0.1.0
......@@ -129,7 +125,6 @@ require (
github.com/sasha-s/go-deadlock v0.2.0
github.com/shirou/gopsutil v2.19.9+incompatible
github.com/shirou/w32 v0.0.0-20160930032740-bb4de0191aa4 // indirect
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 // indirect
github.com/stretchr/testify v1.4.0
github.com/tidwall/pretty v1.0.0 // indirect
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c // indirect
......
This diff is collapsed.
......@@ -33,7 +33,10 @@ import (
"os"
"strconv"
"strings"
"sync"
"sync/atomic"
"syscall"
"unsafe"
)
// Priority of a journal message
......@@ -50,19 +53,35 @@ const (
PriDebug
)
var conn net.Conn
var (
// This can be overridden at build-time:
// https://github.com/golang/go/wiki/GcToolchainTricks#including-build-information-in-the-executable
journalSocket = "/run/systemd/journal/socket"
// unixConnPtr atomically holds the local unconnected Unix-domain socket.
// Concrete safe pointer type: *net.UnixConn
unixConnPtr unsafe.Pointer
// onceConn ensures that unixConnPtr is initialized exactly once.
onceConn sync.Once
)
func init() {
var err error
conn, err = net.Dial("unixgram", "/run/systemd/journal/socket")
if err != nil {
conn = nil
}
onceConn.Do(initConn)
}
// Enabled returns true if the local systemd journal is available for logging
// Enabled checks whether the local systemd journal is available for logging.
func Enabled() bool {
return conn != nil
onceConn.Do(initConn)
if (*net.UnixConn)(atomic.LoadPointer(&unixConnPtr)) == nil {
return false
}
if _, err := net.Dial("unixgram", journalSocket); err != nil {
return false
}
return true
}
// Send a message to the local systemd journal. vars is a map of journald
......@@ -73,8 +92,14 @@ func Enabled() bool {
// (http://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html)
// for more details. vars may be nil.
func Send(message string, priority Priority, vars map[string]string) error {
conn := (*net.UnixConn)(atomic.LoadPointer(&unixConnPtr))
if conn == nil {
return journalError("could not connect to journald socket")
return errors.New("could not initialize socket to journald")
}
socketAddr := &net.UnixAddr{
Name: journalSocket,
Net: "unixgram",
}
data := new(bytes.Buffer)
......@@ -84,32 +109,30 @@ func Send(message string, priority Priority, vars map[string]string) error {
appendVariable(data, k, v)
}
_, err := io.Copy(conn, data)
if err != nil && isSocketSpaceError(err) {
file, err := tempFd()
if err != nil {
return journalError(err.Error())
}
defer file.Close()
_, err = io.Copy(file, data)
if err != nil {
return journalError(err.Error())
}
rights := syscall.UnixRights(int(file.Fd()))
_, _, err := conn.WriteMsgUnix(data.Bytes(), nil, socketAddr)
if err == nil {
return nil
}
if !isSocketSpaceError(err) {
return err
}
/* this connection should always be a UnixConn, but better safe than sorry */
unixConn, ok := conn.(*net.UnixConn)
if !ok {
return journalError("can't send file through non-Unix connection")
}
_, _, err = unixConn.WriteMsgUnix([]byte{}, rights, nil)
if err != nil {
return journalError(err.Error())
}
} else if err != nil {
return journalError(err.Error())
// Large log entry, send it via tempfile and ancillary-fd.
file, err := tempFd()
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(file, data)
if err != nil {
return err
}
rights := syscall.UnixRights(int(file.Fd()))
_, _, err = conn.WriteMsgUnix([]byte{}, rights, socketAddr)
if err != nil {
return err
}
return nil
}
......@@ -119,8 +142,8 @@ func Print(priority Priority, format string, a ...interface{}) error {
}
func appendVariable(w io.Writer, name, value string) {
if !validVarName(name) {
journalError("variable name contains invalid character, ignoring")
if err := validVarName(name); err != nil {
fmt.Fprintf(os.Stderr, "variable name %s contains invalid character, ignoring\n", name)
}
if strings.ContainsRune(value, '\n') {
/* When the value contains a newline, we write:
......@@ -137,32 +160,42 @@ func appendVariable(w io.Writer, name, value string) {
}
}
func validVarName(name string) bool {
/* The variable name must be in uppercase and consist only of characters,
* numbers and underscores, and may not begin with an underscore. (from the docs)
*/
// validVarName validates a variable name to make sure journald will accept it.
// The variable name must be in uppercase and consist only of characters,
// numbers and underscores, and may not begin with an underscore:
// https://www.freedesktop.org/software/systemd/man/sd_journal_print.html
func validVarName(name string) error {
if name == "" {
return errors.New("Empty variable name")
} else if name[0] == '_' {
return errors.New("Variable name begins with an underscore")
}
valid := name[0] != '_'
for _, c := range name {
valid = valid && ('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_'
if !(('A' <= c && c <= 'Z') || ('0' <= c && c <= '9') || c == '_') {
return errors.New("Variable name contains invalid characters")
}
}
return valid
return nil
}
// isSocketSpaceError checks whether the error is signaling
// an "overlarge message" condition.
func isSocketSpaceError(err error) bool {
opErr, ok := err.(*net.OpError)
if !ok {
if !ok || opErr == nil {
return false
}
sysErr, ok := opErr.Err.(syscall.Errno)
if !ok {
sysErr, ok := opErr.Err.(*os.SyscallError)
if !ok || sysErr == nil {
return false
}
return sysErr == syscall.EMSGSIZE || sysErr == syscall.ENOBUFS
return sysErr.Err == syscall.EMSGSIZE || sysErr.Err == syscall.ENOBUFS
}
// tempFd creates a temporary, unlinked file under `/dev/shm`.
func tempFd() (*os.File, error) {
file, err := ioutil.TempFile("/dev/shm/", "journal.XXXXX")
if err != nil {
......@@ -175,8 +208,18 @@ func tempFd() (*os.File, error) {
return file, nil
}
func journalError(s string) error {
s = "journal error: " + s
fmt.Fprintln(os.Stderr, s)
return errors.New(s)
// initConn initializes the global `unixConnPtr` socket.
// It is meant to be called exactly once, at program startup.
func initConn() {
autobind, err := net.ResolveUnixAddr("unixgram", "")
if err != nil {
return
}
sock, err := net.ListenUnixgram("unixgram", autobind)
if err != nil {
return
}
atomic.StorePointer(&unixConnPtr, unsafe.Pointer(sock))
}
......@@ -21,7 +21,7 @@ Still the job of `main` to expose these configurations. `main` may delegate this
Splitting streams is probably not the job of your program, but rather, your log aggregation framework. If you must split output streams, again, `main` configures this and you can write a very simple two-output struct that satisfies io.Writer.
Fancy colorful formatting and JSON output are beyond the scope of a basic logging framework -- they're application/log-collector dependant. These are, at best, provided as options, but more likely, provided by your application.
Fancy colorful formatting and JSON output are beyond the scope of a basic logging framework -- they're application/log-collector dependent. These are, at best, provided as options, but more likely, provided by your application.
##### Log objects are an interface
......
......@@ -32,7 +32,7 @@ import (
func init() {
initHijack()
// Go `log` pacakge uses os.Stderr.
// Go `log` package uses os.Stderr.
SetFormatter(NewDefaultFormatter(os.Stderr))
SetGlobalLogLevel(INFO)
}
......
......@@ -95,6 +95,11 @@ func (l *LogLevel) Set(s string) error {
return nil
}
// Returns an empty string, only here to fulfill the pflag.Value interface.
func (l *LogLevel) Type() string {
return ""
}
// ParseLevel translates some potential loglevel strings into their corresponding levels.
func ParseLevel(s string) (LogLevel, error) {
switch s {
......
......@@ -37,6 +37,14 @@ func (p *PackageLogger) internalLog(depth int, inLevel LogLevel, entries ...inte
}
}
// SetLevel allows users to change the current logging level.
func (p *PackageLogger) SetLevel(l LogLevel) {
logger.Lock()
defer logger.Unlock()
p.level = l
}
// LevelAt checks if the given log level will be outputted under current setting.
func (p *PackageLogger) LevelAt(l LogLevel) bool {
logger.Lock()
defer logger.Unlock()
......@@ -81,6 +89,12 @@ func (p *PackageLogger) Panic(args ...interface{}) {
panic(s)
}
func (p *PackageLogger) Panicln(args ...interface{}) {
s := fmt.Sprintln(args...)
p.internalLog(calldepth, CRITICAL, s)
panic(s)
}
func (p *PackageLogger) Fatalf(format string, args ...interface{}) {
p.Logf(CRITICAL, format, args...)
os.Exit(1)
......
## Unreleased
## 1.6.1 (June 26 2019)
- compute/networks: support network objects for AddNIC [#169]
## 1.6.0 (June 24 2019)
- compute/networks: added support for network objects [#158]
- compute/instances: added instances().get support for deleted instances [#167]
- storage: added support for multipart upload [#160]
- storage: fixed directory list marker filtering [#156]
## 1.3.1 (April 27 2018)
- client: Fixing an issue where private Triton installations were marked as invalid DC [#152]
......
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#
#
# Copyright 2019 Joyent, Inc.
#
TEST?=$$(go list ./... |grep -Ev 'vendor|examples|testutils')
GOFMT_FILES?=$$(find . -name '*.go' |grep -v vendor)
default: check test
.PHONY: all
all:
tools:: ## Download and install all dev/code tools
.PHONY: tools
tools: ## Download and install all dev/code tools
@echo "==> Installing dev tools"
go get -u github.com/golang/dep/cmd/dep
go get -u github.com/alecthomas/gometalinter
gometalinter --install
build::
.PHONY: build
build:
@govvv build
install::
.PHONY: install
install:
@govvv install
test:: ## Run unit tests
.PHONY: test
test: ## Run unit tests
@echo "==> Running unit test with coverage"
@./scripts/go-test-with-coverage.sh
testacc:: ## Run acceptance tests
.PHONY: testacc
testacc: ## Run acceptance tests
@echo "==> Running acceptance tests"
TRITON_TEST=1 go test $(TEST) -v $(TESTARGS) -run -timeout 120m
check::
gometalinter \
--deadline 10m \
--vendor \
--sort="path" \
--aggregate \
--enable-gc \
--disable-all \
--enable goimports \
--enable misspell \
--enable vet \
--enable deadcode \
--enable varcheck \
--enable ineffassign \
--enable gofmt \
./...
.PHONY: check
check:
scripts/gofmt-check.sh
.PHONY: help
help:: ## Display this help message
help: ## Display this help message
@echo "GNU make(1) targets:"
@grep -E '^[a-zA-Z_.-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-15s\033[0m %s\n", $$1, $$2}'
......@@ -3,8 +3,6 @@
`triton-go` is a client SDK for Go applications using Joyent's Triton Compute
and Object Storage (Manta) APIs.
[![Build Status](https://travis-ci.org/joyent/triton-go.svg?branch=master)](https://travis-ci.org/joyent/triton-go) [![Go Report Card](https://goreportcard.com/badge/github.com/joyent/triton-go)](https://goreportcard.com/report/github.com/joyent/triton-go)
The Triton Go SDK is used in the following open source projects.
- [Consul](https://www.consul.io/docs/agent/cloud-auto-join.html#joyent-triton)
......@@ -89,6 +87,12 @@ is performed using the [pkg/errors][7] library.
## Acceptance Tests
_**NOTE:** The tests are not currently well-structured, and depend on many
hard-coded specifics of the Joyent Public Cloud (JPC) which is being shut down
in November 2019. It is likely not possible to run the test suite against a
local Triton installation at this time, though that is definitely the intended
test suite target environment for future development._
Acceptance Tests run directly against the Triton API, so you will need either a
local installation of Triton or an account with Joyent's Public Cloud offering
in order to run them. The tests create real resources (and thus cost real
......@@ -106,7 +110,7 @@ set:
Additionally, you may set `TRITON_KEY_MATERIAL` to the contents of an unencrypted
private key. If this is set, the PrivateKeySigner (see above) will be used - if
not the SSHAgentSigner will be used. You can also set `TRITON_USER` to run the tests
against an account other than the main Triton account
against an account other than the main Triton account.
### Example Run
......
//
// Copyright (c) 2018, Joyent, Inc. All rights reserved.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
package authentication
// DON'T USE THIS OUTSIDE TESTING ~ This key was only created to use for
// internal unit testing. It should never be used for acceptance testing either.
//
// This is just a randomly generated key pair.
var Dummy = struct {
Fingerprint string
PrivateKey []byte
PublicKey []byte
Signer Signer
}{
"9f:d6:65:fc:d6:60:dc:d0:4e:db:2d:75:f7:92:8c:31",
[]byte(`-----BEGIN RSA PRIVATE KEY-----
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
-----END RSA PRIVATE KEY-----`),
[]byte(`ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC6L2U2MIlqEd4VIULodeL8I1fnzwL8vaAlTHrluc2mFUL3yFbXDOhG89cfHlpadvuURuk2E/oHRSgIENNo+C32Ed8P+g1D7odPVCkMgZ9mZcj3X+1yMZVIFvE3tZpi38ew+saNtqXC9A8KE3newxWYWQxMQNHkbfM4E4Aas6KaUJPzTAjZLleDSyl3yOMozkjWzANHTG24NacdNHU6GKf6kRAgTqCUtN9iruhDHqeYxdcE2aT5Jo8PUUDKOQX/zWKbYQdcHKA0TCtpWsNwDEraYqVTZcwmKiBAo1haWbdSRs0HpY8t7Xb4prTauYhWxKoilz9kIGtoCUJpJaVgKRT68naEf/7KnLltc2VtpOJZkr6+4js8LztPnTIs15dW41kDKfMOkEK+yOKIesH9kVF9V8Xo++JXwJX6bsZPN8DAmFV5JuWtHqe2zXorQdMPjy/nsNTRvS3lU68LtxY9KGz5p91IvdnxF4vkRYyBTXB++3JxEp6GINUaPcyzZx/zdEgA2vfzsb7UtxNBg/skm4HtK/LmP5Hr4eMjRyC7gQxQ91Z8I0YbKuXHAk20+ZRJ9qwfXFQqmqvt0L7Sw3j+B8nDvlZMBisBOQ/N7Ghg1oywYN+G6iGRhrdOfarWDeSqGxf9HQV3l3x3mpzXfupxELGJljP1/dtWRdBuFiY711rcqw== test-dummy-20171002140848`),
nil,
}
func init() {
testSigner, _ := NewTestSigner()
Dummy.Signer = testSigner
}
//
// Copyright (c) 2018, Joyent, Inc. All rights reserved.
// Copyright 2019 Joyent, Inc.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
......@@ -225,12 +225,12 @@ func doNotFollowRedirects(*http.Request, []*http.Request) error {
}
// DecodeError decodes a backend Triton error into a more usable Go error type
func (c *Client) DecodeError(resp *http.Response, requestMethod string) error {
func (c *Client) DecodeError(resp *http.Response, requestMethod string, consumeBody bool) error {
err := &errors.APIError{
StatusCode: resp.StatusCode,
}
if requestMethod != http.MethodHead && resp.Body != nil {
if requestMethod != http.MethodHead && resp.Body != nil && consumeBody {
errorDecoder := json.NewDecoder(resp.Body)
if err := errorDecoder.Decode(err); err != nil {
return pkgerrors.Wrapf(err, "unable to decode error response")
......@@ -267,6 +267,9 @@ type RequestInput struct {
Query *url.Values
Headers *http.Header
Body interface{}
// If the response has the HTTP status code 410 (i.e., "Gone"), should we preserve the contents of the body for the caller?
PreserveGone bool
}
func (c *Client) ExecuteRequestURIParams(ctx context.Context, inputs RequestInput) (io.ReadCloser, error) {
......@@ -330,7 +333,7 @@ func (c *Client) ExecuteRequestURIParams(ctx context.Context, inputs RequestInpu
return resp.Body, nil
}
return nil, c.DecodeError(resp, req.Method)
return nil, c.DecodeError(resp, req.Method, true)
}
func (c *Client) ExecuteRequest(ctx context.Context, inputs RequestInput) (io.ReadCloser, error) {
......@@ -398,7 +401,13 @@ func (c *Client) ExecuteRequestRaw(ctx context.Context, inputs RequestInput) (*h
return resp, nil
}
return nil, c.DecodeError(resp, req.Method)
// GetMachine returns a HTTP 410 response for deleted instances, but the body of the response is still a valid machine object with a State value of "deleted". Return the object to the caller as well as an error.
if inputs.PreserveGone && resp.StatusCode == http.StatusGone {
// Do not consume the response body.
return resp, c.DecodeError(resp, req.Method, false)
}
return nil, c.DecodeError(resp, req.Method, true)
}
func (c *Client) ExecuteRequestStorage(ctx context.Context, inputs RequestInput) (io.ReadCloser, http.Header, error) {
......@@ -468,7 +477,7 @@ func (c *Client) ExecuteRequestStorage(ctx context.Context, inputs RequestInput)
return resp.Body, resp.Header, nil
}
return nil, nil, c.DecodeError(resp, req.Method)
return nil, nil, c.DecodeError(resp, req.Method, true)
}
type RequestNoEncodeInput struct {
......@@ -535,7 +544,7 @@ func (c *Client) ExecuteRequestNoEncode(ctx context.Context, inputs RequestNoEnc
return resp.Body, resp.Header, nil
}
return nil, nil, c.DecodeError(resp, req.Method)
return nil, nil, c.DecodeError(resp, req.Method, true)
}
func (c *Client) ExecuteRequestTSG(ctx context.Context, inputs RequestInput) (io.ReadCloser, error) {
......
module github.com/joyent/triton-go
require (
github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af
github.com/cockroachdb/apd v1.1.0 // indirect
github.com/dustin/go-humanize v1.0.0
github.com/imdario/mergo v0.3.6
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 // indirect
github.com/jackc/pgx v3.3.0+incompatible
github.com/lib/pq v1.1.1 // indirect
github.com/mattn/go-isatty v0.0.8
github.com/mattn/go-runewidth v0.0.3 // indirect
github.com/olekukonko/tablewriter v0.0.0-20180130162743-b8a9be070da4
github.com/pkg/errors v0.8.1
github.com/rs/zerolog v1.4.0
github.com/satori/go.uuid v1.2.0 // indirect
github.com/sean-/conswriter v0.0.0-20180208195008-f5ae3917a627
github.com/sean-/pager v0.0.0-20180208200047-666be9bf53b5 // indirect
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24 // indirect
github.com/spf13/afero v1.2.1 // indirect
github.com/spf13/cobra v0.0.5
github.com/spf13/pflag v1.0.3
github.com/spf13/viper v1.4.0
github.com/stretchr/testify v1.3.0 // indirect
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8
golang.org/x/sys v0.0.0-20190515120540-06a5c4944438 // indirect
golang.org/x/text v0.3.2 // indirect
)
This diff is collapsed.
......@@ -15,7 +15,7 @@ import (
// Version represents main version number of the current release
// of the Triton-go SDK.
const Version = "1.5.1"
const Version = "1.7.0"
// Prerelease adds a pre-release marker to the version.
//
......
......@@ -193,9 +193,9 @@ github.com/containerd/continuity/pathdriver
github.com/coreos/go-oidc
# github.com/coreos/go-semver v0.2.0
github.com/coreos/go-semver/semver
# github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7
# github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e
github.com/coreos/go-systemd/journal
# github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf
# github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f
github.com/coreos/pkg/capnslog
# github.com/davecgh/go-spew v1.1.1
github.com/davecgh/go-spew/spew
......@@ -543,7 +543,7 @@ github.com/jefferai/isbadcipher
github.com/jefferai/jsonx
# github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af
github.com/jmespath/go-jmespath
# github.com/joyent/triton-go v0.0.0-20190112182421-51ffac552869
# github.com/joyent/triton-go v1.7.1-0.20200416154420-6801d15b779f
github.com/joyent/triton-go
github.com/joyent/triton-go/authentication
github.com/joyent/triton-go/client
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment