Skip to content

Commit

Permalink
add support supplying cloud creds
Browse files Browse the repository at this point in the history
Signed-off-by: Prashanth Dintyala <vdintyala@nvidia.com>
  • Loading branch information
saiprashanth173 committed Jun 20, 2021
1 parent dda451c commit bceb145
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 10 deletions.
8 changes: 8 additions & 0 deletions operator/api/v1beta1/aistore_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ type AIStoreSpec struct {
// +optional
ClusterDomain *string `json:"clusterDomain,omitempty"`

// Secret name containing GCP credentials
// +optional
GCPSecretName *string `json:"gcpSecretName,omitempty"`

// Secret name containing AWS credentials
// +optional
AWSSecretName *string `json:"awsSecretName,omitempty"`

// ImagePullScerets is an optional list of references to secrets in the same namespace to pull container images of AIS Daemons
// More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod
// +optional
Expand Down
10 changes: 10 additions & 0 deletions operator/api/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions operator/config/crd/bases/ais.nvidia.com_aistores.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ spec:
spec:
description: AIStoreSpec defines the desired state of AIStore
properties:
awsSecretName:
description: Secret name containing AWS credentials
type: string
cleanupData:
description: Defines if the PVCs and (meta)data should be cleaned
up when cluster is destroyed. Reclaiming of PVs associated with
Expand Down Expand Up @@ -331,6 +334,9 @@ spec:
enablePromExporter:
description: Defines if AIS daemons should expose prometheus metrics
type: boolean
gcpSecretName:
description: Secret name containing GCP credentials
type: string
hostpathPrefix:
type: string
imagePullSecrets:
Expand Down
11 changes: 11 additions & 0 deletions operator/pkg/resources/cmn/configmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@ func NewGlobalCM(ais *aisv1.AIStore, toUpdate *aiscmn.ConfigToUpdate) (*corev1.C
return nil, err
}
}
if ais.Spec.AWSSecretName != nil || ais.Spec.GCPSecretName != nil {
if globalConf.Backend.Conf == nil {
globalConf.Backend.Conf = make(map[string]interface{}, 8)
}
if ais.Spec.AWSSecretName != nil {
globalConf.Backend.Conf["aws"] = aisv1.Empty{}
}
if ais.Spec.GCPSecretName != nil {
globalConf.Backend.Conf["gcp"] = aisv1.Empty{}
}
}
conf, err := jsoniter.MarshalToString(globalConf)
if err != nil {
return nil, err
Expand Down
2 changes: 2 additions & 0 deletions operator/pkg/resources/cmn/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ const (
EnvEnableExternalAccess = "ENABLE_EXTERNAL_ACCESS" // Bool flag to indicate AIS daemon is exposed using LoadBalancer
EnvShutdownMarkerPath = "AIS_SHUTDOWN_MARKER_PATH" // Path where node shutdown marker will be located

EnvGCPCredsPath = "GOOGLE_APPLICATION_CREDENTIALS" // Path to GCP credentials

// Benchmark see: https://github.com/NVIDIA/aistore/blob/master/docs/howto_benchmark.md#dry-run-performance-tests
EnvNoDiskIO = "AIS_NO_DISK_IO"
EnvDryObjSize = "AIS_DRY_OBJ_SIZE"
Expand Down
47 changes: 43 additions & 4 deletions operator/pkg/resources/cmn/res.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (
)

func NewAISVolumes(ais *aisv1.AIStore, daeType string) []corev1.Volume {
return []corev1.Volume{
volumes := []corev1.Volume{
{
Name: "config-mount",
VolumeSource: corev1.VolumeSource{
Expand Down Expand Up @@ -71,6 +71,28 @@ func NewAISVolumes(ais *aisv1.AIStore, daeType string) []corev1.Volume {
},
},
}
if ais.Spec.AWSSecretName != nil {
volumes = append(volumes, corev1.Volume{
Name: "aws-creds",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: *ais.Spec.AWSSecretName,
},
},
})
}
if ais.Spec.GCPSecretName != nil {
volumes = append(volumes, corev1.Volume{
Name: "gcp-creds",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: *ais.Spec.GCPSecretName,
},
},
})
}

return volumes
}

func NewAISLivenessProbe(port intstr.IntOrString) *corev1.Probe {
Expand All @@ -97,12 +119,12 @@ func NewAISNodeLifecycle() *corev1.Lifecycle {
}
}

