Dhutton/sre 3199 expose ib kubernetes ufm client for consumption#19
Draft
Dombo wants to merge 33 commits into
Draft
Dhutton/sre 3199 expose ib kubernetes ufm client for consumption#19Dombo wants to merge 33 commits into
Dombo wants to merge 33 commits into
Conversation
Move UFM API client logic from the plugin (package main) into pkg/ufm/ so external consumers can import it directly. The plugin shim now parses env vars and delegates to ufm.NewClient().
IsPKeyValid and GUIDToString were only used by the UFM client. Move them in as unexported functions and delete pkg/ib-utils/.
The HTTP client in pkg/drivers/http/ had no consumers outside the UFM client. Move it into pkg/ufm/http.go with a private interface and delete pkg/drivers/http/. The mock is now internal to the test files.
The httpClient interface and its implementations are private to pkg/ufm, so the methods don't need to be exported.
Move Date header parsing into Client.GetServerTime and replace getServerTime with a generic head method on httpClient. Collapse createRequest/executeRequest into a single doRequest that returns body, headers, and status code.
Replace the bespoke HTTP wrapper with idiomatic Go patterns: - authTransport RoundTripper handles basic auth and content-type - Functional options (WithTLSInsecure, WithTLSCACert) configure TLS - Single-method httpClient interface (do) for testability - HTTP verb helpers (get/post/head) live on Client, not the transport - NewClient accepts variadic options, derives defaults from Config - Tests inject mocks via withHTTPClient option through real constructor
…ient Add StatusError/CapabilityError types replacing string-based error matching. Add context.Context to all SubnetManagerClient interface methods. Add version detection with sync.Once caching, VersionInfo, and Capabilities. Validate() warms the version cache from its existing /ufm_version call.
Pull Config, Option, and TLS option functions into config.go. Move parseVersionResponse alongside parseVersion in version.go. client.go drops from 567 to 487 lines with cleaner concern separation.
Delete httpClient interface, httpClientImpl, and mock. Client stores *http.Client directly. Single do() method handles request execution and status checking (non-200 returns StatusError). Tests rewritten with httptest.Server — no mocks, full HTTP stack exercised.
Replace fmt.Sprintf JSON construction with json.Marshal of typed PKeyGUIDsRequest structs. Move inline response types (GUID, PKey, PKeyLastUpdatedResponse) to types.go with clearer names (PKeyGUID, PKeyResponse).
Move EnableIPOverIB, DefaultLimitedPartition, EnableIndex0ForPrimaryPkey, and SMTimezone out of ufm.Config. The first two were dead code in the client. The latter two become method parameters: AddGuidsToPKey now accepts index0 bool, GetLastPKeyUpdateTimestamp accepts *time.Location. Delete SetConfig from the SubnetManagerClient interface — it existed solely to pass these fields and is no longer needed. The daemon now resolves smLocation at startup and passes both values at call sites.
Accept *http.Client directly instead of hiding it behind Config. Group PKey endpoints into PKeyService (client.PKeys) and version detection into VersionService (client.Version). Export BasicAuthTransport for callers to compose their own http.Client. Delete Config, Option, and TLS helpers — the caller owns transport. Move plugin metadata (Name/Spec) and interface bridging to an adapter in the UFM plugin package. Remove Capabilities concept entirely.
All version-endpoint operations now live on VersionService: Get, Validate, and ServerTime. The top-level Client no longer has any API methods directly — callers use client.Version.* or client.PKeys.*.
Add WithBasicAuth, WithTLSInsecure, WithTLSCACert, and WithHTTPClient options to NewClient. The plugin initializer now composes these options instead of building *http.Client and TLS config inline. NewClient signature changes from (baseURL, *http.Client) to (baseURL, ...Option) returning (*Client, error).
Replace the defensive cloneTransport unwrapping logic with a simple transport() that initializes from http.DefaultTransport when nil. TLS options now precede WithBasicAuth so they operate on the raw *http.Transport before auth wrapping occurs.
Options now write to a clientConfig struct instead of mutating the transport directly. NewClient materializes the transport chain after all options have been applied: TLS config first, then auth wrapping. This eliminates the ordering constraint between options.
The separate http.go file held only BasicAuthTransport. Move it into ufm.go alongside the other transport-related code and delete the file.
Expose a top-level Connect method on Client for connectivity checks. The adapter's Validate implementation now delegates to Connect instead of routing through the version service.
Head issues an uncached HEAD request to the version endpoint and returns the server time from the Date header. The name reflects the HTTP method and distinguishes it from the cached Get.
The detect method was a trivial wrapper around do + parseVersionResponse called from exactly one place. Inline it into Get.
Introduce a per-Client UFM version range with two functional options: - WithSupportedVersionRange(VersionRange) overrides the default SupportedVersionRange. - WithSupportedVersionEnforcement() makes NewClient call EnforceSupportedVersion against the configured range, surfacing out-of-range UFM versions before the Client is handed back. Both can be combined or used independently. Without WithSupportedVersionEnforcement, callers can still invoke VersionService.EnforceSupportedVersion explicitly. Drop VersionInfo.Raw in favour of a String() method that renders M.m.p (or M.m.p-B when Build > 0) from the existing integer fields, removing the duplication between parsed and raw forms. Add VersionInfo.IsZero so range checks can treat missing bounds as "unbounded". Store the range on VersionService where it is consumed; Client no longer carries an unused field.
…rships rename Lib refinements for the UFM PKey client: * New sentinel ErrPKeyDoesNotExist + IsPKeyNotFound predicate so callers can branch on the "PKey not registered" condition without substring matches. AddGUIDsToPKey wraps the sentinel; the human-readable error message text is unchanged. * RemoveGUIDsFromPKey(ctx, RemoveGUIDsFromPKeyRequest) for verb-noun symmetry with AddGUIDsToPKey. The request type is intentionally lean (PKey + GUIDs only) because UFM's Remove endpoint is DELETE-with-URL with no body. RemoveGuids is retained as a thin wrapper. * AddGUIDsToPKeyRequest.Membership []string renamed to Memberships, with the JSON wire field flipped from "membership" to "memberships" per strict UFM spec (memberships is the per-GUID array form; membership is a singular string applied to all GUIDs). The lib emits only the per-GUID form for unambiguity, so wrappers AddGuids/AddLimitedGuids pad to the GUID count. * PKeyGUIDsRequest dropped — orphaned after the AddGUIDsToPKey rework; downstream consumers (tufmctl) declare their own stdin shape.
Expose the full method set of *PKeyService and *VersionService as named interfaces so consumers can: * Depend on the interface in their own code (testable seams). * Pass in either the real *PKeyService or a fake from a future ufmtest helper package. Compile-time guards keep the interfaces in lockstep with the services: if a method is added or signature-changed on either service, the build fails until the interface declaration catches up. No behavioural change. Pure additive surface.
The lib has only been exercised against UFM up to 6.24.1; 6.24.2 and above are not yet validated. Tighten the default supported range Max from 6.25.0 to 6.24.2 (exclusive) so the lib fails closed instead of silently allowing untested UFM versions through. Tests updated to match the new boundary: * TestEnforceSupportedVersion_Default_WithinRange — exercises 6.24.1 (the last fully-supported patch). * TestEnforceSupportedVersion_Default_AtMax — exercises 6.24.2 (the new exclusive boundary). * TestWithSupportedVersionEnforcement_PassesAtInit — switched to 6.24.1. * TestSupportedVersionRange_Defaults — assertion bumped to 6.24.2. Consumers needing 6.24.2 or 6.25.x can opt in via WithSupportedVersionRange to relax the default. The override test (TestWithSupportedVersionRange_Overrides) still uses the prior wider range to exercise that path.
Consolidate GUID/MAC/PKey conversion helpers as public API so consumers can avoid re-implementing the wire-shape ↔ typed-Go conversions in their own code. Add ClientConfig + NewClientFromConfig for the same reason on the auth side. New in pkg/ufm/format.go: * ParsePKey(string) (int, error) — hex "0x..." or decimal * FormatPKey(int) string — canonical "0xNNNN" lowercase * NormalisePKey(string) string — best-effort canonicalisation * IsPKeyValid(int) bool — promoted from internal isPKeyValid * ParseGUID(string) (net.HardwareAddr, error) — accepts colon-MAC, dash-MAC, or un-delimited 16-hex (case-insensitive) * ParseGUIDs([]string) ([]net.HardwareAddr, error) — batch form * FormatGUID(net.HardwareAddr) string — un-delimited 16-hex * CanonicaliseGUIDString(string) string — strip separators + lowercase * GUIDStringToMACString(string) string — insert colons every 2 chars New in pkg/ufm/client_config.go: * ClientConfig struct (host/username/password/ca_cert/tls_insecure) * NewClientFromConfig(cfg, opts...) — wire-shape construction; caller opts override cfg-derived ones. Internal pkey.go helpers (isPKeyValid, guidToString, convertToMacAddr) collapse to the new exported equivalents — no behaviour change.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
WIP