github.com/jenkins-x/jx/v2@v2.1.155/pkg/kube/jenkins.go (about)

     1  package kube
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/beevik/etree"
     7  	"github.com/jenkins-x/jx/v2/pkg/auth"
     8  	"github.com/jenkins-x/jx/v2/pkg/gits"
     9  	corev1 "k8s.io/api/core/v1"
    10  )
    11  
    12  const (
    13  	BitbucketConfigMapKey = "com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketEndpointConfiguration.xml"
    14  	GiteaConfigMapKey     = "org.jenkinsci.plugin.gitea.servers.GiteaServers.xml"
    15  	GithubConfigMapKey    = "org.jenkinsci.plugins.github_branch_source.GitHubConfiguration.xml"
    16  
    17  	bitbucketCloudElementName  = "com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketCloudEndpoint"
    18  	bitbucketServerElementName = "com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketServerEndpoint"
    19  
    20  	defaultBitbucketXml = `<?xml version='1.1' encoding='UTF-8'?>
    21      <com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketEndpointConfiguration plugin="cloudbees-bitbucket-branch-source@2.2.10"/>`
    22  )
    23  
    24  // UpdateJenkinsGitServers update the Jenkins ConfigMap with any missing Git server configurations for the given server and token
    25  func UpdateJenkinsGitServers(cm *corev1.ConfigMap, server *auth.AuthServer, userAuth *auth.UserAuth, credentials string) (bool, error) {
    26  	if gits.IsGitHubServerURL(server.URL) {
    27  		return false, nil
    28  	}
    29  	var key, v1, v2 string
    30  	var err error
    31  
    32  	switch server.Kind {
    33  	case gits.KindBitBucketCloud:
    34  		key = BitbucketConfigMapKey
    35  		v1 = cm.Data[key]
    36  		v2, err = createBitbucketCloudConfig(v1, server, userAuth, credentials)
    37  	case gits.KindBitBucketServer:
    38  		key = BitbucketConfigMapKey
    39  		v1 = cm.Data[key]
    40  		v2, err = createBitbucketServerConfig(v1, server, userAuth, credentials)
    41  	case gits.KindGitHub:
    42  		key = GithubConfigMapKey
    43  		v1 = cm.Data[key]
    44  		v2, err = createGitHubConfig(v1, server, userAuth, credentials)
    45  	case gits.KindGitea:
    46  		key = GiteaConfigMapKey
    47  		v1 = cm.Data[key]
    48  		v2, err = createGiteaConfig(v1, server, userAuth, credentials)
    49  	}
    50  	if err != nil {
    51  		return false, err
    52  	}
    53  	if v1 == v2 {
    54  		return false, nil
    55  	}
    56  	cm.Data[key] = v2
    57  	return true, nil
    58  }
    59  
    60  // ParseXml parses XML
    61  func ParseXml(xml string) (*etree.Document, string, error) {
    62  	prefix := ""
    63  	doc := etree.NewDocument()
    64  	parseXml := xml
    65  	idx := strings.Index(xml, "?>")
    66  	if idx > 0 {
    67  		prefix = xml[0:idx+2] + "\n"
    68  		parseXml = strings.TrimSpace(xml[idx+2:])
    69  	}
    70  	err := doc.ReadFromString(parseXml)
    71  	return doc, prefix, err
    72  }
    73  
    74  func createGitHubConfig(xml string, server *auth.AuthServer, userAuth *auth.UserAuth, credentials string) (string, error) {
    75  	u := gits.GitHubEnterpriseApiEndpointURL(server.URL)
    76  	if strings.TrimSpace(xml) == "" {
    77  		xml = `<?xml version='1.1' encoding='UTF-8'?>
    78  		    <org.jenkinsci.plugins.github__branch__source.GitHubConfiguration plugin="github-branch-source@2.3.2"/>`
    79  	}
    80  	answer := xml
    81  	doc, prefix, err := ParseXml(xml)
    82  	if err != nil {
    83  		return answer, err
    84  	}
    85  	root := doc.Root()
    86  	servers := getChild(root, "endpoints")
    87  	if servers == nil {
    88  		servers = root.CreateElement("endpoints")
    89  		root.AddChild(servers)
    90  	}
    91  
    92  	found := false
    93  	updated := false
    94  	for _, n := range servers.ChildElements() {
    95  		if getChildText(n, "apiUri") == u {
    96  			found = true
    97  			break
    98  		}
    99  	}
   100  	if !found {
   101  		// lets add a new element
   102  		s := servers.CreateElement("org.jenkinsci.plugins.github__branch__source.Endpoint")
   103  		servers.AddChild(s)
   104  		setChildText(s, "name", server.Name)
   105  		setChildText(s, "apiUri", u)
   106  		updated = true
   107  	}
   108  	if updated {
   109  		doc.Indent(2)
   110  		xml2, err := doc.WriteToString()
   111  		return prefix + xml2, err
   112  	}
   113  	return xml, nil
   114  
   115  }
   116  
   117  func createGiteaConfig(xml string, server *auth.AuthServer, userAuth *auth.UserAuth, credentials string) (string, error) {
   118  	u := server.URL
   119  	if strings.TrimSpace(xml) == "" {
   120  		xml = `<?xml version='1.1' encoding='UTF-8'?>
   121  		    <org.jenkinsci.plugin.gitea.servers.GiteaServers plugin="gitea@1.0.5"/>`
   122  	}
   123  	answer := xml
   124  	doc, prefix, err := ParseXml(xml)
   125  	if err != nil {
   126  		return answer, err
   127  	}
   128  	root := doc.Root()
   129  	servers := getChild(root, "servers")
   130  	if servers == nil {
   131  		servers = root.CreateElement("servers")
   132  		root.AddChild(servers)
   133  	}
   134  
   135  	found := false
   136  	updated := false
   137  	for _, n := range servers.ChildElements() {
   138  		if getChildText(n, "serverUrl") == u {
   139  			if setChildText(n, "credentialsId", credentials) {
   140  				updated = true
   141  			}
   142  			found = true
   143  			break
   144  		}
   145  	}
   146  	if !found {
   147  		// lets add a new element
   148  		s := servers.CreateElement("org.jenkinsci.plugin.gitea.servers.GiteaServer")
   149  		servers.AddChild(s)
   150  		setChildText(s, "displayName", server.Name)
   151  		setChildText(s, "serverUrl", u)
   152  		setChildText(s, "credentialsId", credentials)
   153  		setChildText(s, "manageHooks", "true")
   154  		updated = true
   155  	}
   156  	if updated {
   157  		doc.Indent(2)
   158  		xml2, err := doc.WriteToString()
   159  		return prefix + xml2, err
   160  	}
   161  	return xml, nil
   162  }
   163  
   164  func createBitbucketCloudConfig(xml string, server *auth.AuthServer, userAuth *auth.UserAuth, credentials string) (string, error) {
   165  	elementName := bitbucketCloudElementName
   166  	if strings.TrimSpace(xml) == "" {
   167  		xml = defaultBitbucketXml
   168  	}
   169  	answer := xml
   170  	doc, prefix, err := ParseXml(xml)
   171  	if err != nil {
   172  		return answer, err
   173  	}
   174  	root := doc.Root()
   175  	servers := getChild(root, "endpoints")
   176  	if servers == nil {
   177  		servers = root.CreateElement("endpoints")
   178  		root.AddChild(servers)
   179  	}
   180  
   181  	found := false
   182  	updated := false
   183  	for _, n := range servers.ChildElements() {
   184  		if setChildText(n, "credentialsId", credentials) {
   185  			updated = true
   186  		}
   187  		if setChildText(n, "manageHooks", "true") {
   188  			updated = true
   189  		}
   190  		found = true
   191  		break
   192  	}
   193  	if !found {
   194  		// lets add a new element
   195  		s := servers.CreateElement(elementName)
   196  		servers.AddChild(s)
   197  		setChildText(s, "credentialsId", credentials)
   198  		setChildText(s, "manageHooks", "true")
   199  		updated = true
   200  	}
   201  	if updated {
   202  		doc.Indent(2)
   203  		xml2, err := doc.WriteToString()
   204  		return prefix + xml2, err
   205  	}
   206  	return xml, nil
   207  }
   208  
   209  func createBitbucketServerConfig(xml string, server *auth.AuthServer, userAuth *auth.UserAuth, credentials string) (string, error) {
   210  	elementName := bitbucketServerElementName
   211  	u := server.URL
   212  	if strings.TrimSpace(xml) == "" {
   213  		xml = defaultBitbucketXml
   214  	}
   215  	answer := xml
   216  	doc, prefix, err := ParseXml(xml)
   217  	if err != nil {
   218  		return answer, err
   219  	}
   220  	root := doc.Root()
   221  	servers := getChild(root, "endpoints")
   222  	if servers == nil {
   223  		servers = root.CreateElement("endpoints")
   224  		root.AddChild(servers)
   225  	}
   226  
   227  	found := false
   228  	updated := false
   229  	for _, n := range servers.ChildElements() {
   230  		if getChildText(n, "serverUrl") == u {
   231  			if setChildText(n, "credentialsId", credentials) {
   232  				updated = true
   233  			}
   234  			found = true
   235  			break
   236  		}
   237  	}
   238  	if !found {
   239  		// lets add a new element
   240  		s := servers.CreateElement(elementName)
   241  		servers.AddChild(s)
   242  		setChildText(s, "displayName", server.Name)
   243  		setChildText(s, "serverUrl", u)
   244  		setChildText(s, "credentialsId", credentials)
   245  		setChildText(s, "manageHooks", "true")
   246  		updated = true
   247  	}
   248  	if updated {
   249  		doc.Indent(2)
   250  		xml2, err := doc.WriteToString()
   251  		return prefix + xml2, err
   252  	}
   253  	return xml, nil
   254  
   255  }
   256  
   257  func setChildText(node *etree.Element, childName string, value string) bool {
   258  	answer := false
   259  	child := getChild(node, childName)
   260  	if child == nil {
   261  		child = node.CreateElement(childName)
   262  		answer = true
   263  		node.AddChild(child)
   264  	}
   265  	if child.Text() != value {
   266  		child.SetText(value)
   267  		answer = true
   268  	}
   269  	return answer
   270  }
   271  
   272  func getChild(node *etree.Element, childName string) *etree.Element {
   273  	children := node.ChildElements()
   274  	for _, child := range children {
   275  		if child != nil && child.Tag == childName {
   276  			return child
   277  		}
   278  	}
   279  	return nil
   280  }
   281  
   282  func getChildText(node *etree.Element, childName string) string {
   283  	child := getChild(node, childName)
   284  	if child != nil {
   285  		return child.Text()
   286  	}
   287  	return ""
   288  }