func NewAISVolumeMounts(antiAffinityDisabled *bool) []corev1.VolumeMount {
func NewAISVolumeMounts(ais *aisv1.AIStore) []corev1.VolumeMount {
var hostMountSubPath string
if antiAffinityDisabled != nil && *antiAffinityDisabled {
if ais.Spec.DisablePodAntiAffinity != nil && *ais.Spec.DisablePodAntiAffinity {
hostMountSubPath = "$(MY_POD)"
}
return []corev1.VolumeMount{
volumeMounts := []corev1.VolumeMount{
{
Name: "config-mount",
MountPath: "/var/ais_config",
Expand Down Expand Up @@ -137,6 +159,23 @@ func NewAISVolumeMounts(antiAffinityDisabled *bool) []corev1.VolumeMount {
MountPath: "/var/statsd_config",
},
}

if ais.Spec.AWSSecretName != nil {
volumeMounts = append(volumeMounts, corev1.VolumeMount{
Name: "aws-creds",
ReadOnly: true,
MountPath: "/root/.aws",
})
}
if ais.Spec.GCPSecretName != nil {
volumeMounts = append(volumeMounts, corev1.VolumeMount{
Name: "gcp-creds",
ReadOnly: true,
MountPath: "/var/gcp",
})
}

return volumeMounts
}

func NewInitVolumeMounts(antiAffinityDisabled *bool) []corev1.VolumeMount {
Expand Down
10 changes: 7 additions & 3 deletions operator/pkg/resources/proxy/statefulset.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ func proxyPodSpec(ais *aisv1.AIStore) corev1.PodSpec {
cmn.EnvFromFieldPath(cmn.EnvPublicHostname, "status.hostIP"),
}
}
if ais.Spec.GCPSecretName != nil {
// TODO -- FIXME: Remove hardcoding for path
optionals = append(optionals, cmn.EnvFromValue(cmn.EnvGCPCredsPath, "/var/gcp/gcp.json"))
}

return corev1.PodSpec{
InitContainers: []corev1.Container{
Expand Down Expand Up @@ -109,7 +113,7 @@ func proxyPodSpec(ais *aisv1.AIStore) corev1.PodSpec {
Name: "ais-node",
Image: ais.Spec.NodeImage,
ImagePullPolicy: corev1.PullAlways,
Env: []corev1.EnvVar{
Env: append([]corev1.EnvVar{
cmn.EnvFromFieldPath(cmn.EnvPodName, "metadata.name"),
cmn.EnvFromValue(cmn.EnvNS, ais.Namespace),
cmn.EnvFromValue(cmn.EnvClusterDomain, ais.GetClusterDomain()),
Expand All @@ -125,10 +129,10 @@ func proxyPodSpec(ais *aisv1.AIStore) corev1.PodSpec {
cmn.EnvFromValue(cmn.EnvProxyServiceName, HeadlessSVCName(ais)),
cmn.EnvFromValue(cmn.EnvProxyServicePort, ais.Spec.ProxySpec.ServicePort.String()),
cmn.EnvFromValue(cmn.EnvNodeServicePort, ais.Spec.ProxySpec.PublicPort.String()),
},
}, optionals...),
Ports: cmn.NewDaemonPorts(ais.Spec.ProxySpec),
SecurityContext: ais.Spec.ProxySpec.ContainerSecurity,
VolumeMounts: cmn.NewAISVolumeMounts(ais.Spec.DisablePodAntiAffinity),
VolumeMounts: cmn.NewAISVolumeMounts(ais),
Lifecycle: cmn.NewAISNodeLifecycle(),
LivenessProbe: cmn.NewAISLivenessProbe(ais.Spec.ProxySpec.ServicePort),
ReadinessProbe: readinessProbe(),
Expand Down
12 changes: 9 additions & 3 deletions operator/pkg/resources/target/statefulset.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ func NewTargetSS(ais *aisv1.AIStore) *apiv1.StatefulSet {
cmn.EnvFromFieldPath(cmn.EnvPublicHostname, "status.hostIP"),
}
}

if ais.Spec.GCPSecretName != nil {
// TODO -- FIXME: Remove hardcoding for path
optionals = append(optionals, cmn.EnvFromValue(cmn.EnvGCPCredsPath, "/var/gcp/gcp.json"))
}

return &apiv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
Name: statefulSetName(ais),
Expand Down Expand Up @@ -98,7 +104,7 @@ func NewTargetSS(ais *aisv1.AIStore) *apiv1.StatefulSet {
Name: "ais-node",
Image: ais.Spec.NodeImage,
ImagePullPolicy: corev1.PullAlways,
Env: []corev1.EnvVar{
Env: append([]corev1.EnvVar{
cmn.EnvFromFieldPath(cmn.EnvPodName, "metadata.name"),
cmn.EnvFromValue(cmn.EnvClusterDomain, ais.GetClusterDomain()),
cmn.EnvFromValue(cmn.EnvNS, ais.Namespace),
Expand All @@ -118,7 +124,7 @@ func NewTargetSS(ais *aisv1.AIStore) *apiv1.StatefulSet {
cmn.EnvFromValue(cmn.EnvProxyServiceName, proxy.HeadlessSVCName(ais)),
cmn.EnvFromValue(cmn.EnvProxyServicePort, ais.Spec.ProxySpec.ServicePort.String()),
cmn.EnvFromValue(cmn.EnvNodeServicePort, ais.Spec.TargetSpec.PublicPort.String()),
},
}, optionals...),
Ports: cmn.NewDaemonPorts(ais.Spec.TargetSpec.DaemonSpec),
SecurityContext: ais.Spec.TargetSpec.ContainerSecurity,
VolumeMounts: volumeMounts(ais),
Expand All @@ -140,7 +146,7 @@ func NewTargetSS(ais *aisv1.AIStore) *apiv1.StatefulSet {
}

func volumeMounts(ais *aisv1.AIStore) []corev1.VolumeMount {
vols := cmn.NewAISVolumeMounts(ais.Spec.DisablePodAntiAffinity)
vols := cmn.NewAISVolumeMounts(ais)
for _, res := range ais.Spec.TargetSpec.Mounts {
vols = append(vols, corev1.VolumeMount{
Name: ais.Name + strings.ReplaceAll(res.Path, "/", "-"),
Expand Down

0 comments on commit bceb145

Please sign in to comment.