https://pulumi.com logo
#general
Title
# general
i

important-leather-28796

03/13/2019, 7:47 PM
Does pulumi use/read
$HOME/.kube/config
? Or use the
gcloud
config? I had and old set of configs from an infrastructure yesterday and I could not
pulumi up
some things today - failed with:
Copy code
Diagnostics:
  kubernetes:core:Namespace (development):
    error: Plan apply failed: Get <https://104.154.180.226/api?timeout=32s>: x509: certificate signed by unknown authority
Once I used my script to re-setup the
gcloud config
and kube config,
pulumi up
worked. Thoughts?
g

gorgeous-egg-16927

03/13/2019, 7:51 PM
Pulumi acts the same as
kubectl
. It will read ambient config in the same fallback order, including
$HOME/.kube/config
i

important-leather-28796

03/13/2019, 8:18 PM
I wouldn’t think it would fallback since the
Namespace
I am creating is using an explicit
{ providers: { kubernetes } }
g

gorgeous-egg-16927

03/13/2019, 8:19 PM
Yeah, if you set a provider, it should use those creds rather than anything ambient
i

important-leather-28796

03/13/2019, 8:20 PM
I guess the context name would have been identical though, same stacks just rebuild today
@gorgeous-egg-16927 so I
echo "" > $HOME/.kube/config
and
pulumi up
and I get
error: unable to read kubectl config: invalid configuration: no configuration has been provided
my concern is this is going to occur on ci, since it is a new vm every time
what is a valid empty config?
g

gorgeous-egg-16927

03/13/2019, 8:30 PM
Hmm, are you sure all of your k8s resources have a provider set? It could be a bug otherwise
i

important-leather-28796

03/13/2019, 8:31 PM
In this stack I have nothing but a Namespace. let me simplify to verify, it does use the kubeconfig output from another stack
Namespace
uses
CustomResourceOptions
which takes
provider
whereas my
opts
utility outputs
ComponentResourceOptions
which takes
providers
(plural).
two issues here:
1. my env must be screwed up because I don’t see a ts error - I’ll fix that
2. that api seems inconsistent, since I’d expect the Namespace options to look like other options
Regardless, my env needs fixed because I should see that as a ts error.
With the corrected options, it works with an empty .kube/config
c

creamy-potato-29402

03/13/2019, 8:59 PM
@important-leather-28796 the component resource options could have multiple resources with different providers
so, it needs to take many of them.
possibly.
i

important-leather-28796

03/13/2019, 8:59 PM
bizarre thing is my ts passes and it is clearly wrong. looking at that now, but I’m pretty well versed here and it’s not right
c

creamy-potato-29402

03/13/2019, 9:00 PM
this is because it needs to support arbitrary providers.
oh wait
no, this should be right. you need
providers: { kubernetes: yourProvider }
i

important-leather-28796

03/13/2019, 9:01 PM
no, keys are diff
provider
vs
providers
c

creamy-potato-29402

03/13/2019, 9:01 PM
yeah but it’s
any
type
i

important-leather-28796

03/13/2019, 9:01 PM
so I should see a ts error
c

creamy-potato-29402

03/13/2019, 9:01 PM
no, because you could have providers with arbitrary names. Not only the official ones like
aws
,
kubernetes
,
azure
, but also any third party, maybe custom ones you wrote, etc.,
so
providers
needs to be able to take a bag of any providers, with any names.
if that makes sense.
i

important-leather-28796

03/13/2019, 9:02 PM
value is but the key is not. Custom is
provider?: ProviderResource
and Component is
providers?: Record<string, ProviderResource>
currently the result of this fn is what typechecks for either
Copy code
export const opts = (overrides: ComponentResourceOptions = {}): ComponentResourceOptions =>
  merge({ providers: { kubernetes } }, overrides)
which makes no sense
c

creamy-potato-29402

03/13/2019, 9:03 PM
the keys will always be string, no?
kubernetes
is getting “desugared” into the key called
kubernetes
i

important-leather-28796

03/13/2019, 9:04 PM
key is always a string and will error if used in a single file, but not if used by the function
c

creamy-potato-29402

03/13/2019, 9:04 PM
I’m not sure I understand.
i

