sigs.k8s.io/prow@v0.0.0-20240503223140-c5e374dc7eb1/pkg/flagutil/jira.go (about)

     1  /*
     2  Copyright 2020 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package flagutil
    18  
    19  import (
    20  	"errors"
    21  	"flag"
    22  	"fmt"
    23  	"net/url"
    24  
    25  	"sigs.k8s.io/prow/pkg/config/secret"
    26  	"sigs.k8s.io/prow/pkg/jira"
    27  )
    28  
    29  type JiraOptions struct {
    30  	endpoint        string
    31  	username        string
    32  	passwordFile    string
    33  	bearerTokenFile string
    34  }
    35  
    36  func (o *JiraOptions) AddFlags(fs *flag.FlagSet) {
    37  	fs.StringVar(&o.endpoint, "jira-endpoint", "", "The Jira endpoint to use")
    38  	fs.StringVar(&o.username, "jira-username", "", "The username to use for Jira basic auth")
    39  	fs.StringVar(&o.passwordFile, "jira-password-file", "", "Location to a file containing the Jira basic auth password")
    40  	fs.StringVar(&o.bearerTokenFile, "jira-bearer-token-file", "", "Location to a file containing the Jira bearer authorization token")
    41  
    42  }
    43  
    44  func (o *JiraOptions) Validate(_ bool) error {
    45  	if o.endpoint == "" {
    46  		return nil
    47  	}
    48  
    49  	if _, err := url.ParseRequestURI(o.endpoint); err != nil {
    50  		return fmt.Errorf("--jira-endpoint %q is invalid: %w", o.endpoint, err)
    51  	}
    52  
    53  	if (o.username != "") != (o.passwordFile != "") {
    54  		return errors.New("--jira-username and --jira-password-file must be specified together")
    55  	}
    56  
    57  	if o.bearerTokenFile != "" && o.username != "" {
    58  		return errors.New("--jira-bearer-token-file and --jira-username are mutually exclusive")
    59  	}
    60  
    61  	if o.bearerTokenFile != "" && o.passwordFile != "" {
    62  		return errors.New("--jira-bearer-token-file and --jira-password-file are mutually exclusive")
    63  	}
    64  
    65  	return nil
    66  }
    67  
    68  func (o *JiraOptions) Client() (jira.Client, error) {
    69  	if o.endpoint == "" {
    70  		return nil, errors.New("empty --jira-endpoint, can not create a client")
    71  	}
    72  
    73  	var opts []jira.Option
    74  	if o.passwordFile != "" {
    75  		if err := secret.Add(o.passwordFile); err != nil {
    76  			return nil, fmt.Errorf("failed to get --jira-password-file: %w", err)
    77  		}
    78  		opts = append(opts, jira.WithBasicAuth(func() (string, string) {
    79  			return o.username, string(secret.GetSecret(o.passwordFile))
    80  		}))
    81  	}
    82  
    83  	if o.bearerTokenFile != "" {
    84  		if err := secret.Add(o.bearerTokenFile); err != nil {
    85  			return nil, fmt.Errorf("failed to get --jira-bearer-token-file: %w", err)
    86  		}
    87  		opts = append(opts, jira.WithBearerAuth(func() string {
    88  			return string(secret.GetSecret(o.bearerTokenFile))
    89  		}))
    90  	}
    91  
    92  	return jira.NewClient(o.endpoint, opts...)
    93  }