Skip to content

Releases: dannyota/vngcloud

v0.81.1 - User Guides and Storage Workload Access

Choose a tag to compare

@dannyota dannyota released this 13 Oct 05:51
v0.81.1
7809588
  • 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

Choose a tag to compare

@dannyota dannyota released this 12 Oct 12:15
v0.81.0
a5e23d9
  • SDK storage.ObjectClient.CopyObject and CLI storage copy-object copy 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 ErrObjectCopyUnconfirmed and CLI
    ObjectCopyUnconfirmed with 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

Choose a tag to compare

@dannyota dannyota released this 12 Oct 11:49
v0.80.0
01cfd61
  • SDK storage.ObjectClient.DeleteObject and CLI storage 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 ErrObjectDeleteUnconfirmed and CLI
    ObjectDeleteUnconfirmed with 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

Choose a tag to compare

@dannyota dannyota released this 12 Oct 11:18
v0.79.0
953ef6d

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

Choose a tag to compare

@dannyota dannyota released this 12 Oct 06:40
v0.78.0
ccc0ea5
  • SDK storage.NewObjectClient, PutObject, and GetObject transfer arbitrary
    binary objects with explicit in-memory S3 credentials and region.
  • CLI storage put-object and storage get-object transfer 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

Choose a tag to compare

@dannyota dannyota released this 25 Sep 22:10
v0.7.0
c07bf79

Highlights

  • New cdn package: 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.ErrPageFormat rather than an empty or partial list. See
    CDN.
  • New vngcloud cdn list-ip-ranges command, a read allowed under a
    read-only profile.
  • EndpointOverrides gains CDNDocs, 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

Choose a tag to compare

@dannyota dannyota released this 25 Sep 15:21
v0.6.0
6e38d67

Highlights

  • New vngcloud command, installed with
    go install danny.vn/vngcloud/cmd/vngcloud@latest. It covers billing,
    pricing, compute, network, and dns, 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-only makes every write command fail before any request.
  • vngcloud configure and configure set|get|list edit
    ~/.vngcloud/config and credentials safely: 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.LoginError reports a failed login step, its HTTP status,
    and a suspected captcha, and never carries a credential. WithLogger now
    logs requests at Debug level. Config.ProfileSetting reads a key from the
    resolved profile.

Behavior changes

  • APIError.Code (and ErrorCode) now falls back to a status-derived code
    when the API gives none: BadRequest, Unauthorized, Forbidden,
    NotFound, Conflict, Throttled, ServerError, or ClientError. An
    envelope code equal to the HTTP status counts as none, so a billing 400 is
    BadRequest rather than "400".
  • Login failures return *vngcloud.LoginError. It matches ErrAuth,
    except when the login was cancelled or timed out: then it matches
    context.Canceled or context.DeadlineExceeded instead.

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

Choose a tag to compare

@dannyota dannyota released this 25 Sep 11:00
v0.5.0
ed37c88

Highlights

  • vngcloud.LoadConfig(ctx, opts...) resolves a Config from options,
    VNGCLOUD_* environment variables, and AWS-style profile files
    (~/.vngcloud/config and ~/.vngcloud/credentials, or
    WithConfigFile/WithSharedCredentialsFile and their environment
    variables). NewConfig keeps 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_PROFILE never
    does. An explicit profile skips environment variables for credentials and
    the project ID, so a .env file 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.ErrNoCredentials and vngcloud.ErrCredentialsFile
    both match vngcloud.ErrInvalidConfig via errors.Is.
    ErrCredentialsFile covers the credentials file missing at an explicit
    path, unreadable, refused for unsafe permissions, or malformed.
    LoadConfig refuses a credentials file that group or others can read,
    naming the file and chmod 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 also ErrNoCredentials, naming the source and the missing
    keys, so it is never completed by mixing in another source's values. No
    LoadConfig error names a credential value.
  • New vngcloud.CredentialsProvider interface (Token(ctx),
    Invalidate(accessToken)) and vngcloud.WithCredentialsProvider for a
    custom token source, such as a secrets manager. It wins over
    WithStaticToken, which wins over WithIAMUser. A provider returning an
    empty token with a nil error is vngcloud.ErrAuth; a zero ExpiresAt
    makes the SDK call Token before 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 custom CredentialsProvider is
    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 with vngcloud.ErrAuth rather 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.ErrAuth before 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

Choose a tag to compare

@dannyota dannyota released this 25 Sep 09:17
v0.4.0
396cff2