important-leather-28796

03/13/2019, 9:05 PM
This should be failing to ts check:
Copy code
export const namespace = new k8s.core.v1.Namespace(
  name,
  {
    metadata: {
      name,
    },
  },
  opts(),
)
pulumi types are right
my tsc is not failing it
c

creamy-potato-29402

03/13/2019, 9:05 PM
opts
returns
ComponentResourceOptions
, right?
i

important-leather-28796

03/13/2019, 9:06 PM
right, but Namespace takes
CustomResourceOptions
c

creamy-potato-29402

03/13/2019, 9:06 PM
Oh I see.
i

important-leather-28796

03/13/2019, 9:06 PM
tsc not failing it led me to this wierd issue with a stale .kube/config
I’m expecting to always use the explicit provider and here I am finding tsc not erroring
c

creamy-potato-29402

03/13/2019, 9:07 PM
hmm
one second.
Copy code
const ns = new k8s.core.v1.Namespace("foo", {}, { providers: { foo: <any>"bar" } });
doesn’t work for me.
let me try to reproduce
i

important-leather-28796

03/13/2019, 9:09 PM
right, but you aren’t using a different file for the fn
in a single file i get the error correctly
so pulumi types verified correct
c

creamy-potato-29402

03/13/2019, 9:10 PM
what’s merge?
i

important-leather-28796

03/13/2019, 9:10 PM
deep object merge
c

creamy-potato-29402

03/13/2019, 9:10 PM
I mean is it a custom function?
i

important-leather-28796

03/13/2019, 9:10 PM
ns.ts
Copy code
import { opts } from './provider'
import * as k8s from '@pulumi/kubernetes'
import { Config, getStack } from '@pulumi/pulumi'

const name = new Config('kubernetes').get('namespace') || getStack()

export const namespace = new k8s.core.v1.Namespace(
  name,
  {
    metadata: {
      name,
    },
  },
  opts(),
)
provider.ts
Copy code
import * as k8s from '@pulumi/kubernetes'
import * as stack from './stack'
import { ComponentResourceOptions } from '@pulumi/pulumi'
import merge from 'lodash/merge'

export const kubernetes = new k8s.Provider(stack.infrastructurePath, {
  kubeconfig: stack.infrastructure.getOutput('kubeconfig'),
})

/**
 * default kubernetes provider opts
 */
export const opts = (overrides: ComponentResourceOptions = {}): ComponentResourceOptions =>
  merge({ providers: { kubernetes } }, overrides)
regardless of the merge
I took it out and did a spread, the opts fn is explicit with return type, so it should fail
I’ll mod something for you quick
c

creamy-potato-29402

03/13/2019, 9:13 PM
huh sure enough
i

important-leather-28796

03/13/2019, 9:13 PM
this fn in the provider file still typechecks for me
Copy code
export const opts = (): ComponentResourceOptions => ({ providers: { kubernetes } })
c

creamy-potato-29402

03/13/2019, 9:13 PM
Copy code
export const kubernetes = <k8s.Provider>(<any>"foo");

export const opts = (
    overrides: pulumi.ComponentResourceOptions = {},
): pulumi.ComponentResourceOptions => {
    return { providers: { kubernetes }, ...overrides };
};

const ns = new k8s.core.v1.Namespace("foo", {}, opts());
totally typechecks lol
i

important-leather-28796

03/13/2019, 9:13 PM
it’s clearly not providing
CustomResourceOptions
must be a tsc bug
makes no sense
c

creamy-potato-29402

03/13/2019, 9:15 PM
but so does this:
Copy code
const os: pulumi.ComponentResourceOptions = <pulumi.CustomResourceOptions>{};
strange.
that should definitely be a bug
i

important-leather-28796

03/13/2019, 9:16 PM
the pulumi types are simple so there isn’t something fancy occurring.
bizarre, I’ll check my tsc version etc
c

creamy-potato-29402

