Repository navigation
Releases: dannyota/vngcloud
Release list
v0.81.1 - User Guides and Storage Workload Access
- Document application access to vStorage from vServer and VKS: dedicated
identities, bucket grants, private S3 key handoff, rotation, retirement,
and network prerequisites. See Storage Workload Access. - Clarify key retirement and ambiguous-create recovery: delete identified
keys while attached, reconcile uncertain results with known inventory and
other creators, and preserve unrelated keys and policy grants. - Improve README and Wiki navigation, put credential prerequisites before
first-use examples, keep quick starts read-only, and identify SDK server
counts as one page. Add CDN, Monitor, and current object operations to the
service overview. - Correct guidance on secret redaction, Windows file permissions, endpoint
overrides, and operation-specific retries. Clarify the CLI read-only guard
and quote checks without implying IAM restrictions or final billing locks. - This patch changes documentation only. It adds no SDK or CLI operations or
endpoint APIs.
v0.81.0
- SDK
storage.ObjectClient.CopyObjectand CLIstorage copy-objectcopy one
current object directly within vStorage, retaining the source. Both buckets
must belong to the same project and region. - The SDK requires
Replace: true; the CLI requires--replace --yes.
Read-only settings refuse before credentials load. Source and destination
names remain subject to concurrent changes; no version selector or
create-only destination guarantee is provided. - One bodyless signed PUT uses
x-amz-copy-source. There is no local spool,
download/upload fallback, source deletion, multipart copy, or retry.
A complete bounded result is required; HTTP 200 with an Error is not success. - Ambiguous results use
ErrObjectCopyUnconfirmedand CLI
ObjectCopyUnconfirmedwith exit 1. Inspect the destination before deciding
whether to repeat the copy. Failed metadata output after confirmed success
reports completion and never resends. - Provider metadata defaults apply without a lossless clone or encryption
inheritance guarantee. Recorded HCM04 encrypted sources return 501, and a
plain-source copy can remain unencrypted despite destination bucket
encryption. HAN02 encryption and GreenNode's exact copy size limit remain
unverified. No new live verification is claimed. - Existing transfers, listing, HEAD, and deletion remain available. Move/rename
stays gated on safe source removal. See copy guidance.
v0.80.0 - Native vStorage Object Deletion
- SDK
storage.ObjectClient.DeleteObjectand CLIstorage delete-object
delete one current object name. The CLI requires--yes; every read-only
setting refuses before S3 credentials load. - Each invocation sends one unconditional DELETE. HTTP 204 confirms acceptance,
without proving prior existence, permanent erasure, or reclaimed quota.
Concurrent writers remain unprotected, and versioning can retain data or add
a delete marker. No version selector, precondition, retry, or cleanup is added. - Ambiguous results return
ErrObjectDeleteUnconfirmedand CLI
ObjectDeleteUnconfirmedwith exit 1. Inspect the current key and version
history before another deletion. Failed metadata output after confirmed
success reports completion and never resends. - Explicit S3 region and private credentials-file flags, safe metadata output,
and the five-minute default timeout remain. No new live verification is
claimed. Native copy is a separate release; move/rename remains gated.
See object guidance.
v0.79.0 - Native vStorage Object Reads
SDK storage.ObjectClient.ListObjects and HeadObject, plus CLI storage list-objects and storage head-object, add native object discovery and metadata inspection.
- List one bounded page of up to 1,000 combined objects and common prefixes. Continue explicitly with the returned opaque token and unchanged filters.
- Inspect metadata with HEAD without downloading content. Missing length is -1; optional unsafe or oversized fields are omitted.
- Both CLI commands use explicit S3 region and private credentials-file flags and work in read-only mode on Linux and macOS.
- Metadata output supports JSON, table, text and queries. No automatic pagination, application retry or confirmation request is added.
- Both regions use published compatibility, with additional recorded listing evidence for HCM04. This release adds deterministic tests, not new live verification.
- PUT/GET behavior is preserved. Delete and server-side copy remain separate releases; safe move/rename remains gated.
v0.78.0 - Native vStorage Object Transfers
- SDK
storage.NewObjectClient,PutObject, andGetObjecttransfer arbitrary
binary objects with explicit in-memory S3 credentials and region. - CLI
storage put-objectandstorage get-objecttransfer regular files on
Linux and macOS using a private--s3-credentials-file. Output contains
metadata; object bytes stay in files. Management authentication is separate. - Uploads create only by default. Remote or local replacement requires
--replace --yes. Read-only mode blocks uploads and permits downloads. - Uploads are capped at 5,000,000,000 bytes. Downloads have a configurable
finite bound. Transfers default to a five-minute deadline. Uploads use a
private snapshot; downloads publish only after complete local writes. - HCM04 supports create-only uploads. HAN02 supports downloads and explicit
replacement; create-only uploads remain disabled pending server evidence. - An unconfirmed upload may already exist. Download to a fresh path and compare
byte length and SHA256 before retrying. No transfer retries automatically.
ETag remains opaque; a local digest does not verify a remote checksum. - Listing, HEAD, append, delete, sync, multipart uploads, and presigned URLs
remain outside the native transfer surface. See object transfer guidance.
Validation: local race tests, vet, lint, and independent security review passed.
Secret scanning uses gitleaks. Semgrep checks Code and Supply Chain.
v0.7.0 - CDN IP Ranges
Highlights
- New
cdnpackage:cdn.New(cfg).ListIPRanges(ctx, nil)returns the
current GreenNode CDN IP ranges an origin must allow, as sorted,
de-duplicated, canonical CIDR strings. vCDN has no API, so the SDK reads
GreenNode's public FAQ page instead; the request carries no credential
and no cookie. Any doubt about the page's shape fails the call with
cdn.ErrPageFormatrather than an empty or partial list. See
CDN. - New
vngcloud cdn list-ip-rangescommand, a read allowed under a
read-only profile. EndpointOverridesgainsCDNDocs, for pointing the read at a mirror or
a test server.
Behavior changes
None: this release adds a package, an endpoint field, and an internal
transport option. No existing method, field, or command changes.
v0.6.0 - The vngcloud Command
Highlights
- New
vngcloudcommand, installed with
go install danny.vn/vngcloud/cmd/vngcloud@latest. It coversbilling,
pricing,compute,network, anddns, with one subcommand per SDK
operation and flags derived from each operation's Input. --output json|table|text,--query(JMESPath),--cli-input-json, and
--debug, which logs each request's method, path, status, and timing and
never a body, header, token, or credential.- Errors print to stderr as one JSON line with stable exit codes: 1 for API
or network errors and cancellation, 2 for usage and config errors, 3 for
credential and login errors, 4 for not found. - Destructive commands (
billing delete-budget,delete-budget-threshold)
need--yes. Nothing prompts without a terminal. - Read-only profiles:
read_only = true,VNGCLOUD_READ_ONLY=1, or
--read-onlymakes every write command fail before any request. vngcloud configureandconfigure set|get|listedit
~/.vngcloud/configandcredentialssafely: mode 0600 files in a 0700
directory, written through a temp file and rename, symlinks kept, secrets
never taken from the command line.- Generated CLI reference pages in the wiki.
- SDK:
vngcloud.LoginErrorreports a failed login step, its HTTP status,
and a suspected captcha, and never carries a credential.WithLoggernow
logs requests at Debug level.Config.ProfileSettingreads a key from the
resolved profile.
Behavior changes
APIError.Code(andErrorCode) now falls back to a status-derived code
when the API gives none:BadRequest,Unauthorized,Forbidden,
NotFound,Conflict,Throttled,ServerError, orClientError. An
envelope code equal to the HTTP status counts as none, so a billing 400 is
BadRequestrather than"400".- Login failures return
*vngcloud.LoginError. It matchesErrAuth,
except when the login was cancelled or timed out: then it matches
context.Canceledorcontext.DeadlineExceededinstead.
Dependencies
The command adds github.com/spf13/cobra, github.com/spf13/pflag,
github.com/jmespath/go-jmespath, and golang.org/x/term (with
golang.org/x/sys and, on Windows, github.com/inconshreveable/mousetrap).
Only cmd/vngcloud and internal/cli import them; the SDK packages stay
standard-library only, and CI checks it.
v0.5.0 - LoadConfig, Profiles, and Token Cache
Highlights
vngcloud.LoadConfig(ctx, opts...)resolves aConfigfrom options,
VNGCLOUD_*environment variables, and AWS-style profile files
(~/.vngcloud/configand~/.vngcloud/credentials, or
WithConfigFile/WithSharedCredentialsFileand their environment
variables).NewConfigkeeps building from options only. Precedence is
options, then environment variables, then the resolved profile's file
section; credentials resolve as one set from the first source that sets
any value, so a profile's password is never mixed with another source's
username, and an access token wins over IAM User values within one
source. See Configuration
for the full precedence table, file formats, and environment variables.WithProfile(name)selects a profile explicitly;VNGCLOUD_PROFILEnever
does. An explicit profile skips environment variables for credentials and
the project ID, so a.envfile for one account can never send a call
made with another profile to that account. An explicit profile with no
credentials, from options or its own file section, fails with the new
vngcloud.ErrNoCredentials, naming the profile.- New sentinels
vngcloud.ErrNoCredentialsandvngcloud.ErrCredentialsFile
both matchvngcloud.ErrInvalidConfigviaerrors.Is.
ErrCredentialsFilecovers the credentials file missing at an explicit
path, unreadable, refused for unsafe permissions, or malformed.
LoadConfigrefuses a credentials file that group or others can read,
naming the file andchmod 600, before reading it; the check is skipped
on Windows. A path that is not a regular file, such as a directory or a
FIFO, is also an error. A source (the environment or a profile) that sets
some IAM User credentials but not all of root_email, username, and
password is alsoErrNoCredentials, naming the source and the missing
keys, so it is never completed by mixing in another source's values. No
LoadConfigerror names a credential value. - New
vngcloud.CredentialsProviderinterface (Token(ctx),
Invalidate(accessToken)) andvngcloud.WithCredentialsProviderfor a
custom token source, such as a secrets manager. It wins over
WithStaticToken, which wins overWithIAMUser. A provider returning an
empty token with a nil error isvngcloud.ErrAuth; a zeroExpiresAt
makes the SDK callTokenbefore every request. vngcloud.WithTokenCache(dir)turns on an on-disk token cache shared
across processes, so a program run repeatedly, or several programs
sharing one profile, log in only once per token lifetime. Only IAM User
credentials use it; a static token or a customCredentialsProvideris
never written to disk, and without this option the SDK writes nothing.
The cache directory is mode 0700, each token file mode 0600, and one
locked operation per credential set reads, logs in only if needed, and
writes back, so two processes sharing one profile never log in with the
same TOTP code.- Fixed the retry after an HTTP 401: the SDK used to clear its in-memory
token but let the IAM User's own cache immediately hand back that same
rejected token, so the retry failed the same way every time. It now
invalidates exactly the token it sent, in memory and (with a token cache)
on disk, and logs in again before retrying once. A token younger than 30
seconds is left in place instead, so a 401 that a fresh login cannot fix
ends the call withvngcloud.ErrAuthrather than forcing a second login
inside the same 30-second TOTP window. Parallel requests that all get a
401 for the same token cause at most one new login. A request that needs
authentication, including the retry itself, is never sent without a
token; if the token source has none to give, the call fails with
vngcloud.ErrAuthbefore anything goes out. - Fixed the token cache stamping every token it reads from disk with the
read time: a process that reused another process's still-cached token
now keeps that token's real obtain time, so the 30-second rule can still
invalidate an old, revoked token instead of treating it as freshly
obtained forever.
v0.4.0 - Service Packages
Breaking changes
vngcloud.NewClientand the transitionalvngcloud.Clienttype are gone.
Every service is now its own top-level package withNew(cfg vngcloud.Config) *Client, matchingbillingandpricing:compute,
volume,network,loadbalancer,globalloadbalancer,dns,
containerregistry,portal, andproject(new; replaces
client.ListProjects).NewClientused to log in eagerly, so bad credentials failed before its
first return.NewConfigdoes not log in: callcfg.Authenticate(ctx)
right after it to get that same fail-fast check, or skip it and let the
first service call log in lazily.- Every root re-export of a service type is gone; import the service package
instead.vngcloud.Server,NetworkInterface,SSHKey,ServerGroup, and
theirList*Options/List*Resulttypes are nowcompute.*.
vngcloud.VolumeandZonearevolume.*.vngcloud.VPC,
SecurityGroup,Subnet,RouteTable, andPeeringarenetwork.*.
vngcloud.LoadBalancer,Certificate,Listener,Pool, andPolicyare
loadbalancer.*.vngcloud.GlobalLoadBalancer,GlobalPool, and
GlobalListeneraregloballoadbalancer.*.vngcloud.HostedZone,
RecordValue, andDNSRecordaredns.*.vngcloud.PortalUserInfo,
PortalZone,PortalQuota, andPortalTagQuotaareportal.UserInfo,
portal.Zone,portal.Quota, andportal.TagQuota.
vngcloud.ContainerRepositoryandContainerRegistryUserare
containerregistry.Repositoryandcontainerregistry.User.
vngcloud.ProjectandListProjectsOptionsareproject.Projectand
project.ListProjectsInput. Every*Servicetype (ComputeService,
VolumeService,NetworkService,LoadBalancerService,
GlobalLoadBalancerService,DNSService,PortalService,
ContainerRegistryService) is gone withNewClient; call the package's own
New(cfg).vngcloud.ListOptions,Page, andListResult[T]are gone;
see the paging change below. - These root types moved to their package with the same name:
compute:
Flavor,Image,PackageLimit,ServerSecgroup,ServerGroupMember,
ServerSecurityGroup,ServerGroupMembership,ServerGroupPolicy,
OSImage, andUserImage.network:WANIP,ElasticNetworkInterface,
VirtualIPAddress,SubnetSecondarySubnet,SecurityGroupRule,
RouteTableRoute,Tag,Interconnect,AddressPair, and
VNetworkRegion.loadbalancer:PoolMember,HealthMonitor,L7Rule,
andListenerInsertHeader. - Every operation takes one
*OpInputand returns one*OpOutput, for
examplecompute.New(cfg).GetServer(ctx, &compute.GetServerInput{ServerID: id}). Methods that took bare arguments, such asGetServer(ctx, id)and
ListSubnets(ctx), moved to Input structs. A required Input field returns
ErrInvalidInputbefore any request when it is empty, including a nil
Input. - List outputs name their field:
Itemsfor the page, plusPage,
PageSize,TotalPage, andTotalItemfor an API that pages. These sat
under a nestedPagefield before, for exampleres.Page.TotalItem; they
now sit directly on the result, for exampleres.TotalItem. A Get returns
a struct with one named field, such asGetServerOutput{Server Server}. - Model renames drop redundant package prefixes now that each service is its
own package:networkrenamesNetworkRoutetoRoute,NetworkACLto
ACL,NetworkEndpointtoEndpoint,NetworkEndpointDetailto
EndpointDetail(its embeddedNetworkEndpointfield is nowEndpoint,
sodetail.NetworkEndpoint.Nameis nowdetail.Endpoint.Name), and
NetworkZonetoZone.loadbalancerrenamesLoadBalancerNodeto
Node,LoadBalancerPackagetoPackage, andLoadBalancerTagtoTag;
itsListLoadBalancerPackagesmethod is renamed toListPackages, matching
globalloadbalancer.ListPackages.globalloadbalancer(renamed from the
glbinternal package) renames everyGLB- andGlobal-prefixed type,
for exampleGlobalLoadBalancertoLoadBalancer,GLBPackageto
Package,GLBVLBPackage(vngcloud.GlobalLoadBalancerRegionalPackage)
toRegionalPackage, andGLBRegion
(vngcloud.GlobalLoadBalancerRegion) toRegion,GlobalLoadBalancerVIP
toVIP,GlobalLoadBalancerDomaintoDomain,GlobalPooltoPool,
GlobalPoolHealthMonitortoPoolHealthMonitor,GlobalPoolMemberto
PoolMember,GlobalPoolMemberDetailtoPoolMemberDetail,
GlobalListenertoListener, andGlobalLoadBalancerUsageHistoryto
UsageHistory; the root re-export
vngcloud.GlobalLoadBalancerPackageis nowgloballoadbalancer.Package.
dnsrenamesDNSRecordtoRecord,VpcMapRegiontoVPCMapRegion,
andHostedZone.AssocVpcMapRegiontoAssocVPCMapRegion(the
assocVpcMapRegionJSON key is unchanged).portalrenames
PortalUserInfo,PortalZone,PortalQuota, andPortalTagQuotato
UserInfo,Zone,Quota, andTagQuota.containerregistryrenames
ContainerRepositorytoRepositoryandContainerRegistryUserto
User. APIError.Operationis now"<package>.<Method>"in lowercase, such as
"compute.GetServer", everywhere including project discovery
("project.ListProjects").
Highlights
networkimportscomputeforcompute.Server, since
ListServersBySecurityGroupreturns full server objects.- No API coverage changed: every method that existed before keeps its
behavior under the new signature.
v0.3.0 - Budgets and Price Quotes
Breaking changes
vngcloud.Configis an opaque handle built byvngcloud.NewConfigwith
WithRegion,WithProjectID,WithIAMUser, and the existing options.
vngcloud.NewClient(ctx, cfg)takes that Config and no options. Every
client built from one Config shares one login and project lookup.- The
ClientOptionalias is nowLoadOption. - A
POSTorPATCHis retried only after a 429 or a failed connection,
never after a 5xx or a network error that may have reached the server.
IsRetryablefollows the same rule. APIError.CodeandErrorCodenow return a numeric envelope code as
decimal text, such as"400", for every service. They returned""
before.
Highlights
- New
billingpackage: budgets, budget thresholds, alert history,
current-period cost, cost explorer, and balances. Budget and threshold
create, update, and delete are the first write APIs. - New
pricingpackage:GetQuoteprices a resource before it is created
and places no order. ErrInvalidInputfor a missing required field, a malformed ID, or a bad
date, returned before any request.vngcloud.Ptrbuilds pointer fields for partial updates.EndpointOverrides.Billingmoves the dashboard billing gateway.make live-writeruns a gated live budget write test.
Known limits
- The cost explorer and alert history models follow the console's field
names but have not been checked against a live response with data yet.