Breaking changes

  • vngcloud.NewClient and the transitional vngcloud.Client type are gone.
    Every service is now its own top-level package with New(cfg vngcloud.Config) *Client, matching billing and pricing: compute,
    volume, network, loadbalancer, globalloadbalancer, dns,
    containerregistry, portal, and project (new; replaces
    client.ListProjects).
  • NewClient used to log in eagerly, so bad credentials failed before its
    first return. NewConfig does not log in: call cfg.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
    their List*Options/List*Result types are now compute.*.
    vngcloud.Volume and Zone are volume.*. vngcloud.VPC,
    SecurityGroup, Subnet, RouteTable, and Peering are network.*.
    vngcloud.LoadBalancer, Certificate, Listener, Pool, and Policy are
    loadbalancer.*. vngcloud.GlobalLoadBalancer, GlobalPool, and
    GlobalListener are globalloadbalancer.*. vngcloud.HostedZone,
    RecordValue, and DNSRecord are dns.*. vngcloud.PortalUserInfo,
    PortalZone, PortalQuota, and PortalTagQuota are portal.UserInfo,
    portal.Zone, portal.Quota, and portal.TagQuota.
    vngcloud.ContainerRepository and ContainerRegistryUser are
    containerregistry.Repository and containerregistry.User.
    vngcloud.Project and ListProjectsOptions are project.Project and
    project.ListProjectsInput. Every *Service type (ComputeService,
    VolumeService, NetworkService, LoadBalancerService,
    GlobalLoadBalancerService, DNSService, PortalService,
    ContainerRegistryService) is gone with NewClient; call the package's own
    New(cfg). vngcloud.ListOptions, Page, and ListResult[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, and UserImage. network: WANIP, ElasticNetworkInterface,
    VirtualIPAddress, SubnetSecondarySubnet, SecurityGroupRule,
    RouteTableRoute, Tag, Interconnect, AddressPair, and
    VNetworkRegion. loadbalancer: PoolMember, HealthMonitor, L7Rule,
    and ListenerInsertHeader.
  • Every operation takes one *OpInput and returns one *OpOutput, for
    example compute.New(cfg).GetServer(ctx, &compute.GetServerInput{ServerID: id}). Methods that took bare arguments, such as GetServer(ctx, id) and
    ListSubnets(ctx), moved to Input structs. A required Input field returns
    ErrInvalidInput before any request when it is empty, including a nil
    Input.
  • List outputs name their field: Items for the page, plus Page,
    PageSize, TotalPage, and TotalItem for an API that pages. These sat
    under a nested Page field before, for example res.Page.TotalItem; they
    now sit directly on the result, for example res.TotalItem. A Get returns
    a struct with one named field, such as GetServerOutput{Server Server}.
  • Model renames drop redundant package prefixes now that each service is its
    own package: network renames NetworkRoute to Route, NetworkACL to
    ACL, NetworkEndpoint to Endpoint, NetworkEndpointDetail to
    EndpointDetail (its embedded NetworkEndpoint field is now Endpoint,
    so detail.NetworkEndpoint.Name is now detail.Endpoint.Name), and
    NetworkZone to Zone. loadbalancer renames LoadBalancerNode to
    Node, LoadBalancerPackage to Package, and LoadBalancerTag to Tag;
    its ListLoadBalancerPackages method is renamed to ListPackages, matching
    globalloadbalancer.ListPackages. globalloadbalancer (renamed from the
    glb internal package) renames every GLB- and Global-prefixed type,
    for example GlobalLoadBalancer to LoadBalancer, GLBPackage to
    Package, GLBVLBPackage (vngcloud.GlobalLoadBalancerRegionalPackage)
    to RegionalPackage, and GLBRegion
    (vngcloud.GlobalLoadBalancerRegion) to Region, GlobalLoadBalancerVIP
    to VIP, GlobalLoadBalancerDomain to Domain, GlobalPool to Pool,
    GlobalPoolHealthMonitor to PoolHealthMonitor, GlobalPoolMember to
    PoolMember, GlobalPoolMemberDetail to PoolMemberDetail,
    GlobalListener to Listener, and GlobalLoadBalancerUsageHistory to
    UsageHistory; the root re-export
    vngcloud.GlobalLoadBalancerPackage is now globalloadbalancer.Package.
    dns renames DNSRecord to Record, VpcMapRegion to VPCMapRegion,
    and HostedZone.AssocVpcMapRegion to AssocVPCMapRegion (the
    assocVpcMapRegion JSON key is unchanged). portal renames
    PortalUserInfo, PortalZone, PortalQuota, and PortalTagQuota to
    UserInfo, Zone, Quota, and TagQuota. containerregistry renames
    ContainerRepository to Repository and ContainerRegistryUser to
    User.
  • APIError.Operation is now "<package>.<Method>" in lowercase, such as
    "compute.GetServer", everywhere including project discovery
    ("project.ListProjects").

Highlights

  • network imports compute for compute.Server, since
    ListServersBySecurityGroup returns 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

Choose a tag to compare

@dannyota dannyota released this 25 Sep 02:15
v0.3.0
7f04908

Breaking changes

  • vngcloud.Config is an opaque handle built by vngcloud.NewConfig with
    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 ClientOption alias is now LoadOption.
  • A POST or PATCH is retried only after a 429 or a failed connection,
    never after a 5xx or a network error that may have reached the server.
    IsRetryable follows the same rule.
  • APIError.Code and ErrorCode now return a numeric envelope code as
    decimal text, such as "400", for every service. They returned ""
    before.

Highlights

  • New billing package: 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 pricing package: GetQuote prices a resource before it is created
    and places no order.
  • ErrInvalidInput for a missing required field, a malformed ID, or a bad
    date, returned before any request.
  • vngcloud.Ptr builds pointer fields for partial updates.
  • EndpointOverrides.Billing moves the dashboard billing gateway.
  • make live-write runs 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.