Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LocalFileConfigLoader #8

Merged
merged 4 commits into from
Aug 25, 2021
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions Sources/SwiftkubeClient/Config/KubernetesClientConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -228,3 +228,51 @@ private extension AuthInfo {
return nil
}
}

public extension KubernetesClientConfig {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make this implement the KubernetesClientConfigLoader protocol analogous to the other loaders. It would however mean that we would have to create an instance of the struct and, as of now, it is a one-shot-then-throw-away instance (as you can see here).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes, I did actually consider this when I first looked at it, but the one-shot-then-throw-away thing confused me. But yeah, if nothing else it keeps everything consistent and maintainable. I will change it

static func loadConfigFromPath(logger: Logger, path: String) throws -> KubernetesClientConfig? {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could change the function to look more "swifty" by moving the path parameter to first position and dropping the fromPath part:

func load(fromPath: String, logger: Logger) throws -> KubernetesClientConfig? { ... }

The call-site would look like this then:

KubernetesClientConfig().load(fromPath: "/some/path/", logger: logger)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah yes, that reads much better! I will implement 👍

let decoder = YAMLDecoder()

let fileURL = URL(fileURLWithPath: path)

guard let contents = try? String(contentsOf: fileURL, encoding: .utf8) else {
return nil
}

guard let kubeConfig = try? decoder.decode(KubeConfig.self, from: contents) else {
return nil
}

guard let currentContext = kubeConfig.currentContext else {
return nil
}

guard let context = kubeConfig.contexts?.filter({ $0.name == currentContext }).map(\.context).first else {
return nil
}

guard let cluster = kubeConfig.clusters?.filter({ $0.name == context.cluster }).map(\.cluster).first else {
return nil
}

guard let masterURL = URL(string: cluster.server) else {
return nil
}

guard let authInfo = kubeConfig.users?.filter({ $0.name == context.user }).map(\.authInfo).first else {
return nil
}

guard let authentication = authInfo.authentication(logger: logger) else {
return nil
}

return KubernetesClientConfig(
masterURL: masterURL,
namespace: context.namespace ?? "default",
authentication: authentication,
trustRoots: cluster.trustRoots(logger: logger),
insecureSkipTLSVerify: cluster.insecureSkipTLSVerify ?? true
)
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an exact duplicate of the same lines in the LocalFileConfigLoader. How about this:

  • We change the LocalFileConfigLoader to accept a URL and the body would contains this logic for loading any given arbitrary URL.
internal struct LocalFileConfigLoadera {
   internal func load(fromURL: URL, logger: Logger) throws -> KubernetesClientConfig? { ... }
} 
  • Then we rename LocalFileConfigLoader to something like URLConfigLoader
  • And finally rename the new KubernetesClientConfig to something like LocalKubeConfigLoader and make it call the URLConfigLoader to restore the previous functionality, e.g.:
struct LocalKubeConfigLoader {
    func load(logger: Logger) throws -> KubernetesClientConfig? {
        guard let homePath = ProcessInfo.processInfo.environment["HOME"] else {
            logger.info("Skipping kubeconfig in $HOME/.kube/config because HOME env variable is not set.")
            return nil
        }
        let kubeConfigURL = URL(fileURLWithPath: homePath + "/.kube/config")
        return try? URLConfigLoader().load(fromURL: kubeConfigURL, logger: logger)
    }
}

Copy link
Contributor Author

@thomashorrobin thomashorrobin Aug 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see. So we will have three structs the implement KubernetesClientConfigLoader

  1. LocalFileConfigLoader
  2. LocalKubeConfigLoader
  3. ServiceAccountConfigLoader
    Cool, I reckon that'll work well 😊

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes exactly, however the LocalFileConfigLoader can accept any URL, even remote URLs(don't know if that is really a use-case), so we could just call itURLConfigLoader` 😉

}