03/13/2019, 9:17 PM
second one fails:
Copy code
const os: pulumi.CustomResourceOptions = <pulumi.ComponentResourceOptions>{};
const os2: pulumi.CustomResourceOptions = { providers: {} };
weeeeeiiiird
and then somehow this succeeds:
Copy code
const os2: pulumi.CustomResourceOptions = <pulumi.ComponentResourceOptions>{ providers: {} };
this fails:
Copy code
const os2: pulumi.CustomResourceOptions = { providers: undefined };
@important-leather-28796 I apologize, I have no idea what’s going on here.
i

important-leather-28796

03/13/2019, 9:19 PM
np - definitely a ts problem
c

creamy-potato-29402

03/13/2019, 9:19 PM
how odd
i

important-leather-28796

03/13/2019, 9:20 PM
my tsc is at 3.2.4, what is yours. I’m going to update
c

creamy-potato-29402

03/13/2019, 9:20 PM
3.0
lmk if you see it in the most recent ts
i

important-leather-28796

03/13/2019, 9:22 PM
ok
c

creamy-potato-29402

03/13/2019, 9:22 PM
i’ll try to get an isolated case for a bug repory
compiles:
Copy code
export interface ResourceOptions {
    foo?: boolean;
}

export interface CustomResourceOptions extends ResourceOptions {
    bar?: string;
}

export interface ComponentResourceOptions extends ResourceOptions {
    bars?: string;
}

const os: CustomResourceOptions = <ComponentResourceOptions>{};
does not compile:
Copy code
export interface ResourceOptions {}

export interface CustomResourceOptions extends ResourceOptions {
    bar?: string;
}

export interface ComponentResourceOptions extends ResourceOptions {
    bars?: string;
}

const os: CustomResourceOptions = <ComponentResourceOptions>{};
def. a TS bug.
@important-leather-28796 so, one of our engineers, @lemon-spoon-91807 says that this is actually all on purpose, coming from a set of heuristics in the TS compiler.
Turns out: I lied.
Sorry.
l

lemon-spoon-91807

03/13/2019, 10:26 PM
Yes 🙂
this is just how TS works
which can def seem wonky at times
c

creamy-potato-29402

03/13/2019, 10:27 PM
It makes sense when you think about it.
I mean, when you think about it as a pile of heuristics
i

important-leather-28796

03/13/2019, 11:17 PM
This can't be right. One interface has a key provider and the other has a key providers. There is no reason for this to statically type check
l

lemon-spoon-91807

03/13/2019, 11:17 PM
one is optional
and typescript is loosygoosy
i say that as a person who helped create the first two versions of TS
and who helped define the language 😄
so you can blame me for some of this
i

important-leather-28796

03/13/2019, 11:23 PM
Logically this is a ts bug, and I'm expecting > 99.9999% of users will think of it (as shown in this case) as a bug. I think we should still file it
l

lemon-spoon-91807

03/13/2019, 11:23 PM
File against 'ts'?
i

important-leather-28796

03/13/2019, 11:23 PM
Yes
l

lemon-spoon-91807

03/13/2019, 11:23 PM
I mean... thsi has been behavior it has had since pre-1.0
it's definitely something we knew about and accepted.
i

important-leather-28796

03/13/2019, 11:24 PM
Doesn't mean it should not be improved
l

lemon-spoon-91807

03/13/2019, 11:24 PM
that said, i'm not opposed to you filing a bug here 🙂
if you really think they should improve
i can hook you up with the current PM on the team
to help draw some attention to it.
i

important-leather-28796

03/13/2019, 11:24 PM
Or change the interface on namespace so I cannot make the mistake
I have never encountered it and we have a large ts codebase
l

lemon-spoon-91807

03/13/2019, 11:25 PM
that's tricky given TS's structural nature
we could attempt to look for mistakes at the runtime level
i.e. if you pass 'providers' to Custom, or 'provider' to Component
note: we hit this several times ourselves when writing the TS compiler 🙂 Fun times.
i

important-leather-28796

03/13/2019, 11:27 PM
Lol
l

lemon-spoon-91807

03/13/2019, 11:27 PM
i'll add the runtime check
give me a minute
i

important-leather-28796

03/13/2019, 11:27 PM
Definitely at least a runtime check is good
I just don't want things running locally only to have them fail on CI, this is that exact case
l

lemon-spoon-91807

03/13/2019, 11:36 PM