github.com/argoproj/argo-events@v1.9.1/eventsources/sources/hdfs/client.go (about)

     1  package hdfs
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/colinmarc/hdfs"
     7  	krb "gopkg.in/jcmturner/gokrb5.v5/client"
     8  	"gopkg.in/jcmturner/gokrb5.v5/config"
     9  	"gopkg.in/jcmturner/gokrb5.v5/credentials"
    10  	"gopkg.in/jcmturner/gokrb5.v5/keytab"
    11  	corev1 "k8s.io/api/core/v1"
    12  
    13  	"github.com/argoproj/argo-events/common"
    14  	"github.com/argoproj/argo-events/pkg/apis/eventsource/v1alpha1"
    15  )
    16  
    17  // HDFSConfig is config for HDFS
    18  type HDFSConfig struct {
    19  	Addresses  []string // comma-separated name nodes
    20  	HDFSUser   string
    21  	KrbOptions *KrbOptions
    22  }
    23  
    24  // KrbOptions is options for Kerberos
    25  type KrbOptions struct {
    26  	CCacheOptions        *CCacheOptions
    27  	KeytabOptions        *KeytabOptions
    28  	Config               string
    29  	ServicePrincipalName string
    30  }
    31  
    32  // CCacheOptions is options for ccache
    33  type CCacheOptions struct {
    34  	CCache credentials.CCache
    35  }
    36  
    37  // KeytabOptions is options for keytab
    38  type KeytabOptions struct {
    39  	Keytab   keytab.Keytab
    40  	Username string
    41  	Realm    string
    42  }
    43  
    44  func getConfigMapKey(selector *corev1.ConfigMapKeySelector) (string, error) {
    45  	result, err := common.GetConfigMapFromVolume(selector)
    46  	if err != nil {
    47  		return "", fmt.Errorf("configmap value not injected, %w", err)
    48  	}
    49  	return result, nil
    50  }
    51  
    52  func getSecretKey(selector *corev1.SecretKeySelector) ([]byte, error) {
    53  	result, err := common.GetSecretFromVolume(selector)
    54  	if err != nil {
    55  		return nil, fmt.Errorf("secret value not injected, %w", err)
    56  	}
    57  	return []byte(result), nil
    58  }
    59  
    60  // createHDFSConfig constructs HDFSConfig
    61  func createHDFSConfig(hdfsEventSource *v1alpha1.HDFSEventSource) (*HDFSConfig, error) {
    62  	var krbConfig string
    63  	var krbOptions *KrbOptions
    64  	var err error
    65  
    66  	if hdfsEventSource.KrbConfigConfigMap != nil && hdfsEventSource.KrbConfigConfigMap.Name != "" {
    67  		krbConfig, err = getConfigMapKey(hdfsEventSource.KrbConfigConfigMap)
    68  		if err != nil {
    69  			return nil, err
    70  		}
    71  	}
    72  	if hdfsEventSource.KrbCCacheSecret != nil && hdfsEventSource.KrbCCacheSecret.Name != "" {
    73  		bytes, err := getSecretKey(hdfsEventSource.KrbCCacheSecret)
    74  		if err != nil {
    75  			return nil, err
    76  		}
    77  		ccache, err := credentials.ParseCCache(bytes)
    78  		if err != nil {
    79  			return nil, err
    80  		}
    81  		krbOptions = &KrbOptions{
    82  			CCacheOptions: &CCacheOptions{
    83  				CCache: ccache,
    84  			},
    85  			Config:               krbConfig,
    86  			ServicePrincipalName: hdfsEventSource.KrbServicePrincipalName,
    87  		}
    88  	}
    89  	if hdfsEventSource.KrbKeytabSecret != nil && hdfsEventSource.KrbKeytabSecret.Name != "" {
    90  		bytes, err := getSecretKey(hdfsEventSource.KrbKeytabSecret)
    91  		if err != nil {
    92  			return nil, err
    93  		}
    94  		ktb, err := keytab.Parse(bytes)
    95  		if err != nil {
    96  			return nil, err
    97  		}
    98  		krbOptions = &KrbOptions{
    99  			KeytabOptions: &KeytabOptions{
   100  				Keytab:   ktb,
   101  				Username: hdfsEventSource.KrbUsername,
   102  				Realm:    hdfsEventSource.KrbRealm,
   103  			},
   104  			Config:               krbConfig,
   105  			ServicePrincipalName: hdfsEventSource.KrbServicePrincipalName,
   106  		}
   107  	}
   108  
   109  	hdfsConfig := HDFSConfig{
   110  		Addresses:  hdfsEventSource.Addresses,
   111  		HDFSUser:   hdfsEventSource.HDFSUser,
   112  		KrbOptions: krbOptions,
   113  	}
   114  	return &hdfsConfig, nil
   115  }
   116  
   117  func createHDFSClient(addresses []string, user string, krbOptions *KrbOptions) (*hdfs.Client, error) {
   118  	options := hdfs.ClientOptions{
   119  		Addresses: addresses,
   120  	}
   121  
   122  	if krbOptions != nil {
   123  		krbClient, err := createKrbClient(krbOptions)
   124  		if err != nil {
   125  			return nil, err
   126  		}
   127  		options.KerberosClient = krbClient
   128  		options.KerberosServicePrincipleName = krbOptions.ServicePrincipalName
   129  	} else {
   130  		options.User = user
   131  	}
   132  
   133  	return hdfs.NewClient(options)
   134  }
   135  
   136  func createKrbClient(krbOptions *KrbOptions) (*krb.Client, error) {
   137  	krbConfig, err := config.NewConfigFromString(krbOptions.Config)
   138  	if err != nil {
   139  		return nil, err
   140  	}
   141  
   142  	if krbOptions.CCacheOptions != nil {
   143  		client, err := krb.NewClientFromCCache(krbOptions.CCacheOptions.CCache)
   144  		if err != nil {
   145  			return nil, err
   146  		}
   147  		return client.WithConfig(krbConfig), nil
   148  	} else if krbOptions.KeytabOptions != nil {
   149  		client := krb.NewClientWithKeytab(krbOptions.KeytabOptions.Username, krbOptions.KeytabOptions.Realm, krbOptions.KeytabOptions.Keytab)
   150  		client = *client.WithConfig(krbConfig)
   151  		err = client.Login()
   152  		if err != nil {
   153  			return nil, err
   154  		}
   155  		return &client, nil
   156  	}
   157  
   158  	return nil, fmt.Errorf("Failed to get a Kerberos client")
   159  }